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-2017 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lp.c
17  * @brief LP management methods and data structures
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Marc Pfetsch
21  * @author Kati Wolter
22  * @author Gerald Gamrath
23  *
24  * In LP management, we have to differ between the current LP and the SCIP_LP
25  * stored in the LP solver. All LP methods affect the current LP only.
26  * Before solving the current LP with the LP solver or setting an LP state,
27  * the LP solvers data has to be updated to the current LP with a call to
28  * lpFlush().
29  */
30 
31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32 
33 
34 #include <assert.h>
35 #include <math.h>
36 #include <limits.h>
37 #include <string.h>
38 
39 #include "scip/def.h"
40 #include "scip/set.h"
41 #include "scip/stat.h"
42 #include "scip/intervalarith.h"
43 #include "scip/clock.h"
44 #include "scip/misc.h"
45 #include "scip/lp.h"
46 #include "scip/var.h"
47 #include "scip/prob.h"
48 #include "scip/sol.h"
49 #include "scip/solve.h"
50 #include "scip/event.h"
51 #include "scip/pub_message.h"
52 #include "lpi/lpi.h"
53 
54 
55 
56 /*
57  * debug messages
58  */
59 
60 #ifdef SCIP_DEBUG
61 /** method is to print in row in case SCIP_DEBUG is defined */
62 static
63 void debugRowPrint(
64  SCIP_SET* set, /**< global SCIP settings */
65  SCIP_ROW* row /**< LP row */
66  )
67 {
68  int i;
69 
70  assert(row != NULL);
71 
72  /* print row name */
73  if( row->name != NULL && row->name[0] != '\0' )
74  {
75  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
76  }
77 
78  /* print left hand side */
79  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
80 
81  /* print coefficients */
82  if( row->len == 0 )
83  {
84  SCIPsetDebugMsgPrint(set, "0 ");
85  }
86  for( i = 0; i < row->len; ++i )
87  {
88  assert(row->cols[i] != NULL);
89  assert(row->cols[i]->var != NULL);
90  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
91  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
92  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
93  }
94 
95  /* print constant */
97  {
98  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
99  }
100 
101  /* print right hand side */
102  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
103 }
104 #else
105 #define debugRowPrint(x,y) /**/
106 #endif
107 
108 #ifdef SCIP_DEBUG
109 /** method to output column if SCIP_DEBUG is define */
110 static
111 void debugColPrint(
112  SCIP_SET* set, /**< global SCIP settings */
113  SCIP_COL* col /**< LP column */
114  )
115 {
116  int r;
117 
118  assert(col != NULL);
119  assert(col->var != NULL);
120 
121  /* print bounds */
122  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
123 
124  /* print coefficients */
125  if( col->len == 0 )
126  {
127  SCIPsetDebugMsgPrint(set, "<empty>");
128  }
129  for( r = 0; r < col->len; ++r )
130  {
131  assert(col->rows[r] != NULL);
132  assert(col->rows[r]->name != NULL);
133  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
134  }
135  SCIPsetDebugMsgPrint(set, "\n");
136 }
137 #else
138 #define debugColPrint(x,y) /**/
139 #endif
140 
141 /*
142  * memory growing methods for dynamically allocated arrays
143  */
144 
145 /** ensures, that chgcols array can store at least num entries */
146 static
148  SCIP_LP* lp, /**< current LP data */
149  SCIP_SET* set, /**< global SCIP settings */
150  int num /**< minimum number of entries to store */
151  )
152 {
153  assert(lp->nchgcols <= lp->chgcolssize);
154 
155  if( num > lp->chgcolssize )
156  {
157  int newsize;
158 
159  newsize = SCIPsetCalcMemGrowSize(set, num);
160  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
161  lp->chgcolssize = newsize;
162  }
163  assert(num <= lp->chgcolssize);
164 
165  return SCIP_OKAY;
166 }
167 
168 /** ensures, that chgrows array can store at least num entries */
169 static
171  SCIP_LP* lp, /**< current LP data */
172  SCIP_SET* set, /**< global SCIP settings */
173  int num /**< minimum number of entries to store */
174  )
175 {
176  assert(lp->nchgrows <= lp->chgrowssize);
177 
178  if( num > lp->chgrowssize )
179  {
180  int newsize;
181 
182  newsize = SCIPsetCalcMemGrowSize(set, num);
183  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
184  lp->chgrowssize = newsize;
185  }
186  assert(num <= lp->chgrowssize);
187 
188  return SCIP_OKAY;
189 }
190 
191 /** ensures, that lpicols array can store at least num entries */
192 static
194  SCIP_LP* lp, /**< current LP data */
195  SCIP_SET* set, /**< global SCIP settings */
196  int num /**< minimum number of entries to store */
197  )
198 {
199  assert(lp->nlpicols <= lp->lpicolssize);
200 
201  if( num > lp->lpicolssize )
202  {
203  int newsize;
204 
205  newsize = SCIPsetCalcMemGrowSize(set, num);
206  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
207  lp->lpicolssize = newsize;
208  }
209  assert(num <= lp->lpicolssize);
210 
211  return SCIP_OKAY;
212 }
213 
214 /** ensures, that lpirows array can store at least num entries */
215 static
217  SCIP_LP* lp, /**< current LP data */
218  SCIP_SET* set, /**< global SCIP settings */
219  int num /**< minimum number of entries to store */
220  )
221 {
222  assert(lp->nlpirows <= lp->lpirowssize);
223 
224  if( num > lp->lpirowssize )
225  {
226  int newsize;
227 
228  newsize = SCIPsetCalcMemGrowSize(set, num);
229  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
230  lp->lpirowssize = newsize;
231  }
232  assert(num <= lp->lpirowssize);
233 
234  return SCIP_OKAY;
235 }
236 
237 /** ensures, that cols array can store at least num entries */
238 static
240  SCIP_LP* lp, /**< current LP data */
241  SCIP_SET* set, /**< global SCIP settings */
242  int num /**< minimum number of entries to store */
243  )
244 {
245  assert(lp->ncols <= lp->colssize);
246 
247  if( num > lp->colssize )
248  {
249  int newsize;
250 
251  newsize = SCIPsetCalcMemGrowSize(set, num);
252  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
253  lp->colssize = newsize;
254  }
255  assert(num <= lp->colssize);
256 
257  return SCIP_OKAY;
258 }
259 
260 /** ensures, that lazy cols array can store at least num entries */
261 static
263  SCIP_LP* lp, /**< current LP data */
264  SCIP_SET* set, /**< global SCIP settings */
265  int num /**< minimum number of entries to store */
266  )
267 {
268  assert(lp->nlazycols <= lp->lazycolssize);
269 
270  if( num > lp->lazycolssize )
271  {
272  int newsize;
273 
274  newsize = SCIPsetCalcMemGrowSize(set, num);
275  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
276  lp->lazycolssize = newsize;
277  }
278  assert(num <= lp->lazycolssize);
279 
280  return SCIP_OKAY;
281 }
282 
283 /** ensures, that rows array can store at least num entries */
284 static
286  SCIP_LP* lp, /**< current LP data */
287  SCIP_SET* set, /**< global SCIP settings */
288  int num /**< minimum number of entries to store */
289  )
290 {
291  assert(lp->nrows <= lp->rowssize);
292 
293  if( num > lp->rowssize )
294  {
295  int newsize;
296 
297  newsize = SCIPsetCalcMemGrowSize(set, num);
298  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
299  lp->rowssize = newsize;
300  }
301  assert(num <= lp->rowssize);
302 
303  return SCIP_OKAY;
304 }
305 
306 /** ensures, that row array of column can store at least num entries */
307 static
309  SCIP_COL* col, /**< LP column */
310  BMS_BLKMEM* blkmem, /**< block memory */
311  SCIP_SET* set, /**< global SCIP settings */
312  int num /**< minimum number of entries to store */
313  )
314 {
315  assert(col != NULL);
316  assert(col->len <= col->size);
317 
318  if( num > col->size )
319  {
320  int newsize;
321 
322  newsize = SCIPsetCalcMemGrowSize(set, num);
323  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
324  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
325  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
326  col->size = newsize;
327  }
328  assert(num <= col->size);
329 
330  return SCIP_OKAY;
331 }
332 
333 /** save current LP values dependent on the solution */
334 static
336  SCIP_LP* lp, /**< LP data */
337  SCIP_STAT* stat, /**< problem statistics */
338  BMS_BLKMEM* blkmem /**< block memory */
339  )
340 {
341  SCIP_LPSOLVALS* storedsolvals;
342 
343  assert(lp != NULL);
344  assert(stat != NULL);
345  assert(blkmem != NULL);
346 
347  /* allocate memory for storage */
348  if( lp->storedsolvals == NULL )
349  {
351  }
352  storedsolvals = lp->storedsolvals;
353 
354  /* store values */
355  storedsolvals->lpsolstat = lp->lpsolstat;
356  storedsolvals->lpobjval = lp->lpobjval;
357  storedsolvals->primalfeasible = lp->primalfeasible;
358  storedsolvals->dualfeasible = lp->dualfeasible;
359  storedsolvals->solisbasic = lp->solisbasic;
360  storedsolvals->lpissolved = lp->solved;
361 
362  return SCIP_OKAY;
363 }
364 
365 /** restore LP solution values in column */
366 static
368  SCIP_LP* lp, /**< LP data */
369  BMS_BLKMEM* blkmem, /**< block memory */
370  SCIP_Longint validlp /**< number of lp for which restored values are valid */
371  )
372 {
373  SCIP_LPSOLVALS* storedsolvals;
374 
375  assert(lp != NULL);
376  assert(blkmem != NULL);
377 
378  /* if stored values are available, restore them */
379  storedsolvals = lp->storedsolvals;
380  if( storedsolvals != NULL )
381  {
382  lp->solved = storedsolvals->lpissolved;
383  lp->validsollp = validlp;
384 
385  lp->lpsolstat = storedsolvals->lpsolstat;
386  lp->lpobjval = storedsolvals->lpobjval;
387  lp->primalfeasible = storedsolvals->primalfeasible;
388  lp->dualfeasible = storedsolvals->dualfeasible;
389  lp->solisbasic = storedsolvals->solisbasic;
390 
391  /* solution values are stored only for LPs solved to optimality or unboundedness */
392  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
398  lp->validsollp == -1);
399  }
400  /* no values available, mark LP as unsolved */
401  else
402  {
403  lp->solved = FALSE;
404  lp->validsollp = -1;
405 
407  lp->lpobjval = SCIP_INVALID;
408  lp->primalfeasible = FALSE;
409  lp->dualfeasible = FALSE;
410  lp->solisbasic = FALSE;
411  lp->validfarkaslp = -1;
412  }
413 
414  /* intentionally keep storage space allocated */
415 
416  return SCIP_OKAY;
417 }
418 
419 /** save current LP solution values stored in each column */
420 static
422  SCIP_COL* col, /**< LP column */
423  BMS_BLKMEM* blkmem /**< block memory */
424  )
425 {
426  SCIP_COLSOLVALS* storedsolvals;
427 
428  assert(col != NULL);
429  assert(blkmem != NULL);
430 
431  /* allocate memory for storage */
432  if( col->storedsolvals == NULL )
433  {
434  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
435  }
436  storedsolvals = col->storedsolvals;
437 
438  /* store values */
439  storedsolvals->primsol = col->primsol;
440  storedsolvals->redcost = col->redcost;
441  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
442 
443  return SCIP_OKAY;
444 }
445 
446 /** restore LP solution values in column */
447 static
449  SCIP_COL* col, /**< LP column */
450  BMS_BLKMEM* blkmem, /**< block memory */
451  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
452  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
453  )
454 {
455  SCIP_COLSOLVALS* storedsolvals;
456 
457  assert(col != NULL);
458  assert(blkmem != NULL);
459 
460  /* if stored values are available, restore them */
461  storedsolvals = col->storedsolvals;
462  if( storedsolvals != NULL )
463  {
464  col->primsol = storedsolvals->primsol;
465  col->redcost = storedsolvals->redcost;
466  col->validredcostlp = validlp;
467  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
468 
469  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
470  col->validfarkaslp = -1;
471  }
472  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
473  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
474  */
475  else
476  {
477  col->primsol = 0.0;
478  col->validredcostlp = -1;
479  col->validfarkaslp = -1;
480  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
481  }
482 
483  /* free memory */
484  if( freebuffer )
485  {
486  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
487  assert(col->storedsolvals == NULL);
488  }
489 
490  return SCIP_OKAY;
491 }
492 
493 /** save current LP solution values stored in each column */
494 static
496  SCIP_ROW* row, /**< LP row */
497  BMS_BLKMEM* blkmem, /**< block memory */
498  SCIP_Bool infeasible /**< is the solution infeasible? */
499  )
500 {
501  SCIP_ROWSOLVALS* storedsolvals;
502 
503  assert(row != NULL);
504  assert(blkmem != NULL);
505 
506  /* allocate memory for storage */
507  if( row->storedsolvals == NULL )
508  {
509  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
510  }
511  storedsolvals = row->storedsolvals;
512 
513  /* store values */
514  if ( infeasible )
515  {
516  storedsolvals->dualsol = row->dualfarkas;
517  storedsolvals->activity = SCIP_INVALID;
518  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
519  }
520  else
521  {
522  storedsolvals->dualsol = row->dualsol;
523  storedsolvals->activity = row->activity;
524  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
525  }
526 
527  return SCIP_OKAY;
528 }
529 
530 /** restore LP solution values in row */
531 static
533  SCIP_ROW* row, /**< LP column */
534  BMS_BLKMEM* blkmem, /**< block memory */
535  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
536  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
537  SCIP_Bool infeasible /**< is the solution infeasible? */
538  )
539 {
540  SCIP_ROWSOLVALS* storedsolvals;
541 
542  assert(row != NULL);
543  assert(blkmem != NULL);
544 
545  /* if stored values are available, restore them */
546  storedsolvals = row->storedsolvals;
547  if( storedsolvals != NULL )
548  {
549  if ( infeasible )
550  row->dualfarkas = storedsolvals->dualsol;
551  else
552  row->dualsol = storedsolvals->dualsol;
553  row->activity = storedsolvals->activity;
554  row->validactivitylp = validlp;
555  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
556  }
557  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
558  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
559  */
560  else
561  {
562  row->dualsol = 0.0;
563  row->dualfarkas = 0.0;
564  row->activity = SCIP_INVALID;
565  row->validactivitylp = -1;
566  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
567  }
568 
569  /* free memory */
570  if( freebuffer )
571  {
572  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
573  assert(row->storedsolvals == NULL);
574  }
575 
576  return SCIP_OKAY;
577 }
578 
579 /** ensures, that column array of row can store at least num entries */
581  SCIP_ROW* row, /**< LP row */
582  BMS_BLKMEM* blkmem, /**< block memory */
583  SCIP_SET* set, /**< global SCIP settings */
584  int num /**< minimum number of entries to store */
585  )
586 {
587  assert(row != NULL);
588  assert(row->len <= row->size);
589 
590  if( num > row->size )
591  {
592  int newsize;
593 
594  newsize = SCIPsetCalcMemGrowSize(set, num);
595  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
596  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
597  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
598  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
599  row->size = newsize;
600  }
601  assert(num <= row->size);
602 
603  return SCIP_OKAY;
604 }
605 
606 
607 #if 0 /* enable this to check the sortings within rows (for debugging, very slow!) */
608 static SCIP_Bool msgdisp_checkrow = FALSE;
609 
610 static
611 void checkRow(
612  SCIP_ROW* row
613  )
614 {
615  int i;
616 
617  if( !msgdisp_checkrow )
618  {
619  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
620  msgdisp_checkrow = TRUE;
621  }
622 
623  /* validate sorting of LP part of row */
624  if( row->lpcolssorted && row->nlpcols > 0)
625  {
626  assert(row->cols_index[0] == row->cols[0]->index);
627  for( i = 1; i < row->nlpcols; ++i )
628  {
629  assert(row->cols_index[i] == row->cols[i]->index);
630  assert(row->cols_index[i] >= row->cols_index[i-1]);
631  }
632  }
633 
634  /* validate sorting of non-LP part of row */
635  if( row->nonlpcolssorted && row->len > row->nlpcols )
636  {
637  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
638  for( i = row->nlpcols + 1; i < row->len; ++i )
639  {
640  assert(row->cols_index[i] == row->cols[i]->index);
641  assert(row->cols_index[i] >= row->cols_index[i-1]);
642  }
643  }
644 }
645 #else
646 #define checkRow(row) /**/
647 #endif
648 
649 #if 0 /* enable this to check norms of rows (for debugging, very slow!) */
650 static
651 void checkRowSqrnorm(
652  SCIP_ROW* row
653  )
654 {
655  SCIP_COL** cols;
656  SCIP_Real sqrnorm;
657  int c;
658 
659  cols = row->cols;
660  assert(cols != NULL || row->len == 0);
661 
662  sqrnorm = 0.0;
663 
664  for( c = row->len - 1; c >= 0; --c )
665  {
666  if( cols[c]->lppos >= 0 )
667  sqrnorm += SQR(row->vals[c]);
668  }
669 
670  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
671 }
672 
673 static
674 void checkRowSumnorm(
675  SCIP_ROW* row
676  )
677 {
678  SCIP_COL** cols;
679  SCIP_Real sumnorm;
680  int c;
681 
682  cols = row->cols;
683  assert(cols != NULL || row->len == 0);
684 
685  sumnorm = 0.0;
686 
687  for( c = row->len - 1; c >= 0; --c )
688  {
689  if( cols[c]->lppos >= 0 )
690  sumnorm += REALABS(row->vals[c]);
691  }
692 
693  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
694 }
695 
696 static
697 void checkRowObjprod(
698  SCIP_ROW* row
699  )
700 {
701  SCIP_COL** cols;
702  SCIP_Real objprod;
703  int c;
704 
705  cols = row->cols;
706  assert(cols != NULL || row->len == 0);
707 
708  objprod = 0.0;
709 
710  for( c = row->len - 1; c >= 0; --c )
711  {
712  if( cols[c]->lppos >= 0 )
713  objprod += row->vals[c] * cols[c]->unchangedobj;
714  }
715 
716  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
717 }
718 #else
719 #define checkRowSqrnorm(row) /**/
720 #define checkRowSumnorm(row) /**/
721 #define checkRowObjprod(row) /**/
722 #endif
723 
724 /*
725  * Local methods for pseudo and loose objective values
726  */
727 
728 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
729 static
731  SCIP_LP* lp, /**< current LP data */
732  SCIP_SET* set, /**< global SCIP settings */
733  SCIP_PROB* prob /**< problem data */
734  )
735 {
736  SCIP_VAR** vars;
737  SCIP_Real obj;
738  int nvars;
739  int v;
740 
741  assert(lp != NULL);
742  assert(set != NULL);
743  assert(prob != NULL);
744  assert(!lp->looseobjvalid);
745 
746  vars = prob->vars;
747  nvars = prob->nvars;
748  lp->looseobjval = 0.0;
749 
750  /* iterate over all variables in the problem */
751  for( v = 0; v < nvars; ++v )
752  {
753  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
754  {
755  obj = SCIPvarGetObj(vars[v]);
756 
757  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
758  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
759  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
760  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
761  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
762  }
763  }
764 
765  /* the recomputed value is reliable */
766  lp->rellooseobjval = lp->looseobjval;
767  lp->looseobjvalid = TRUE;
768 }
769 
770 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
771 static
773  SCIP_LP* lp, /**< current LP data */
774  SCIP_SET* set, /**< global SCIP settings */
775  SCIP_PROB* prob /**< problem data */
776  )
777 {
778  SCIP_VAR** vars;
779  int nvars;
780  int v;
781 
782  assert(lp != NULL);
783  assert(set != NULL);
784  assert(prob != NULL);
785  assert(!lp->pseudoobjvalid);
786 
787  vars = prob->vars;
788  nvars = prob->nvars;
789  lp->pseudoobjval = 0.0;
790 
791  /* iterate over all variables in the problem */
792  for( v = 0; v < nvars; ++v )
793  {
794  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
795  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
796  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
797  {
798  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
799  }
800  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
801  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
802  {
803  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
804  }
805  }
806 
807  /* the recomputed value is reliable */
808  lp->relpseudoobjval = lp->pseudoobjval;
809  lp->pseudoobjvalid = TRUE;
810 }
811 
812 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
813 static
815  SCIP_LP* lp, /**< current LP data */
816  SCIP_SET* set, /**< global SCIP settings */
817  SCIP_PROB* prob /**< problem data */
818  )
819 {
820  SCIP_VAR** vars;
821  int nvars;
822  int v;
823 
824  assert(lp != NULL);
825  assert(set != NULL);
826  assert(prob != NULL);
827  assert(!lp->glbpseudoobjvalid);
828 
829  vars = prob->vars;
830  nvars = prob->nvars;
831  lp->glbpseudoobjval = 0.0;
832 
833  /* iterate over all variables in the problem */
834  for( v = 0; v < nvars; ++v )
835  {
836  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
837  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
838  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
839  {
840  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
841  }
842  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
843  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
844  {
845  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
846  }
847  }
848 
849  /* the recomputed value is reliable */
851  lp->glbpseudoobjvalid = TRUE;
852 }
853 
854 /** gets finite part of objective value of current LP that results from LOOSE variables only */
855 static
857  SCIP_LP* lp, /**< current LP data */
858  SCIP_SET* set, /**< global SCIP settings */
859  SCIP_PROB* prob /**< problem data */
860  )
861 {
862  assert(lp != NULL);
863  assert(set != NULL);
864  assert(prob != NULL);
865  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
866  assert(lp->flushed);
867  assert(lp->looseobjvalinf == 0);
868 
869  /* recalculate the loose objective value, if needed */
870  if( !lp->looseobjvalid )
871  recomputeLooseObjectiveValue(lp, set, prob);
872 
873  return lp->looseobjval;
874 }
875 
876 /** gets finite part of pseudo objective value of current LP */
877 static
879  SCIP_LP* lp, /**< current LP data */
880  SCIP_SET* set, /**< global SCIP settings */
881  SCIP_PROB* prob /**< problem data */
882  )
883 {
884  assert(lp != NULL);
885  assert(set != NULL);
886  assert(prob != NULL);
887 
888  /* recalculate the pseudo objective value, if needed */
889  if( !lp->pseudoobjvalid )
890  recomputePseudoObjectiveValue(lp, set, prob);
891 
892  return lp->pseudoobjval;
893 }
894 
895 /*
896  * Sorting and searching rows and columns
897  */
898 
899 
900 /** comparison method for sorting rows by non-decreasing index */
902 {
903  assert(elem1 != NULL);
904  assert(elem2 != NULL);
905 
906  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
907  return -1;
908  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
909  return +1;
910  else
911  {
912  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
913  return 0;
914  }
915 }
916 
917 
918 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
919 static
921  SCIP_COL* col /**< column to be sorted */
922  )
923 {
924  int i;
925 
926  assert(col != NULL);
927 
928  /* check, if column is already sorted in the LP part */
929  if( col->lprowssorted )
930  return;
931 
932  /* sort coefficients */
933  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
934 
935  /* update links */
936  for( i = 0; i < col->nlprows; ++i )
937  {
938  if( col->linkpos[i] >= 0 )
939  {
940  assert(col->rows[i]->cols[col->linkpos[i]] == col);
941  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
942  col->rows[i]->linkpos[col->linkpos[i]] = i;
943  }
944  }
945 
946  col->lprowssorted = TRUE;
947 }
948 
949 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
950  * ones
951  */
952 static
954  SCIP_COL* col /**< column to be sorted */
955  )
956 {
957  int i;
958 
959  assert(col != NULL);
960 
961  /* check, if column is already sorted in the non-LP part */
962  if( col->nonlprowssorted )
963  return;
964 
965  /* sort coefficients */
966  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
967 
968  /* update links */
969  for( i = col->nlprows; i < col->len; ++i )
970  {
971  if( col->linkpos[i] >= 0 )
972  {
973  assert(col->rows[i]->cols[col->linkpos[i]] == col);
974  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
975  col->rows[i]->linkpos[col->linkpos[i]] = i;
976  }
977  }
978 
979  col->nonlprowssorted = TRUE;
980 }
981 
982 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
983 static
985  SCIP_ROW* row /**< row to be sorted */
986  )
987 {
988  int i;
989 
990  assert(row != NULL);
991 
992  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
993  if( row->lpcolssorted || row->delaysort )
994  return;
995 
996  /* sort coefficients */
997  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
998 
999  /* update links */
1000  for( i = 0; i < row->nlpcols; ++i )
1001  {
1002  if( row->linkpos[i] >= 0 )
1003  {
1004  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1005  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1006  row->cols[i]->linkpos[row->linkpos[i]] = i;
1007  }
1008  }
1009 
1010  row->lpcolssorted = TRUE;
1011 }
1012 
1013 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1014  * higher ones
1015  */
1016 static
1018  SCIP_ROW* row /**< row to be sorted */
1019  )
1020 {
1021  int i;
1022 
1023  assert(row != NULL);
1024 
1025  checkRow(row);
1026 
1027  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1028  if( row->nonlpcolssorted || row->delaysort )
1029  return;
1030 
1031  /* sort coefficients */
1032  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1033 
1034  /* update links */
1035  for( i = row->nlpcols; i < row->len; ++i )
1036  {
1037  if( row->linkpos[i] >= 0 )
1038  {
1039  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1040  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1041  row->cols[i]->linkpos[row->linkpos[i]] = i;
1042  }
1043  }
1044 
1045  checkRow(row);
1046 
1047  row->nonlpcolssorted = TRUE;
1048 }
1049 
1050 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1051 static
1053  SCIP_COL* col, /**< column to be searched in */
1054  const SCIP_ROW* row, /**< coefficient to be searched for */
1055  int minpos, /**< first position of search range */
1056  int maxpos /**< last position of search range */
1057  )
1058 {
1059  int pos;
1060  int idx;
1061  int searchidx;
1062 
1063  assert(col != NULL);
1064  assert(row != NULL);
1065 
1066  /* binary search */
1067  searchidx = row->index;
1068  while(minpos <= maxpos)
1069  {
1070  pos = (minpos + maxpos)/2;
1071  assert(0 <= pos && pos < col->len);
1072  assert(col->rows[pos] != NULL);
1073  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1074  idx = col->rows[pos]->index;
1075  if( searchidx == idx )
1076  return pos;
1077  else if( searchidx < idx )
1078  maxpos = pos-1;
1079  else
1080  minpos = pos+1;
1081  }
1082 
1083  return -1;
1084 }
1085 
1086 /** searches coefficient in column, returns position in col vector or -1 if not found */
1087 static
1089  SCIP_COL* col, /**< column to be searched in */
1090  const SCIP_ROW* row /**< coefficient to be searched for */
1091  )
1092 {
1093  int pos;
1094 
1095  assert(col != NULL);
1096  assert(row != NULL);
1097 
1098  pos = -1;
1099 
1100  /* search in the linked LP rows */
1101  if( row->lppos >= 0 )
1102  {
1103  /* column has to be sorted, such that binary search works */
1104  colSortLP(col);
1105  assert(col->lprowssorted);
1106 
1107  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1108  if( pos >= 0 )
1109  return pos;
1110  }
1111 
1112  /* search in the non-LP/unlinked rows */
1113  if( row->lppos == -1 || col->nunlinked > 0 )
1114  {
1115  /* column has to be sorted, such that binary search works */
1116  colSortNonLP(col);
1117  assert(col->nonlprowssorted);
1118 
1119  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1120  }
1121 
1122  return pos;
1123 }
1124 
1125 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1126 static
1128  SCIP_ROW* row, /**< row to be searched in */
1129  const SCIP_COL* col, /**< coefficient to be searched for */
1130  int minpos, /**< first position of search range */
1131  int maxpos /**< last position of search range */
1132  )
1133 {
1134  int pos;
1135  int idx;
1136  int searchidx;
1137 
1138  assert(row != NULL);
1139  assert(col != NULL);
1140 
1141  /* binary search */
1142  searchidx = col->index;
1143  while(minpos <= maxpos)
1144  {
1145  pos = (minpos + maxpos)/2;
1146  assert(0 <= pos && pos < row->len);
1147  assert(row->cols[pos] != NULL);
1148  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1149  assert(row->cols_index[pos] == row->cols[pos]->index);
1150  idx = row->cols_index[pos];
1151  if( searchidx == idx )
1152  return pos;
1153  else if( searchidx < idx )
1154  maxpos = pos-1;
1155  else
1156  minpos = pos+1;
1157  }
1158 
1159  return -1;
1160 }
1161 
1162 /** searches coefficient in row, returns position in row vector or -1 if not found;
1163  * if the sorting of the row is delayed, returns -1
1164  */
1165 static
1167  SCIP_ROW* row, /**< row to be searched in */
1168  const SCIP_COL* col /**< coefficient to be searched for */
1169  )
1170 {
1171  int pos;
1172 
1173  assert(row != NULL);
1174  assert(col != NULL);
1175 
1176  if( row->delaysort )
1177  return -1;
1178 
1179  pos = -1;
1180 
1181  /* search in the linked LP columns */
1182  if( col->lppos >= 0 )
1183  {
1184  /* row has to be sorted, such that binary search works */
1185  rowSortLP(row);
1186  assert(row->lpcolssorted);
1187 
1188  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1189  }
1190 
1191  /* search in the non-LP/unlinked columns */
1192  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1193  {
1194  /* row has to be sorted, such that binary search works */
1195  rowSortNonLP(row);
1196  assert(row->nonlpcolssorted);
1197 
1198  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1199  }
1200 
1201 #ifndef NDEBUG
1202  /* validate result */
1203  assert(-1 <= pos && pos < row->len);
1204  if( pos >= 0 )
1205  assert(row->cols[pos] == col);
1206  else
1207  {
1208  int i;
1209  for( i = 0; i < row->len; ++i )
1210  assert(row->cols[i] != col);
1211  }
1212 #endif
1213 
1214  return pos;
1215 }
1216 
1217 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1218 static
1220  SCIP_COL* col, /**< LP column */
1221  int oldpos, /**< old position of coefficient */
1222  int newpos /**< new position of coefficient */
1223  )
1224 {
1225  assert(col != NULL);
1226  assert(0 <= oldpos && oldpos < col->len);
1227  assert(0 <= newpos && newpos < col->len);
1228  assert(col->rows[oldpos] != NULL);
1229 
1230  if( oldpos == newpos )
1231  return;
1232 
1233  col->rows[newpos] = col->rows[oldpos];
1234  col->vals[newpos] = col->vals[oldpos];
1235  col->linkpos[newpos] = col->linkpos[oldpos];
1236 
1237  /* update link position in row */
1238  if( col->linkpos[newpos] >= 0 )
1239  {
1240  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1241  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1242 
1243  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1244  }
1245 
1246  /* update sorted flags */
1247  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1248  col->lprowssorted = FALSE;
1249  else
1250  col->nonlprowssorted = FALSE;
1251 }
1252 
1253 /** swaps two coefficients in a column, and updates all corresponding data structures */
1254 static
1256  SCIP_COL* col, /**< LP column */
1257  int pos1, /**< position of first coefficient */
1258  int pos2 /**< position of second coefficient */
1259  )
1260 {
1261  SCIP_ROW* tmprow;
1262  SCIP_Real tmpval;
1263  int tmplinkpos;
1264 
1265  assert(col != NULL);
1266  assert(0 <= pos1 && pos1 < col->len);
1267  assert(0 <= pos2 && pos2 < col->len);
1268  assert(col->rows[pos1] != NULL);
1269 
1270  if( pos1 == pos2 )
1271  return;
1272 
1273  /* swap coefficients */
1274  tmprow = col->rows[pos2];
1275  tmpval = col->vals[pos2];
1276  tmplinkpos = col->linkpos[pos2];
1277 
1278  col->rows[pos2] = col->rows[pos1];
1279  col->vals[pos2] = col->vals[pos1];
1280  col->linkpos[pos2] = col->linkpos[pos1];
1281 
1282  col->rows[pos1] = tmprow;
1283  col->vals[pos1] = tmpval;
1284  col->linkpos[pos1] = tmplinkpos;
1285 
1286  /* update link position in rows */
1287  if( col->linkpos[pos1] >= 0 )
1288  {
1289  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1290  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1291 
1292  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1293  }
1294  if( col->linkpos[pos2] >= 0 )
1295  {
1296  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1297  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1298 
1299  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1300  }
1301 
1302  /* update sorted flags */
1303  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1304  col->lprowssorted = FALSE;
1305  else
1306  col->nonlprowssorted = FALSE;
1307  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1308  col->lprowssorted = FALSE;
1309  else
1310  col->nonlprowssorted = FALSE;
1311 }
1312 
1313 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1314 static
1316  SCIP_ROW* row, /**< LP row */
1317  int oldpos, /**< old position of coefficient */
1318  int newpos /**< new position of coefficient */
1319  )
1320 {
1321  assert(row != NULL);
1322  assert(0 <= oldpos && oldpos < row->len);
1323  assert(0 <= newpos && newpos < row->len);
1324  assert(row->cols[oldpos] != NULL);
1325 
1326  if( oldpos == newpos )
1327  return;
1328 
1329  row->cols[newpos] = row->cols[oldpos];
1330  row->cols_index[newpos] = row->cols_index[oldpos];
1331  row->vals[newpos] = row->vals[oldpos];
1332  row->linkpos[newpos] = row->linkpos[oldpos];
1333 
1334  /* update link position in column */
1335  if( row->linkpos[newpos] >= 0 )
1336  {
1337  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1338  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1339 
1340  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1341  }
1342 
1343  /* update sorted flags */
1344  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1345  row->lpcolssorted = FALSE;
1346  else
1347  row->nonlpcolssorted = FALSE;
1348 }
1349 
1350 /** swaps two coefficients in a row, and updates all corresponding data structures */
1351 static
1353  SCIP_ROW* row, /**< LP row */
1354  int pos1, /**< position of first coefficient */
1355  int pos2 /**< position of second coefficient */
1356  )
1357 {
1358  SCIP_COL* tmpcol;
1359  SCIP_Real tmpval;
1360  int tmpindex;
1361  int tmplinkpos;
1362 
1363  assert(row != NULL);
1364  assert(0 <= pos1 && pos1 < row->len);
1365  assert(0 <= pos2 && pos2 < row->len);
1366  assert(row->cols[pos1] != NULL);
1367  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1368 
1369  if( pos1 == pos2 )
1370  return;
1371 
1372  /* swap coefficients */
1373  tmpcol = row->cols[pos2];
1374  tmpindex = row->cols_index[pos2];
1375  tmpval = row->vals[pos2];
1376  tmplinkpos = row->linkpos[pos2];
1377 
1378  row->cols[pos2] = row->cols[pos1];
1379  row->cols_index[pos2] = row->cols_index[pos1];
1380  row->vals[pos2] = row->vals[pos1];
1381  row->linkpos[pos2] = row->linkpos[pos1];
1382 
1383  row->cols[pos1] = tmpcol;
1384  row->cols_index[pos1] = tmpindex;
1385  row->vals[pos1] = tmpval;
1386  row->linkpos[pos1] = tmplinkpos;
1387 
1388  /* update link position in columns */
1389  if( row->linkpos[pos1] >= 0 )
1390  {
1391  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1392  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1393 
1394  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1395  }
1396  if( row->linkpos[pos2] >= 0 )
1397  {
1398  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1399  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1400 
1401  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1402  }
1403 
1404  /* update sorted flags */
1405  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1406  row->lpcolssorted = FALSE;
1407  else
1408  row->nonlpcolssorted = FALSE;
1409  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1410  row->lpcolssorted = FALSE;
1411  else
1412  row->nonlpcolssorted = FALSE;
1413 }
1414 
1415 /** issues a ROWCOEFCHANGED event on the given row */
1416 static
1418  SCIP_ROW* row, /**< row which coefficient has changed */
1419  BMS_BLKMEM* blkmem, /**< block memory */
1420  SCIP_SET* set, /**< global SCIP settings */
1421  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1422  SCIP_COL* col, /**< the column which coefficient has changed */
1423  SCIP_Real oldval, /**< old value of the coefficient */
1424  SCIP_Real newval /**< new value of the coefficient */
1425  )
1426 {
1427  assert(row != NULL);
1428  assert(row->eventfilter != NULL);
1429  assert(col != NULL);
1430 
1431  /* check, if the row is being tracked for coefficient changes
1432  * if so, issue ROWCOEFCHANGED event
1433  */
1434  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1435  {
1436  SCIP_EVENT* event;
1437 
1438  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1439  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1440  }
1441 
1442  return SCIP_OKAY;
1443 }
1444 
1445 /** issues a ROWCONSTCHANGED event on the given row */
1446 static
1448  SCIP_ROW* row, /**< row which coefficient has changed */
1449  BMS_BLKMEM* blkmem, /**< block memory */
1450  SCIP_SET* set, /**< global SCIP settings */
1451  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1452  SCIP_Real oldval, /**< old value of the constant */
1453  SCIP_Real newval /**< new value of the constant */
1454  )
1455 {
1456  assert(row != NULL);
1457  assert(row->eventfilter != NULL);
1458 
1459  /* check, if the row is being tracked for coefficient changes
1460  * if so, issue ROWCONSTCHANGED event
1461  */
1462  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED) != 0) )
1463  {
1464  SCIP_EVENT* event;
1465 
1466  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1467  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1468  }
1469 
1470  return SCIP_OKAY;
1471 }
1472 
1473 /** issues a ROWSIDECHANGED event on the given row */
1474 static
1476  SCIP_ROW* row, /**< row which coefficient has changed */
1477  BMS_BLKMEM* blkmem, /**< block memory */
1478  SCIP_SET* set, /**< global SCIP settings */
1479  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1480  SCIP_SIDETYPE side, /**< the side that has changed */
1481  SCIP_Real oldval, /**< old value of side */
1482  SCIP_Real newval /**< new value of side */
1483  )
1484 {
1485  assert(row != NULL);
1486  assert(row->eventfilter != NULL);
1487 
1488  /* check, if the row is being tracked for coefficient changes
1489  * if so, issue ROWSIDECHANGED event
1490  */
1491  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED) != 0) )
1492  {
1493  SCIP_EVENT* event;
1494 
1495  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1496  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1497  }
1498 
1499  return SCIP_OKAY;
1500 }
1501 
1502 #if 0 /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1503 
1504 #ifdef NDEBUG
1505 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1506 #else
1507 #define ASSERT(x) assert(x)
1508 #endif
1509 
1510 static SCIP_Bool msgdisp_checklinks = FALSE;
1511 
1512 
1513 static
1514 void checkLinks(
1515  SCIP_LP* lp /**< current LP data */
1516  )
1517 {
1518  SCIP_COL* col;
1519  SCIP_ROW* row;
1520  int i;
1521  int j;
1522 
1523  ASSERT(lp != NULL);
1524 
1525  if( !msgdisp_checklinks )
1526  {
1527  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1528  msgdisp_checklinks = TRUE;
1529  }
1530 
1531  for( i = 0; i < lp->ncols; ++i )
1532  {
1533  col = lp->cols[i];
1534  ASSERT(col != NULL);
1535  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1536  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1537  ASSERT(col->nlprows <= col->len);
1538  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1539 
1540  for( j = 0; j < col->len; ++j )
1541  {
1542  row = col->rows[j];
1543  ASSERT(row != NULL);
1544  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1545  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1546  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1547  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1548  }
1549  }
1550 
1551  for( i = 0; i < lp->nrows; ++i )
1552  {
1553  row = lp->rows[i];
1554  ASSERT(row != NULL);
1555  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1556  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1557  ASSERT(row->nlpcols <= row->len);
1558  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1559 
1560  for( j = 0; j < row->len; ++j )
1561  {
1562  col = row->cols[j];
1563  ASSERT(col != NULL);
1564  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1565  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1566  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1567  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1568  }
1569  }
1570 }
1571 
1572 #undef ASSERT
1573 
1574 #else
1575 #define checkLinks(lp) /**/
1576 #endif
1577 
1578 /*
1579  * Changing announcements
1580  */
1581 
1582 /** announces, that the given coefficient in the constraint matrix changed */
1583 static
1585  SCIP_ROW* row, /**< LP row */
1586  SCIP_COL* col, /**< LP col */
1587  SCIP_LP* lp /**< current LP data */
1588  )
1589 {
1590  assert(row != NULL);
1591  assert(col != NULL);
1592  assert(lp != NULL);
1593 
1594  if( row->lpipos >= 0 && col->lpipos >= 0 )
1595  {
1596  assert(row->lpipos < lp->nlpirows);
1597  assert(col->lpipos < lp->nlpicols);
1598 
1599  /* we have to remember the change only in the row or in the column,
1600  * because the readdition of one vector would change the other automatically.
1601  */
1602  if( row->lpipos >= lp->lpifirstchgrow )
1603  row->coefchanged = TRUE;
1604  else if( col->lpipos >= lp->lpifirstchgcol )
1605  col->coefchanged = TRUE;
1606  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1607  {
1608  row->coefchanged = TRUE;
1609  lp->lpifirstchgrow = row->lpipos;
1610  }
1611  else
1612  {
1613  col->coefchanged = TRUE;
1614  lp->lpifirstchgcol = col->lpipos;
1615  }
1616 
1617  /* mark the current LP unflushed */
1618  lp->flushed = FALSE;
1619  }
1620 
1622  row->minactivity = SCIP_INVALID;
1623  row->maxactivity = SCIP_INVALID;
1624  row->validpsactivitydomchg = -1;
1625  row->validactivitybdsdomchg = -1;
1626 }
1627 
1628 
1629 
1630 /*
1631  * local column changing methods
1632  */
1633 
1634 /* forward declaration for colAddCoef() */
1635 static
1637  SCIP_ROW* row, /**< LP row */
1638  BMS_BLKMEM* blkmem, /**< block memory */
1639  SCIP_SET* set, /**< global SCIP settings */
1640  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1641  SCIP_LP* lp, /**< current LP data */
1642  SCIP_COL* col, /**< LP column */
1643  SCIP_Real val, /**< value of coefficient */
1644  int linkpos /**< position of row in the column's row array, or -1 */
1645  );
1646 
1647 /** adds a previously non existing coefficient to an LP column */
1648 static
1650  SCIP_COL* col, /**< LP column */
1651  BMS_BLKMEM* blkmem, /**< block memory */
1652  SCIP_SET* set, /**< global SCIP settings */
1653  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1654  SCIP_LP* lp, /**< current LP data */
1655  SCIP_ROW* row, /**< LP row */
1656  SCIP_Real val, /**< value of coefficient */
1657  int linkpos /**< position of column in the row's col array, or -1 */
1658  )
1659 {
1660  int pos;
1661 
1662  assert(blkmem != NULL);
1663  assert(col != NULL);
1664  assert(col->nlprows <= col->len);
1665  assert(col->var != NULL);
1666  assert(row != NULL);
1667  assert(!SCIPsetIsZero(set, val));
1668  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1669 
1670  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1671  assert(col->rows != NULL);
1672  assert(col->vals != NULL);
1673  assert(col->linkpos != NULL);
1674 
1675  pos = col->len;
1676  col->len++;
1677 
1678  /* 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
1679  * part of the column's arrays
1680  */
1681  if( row->lppos >= 0 && linkpos >= 0 )
1682  {
1683  /* move the first non-LP/not linked row to the end */
1684  if( col->nlprows < pos )
1685  {
1686  colMoveCoef(col, col->nlprows, pos);
1687  pos = col->nlprows;
1688  }
1689  col->nlprows++;
1690  }
1691 
1692  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1693  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1694 
1695  /* insert the row at the correct position and update the links */
1696  col->rows[pos] = row;
1697  col->vals[pos] = val;
1698  col->linkpos[pos] = linkpos;
1699  if( linkpos == -1 )
1700  {
1701  col->nunlinked++;
1702 
1703  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1704  * of the row is not complete
1705  */
1706  if( col->lppos >= 0 )
1707  {
1708  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1709  * has to be updated
1710  */
1711  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1712  if( row->lppos >= 0 )
1713  pos = col->nlprows-1;
1714  linkpos = col->linkpos[pos];
1715 
1716  assert(0 <= linkpos && linkpos < row->len);
1717  assert(row->cols[linkpos] == col);
1718  assert(col->rows[pos] == row);
1719  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1720  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1721  }
1722  }
1723  else
1724  {
1725  assert(row->linkpos[linkpos] == -1);
1726  assert(row->nunlinked > 0);
1727  row->linkpos[linkpos] = pos;
1728  row->nunlinked--;
1729 
1730  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1731  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1732  */
1733  if( col->lppos >= 0 )
1734  {
1735  row->nlpcols++;
1736  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1737 
1738  /* if no swap was necessary, mark nonlpcols to be unsorted */
1739  if( linkpos == row->nlpcols-1 )
1740  row->lpcolssorted = FALSE;
1741  }
1742  }
1743 
1744  /* update the sorted flags */
1745  if( row->lppos >= 0 && linkpos >= 0 )
1746  {
1747  assert(col->nlprows >= 1);
1748  assert(col->rows[col->nlprows-1] == row);
1749  if( col->nlprows > 1 )
1750  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1751  }
1752  else
1753  {
1754  assert(col->len - col->nlprows >= 1);
1755  assert(col->rows[col->len-1] == row);
1756  if( col->len - col->nlprows > 1 )
1757  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1758  }
1759 
1760  coefChanged(row, col, lp);
1761 
1762  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1763  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1764 
1765  return SCIP_OKAY;
1766 }
1767 
1768 /** deletes coefficient at given position from column */
1769 static
1771  SCIP_COL* col, /**< column to be changed */
1772  SCIP_SET* set, /**< global SCIP settings */
1773  SCIP_LP* lp, /**< current LP data */
1774  int pos /**< position in column vector to delete */
1775  )
1776 {
1777  SCIP_ROW* row;
1778 
1779  assert(col != NULL);
1780  assert(col->var != NULL);
1781  assert(set != NULL);
1782  assert(0 <= pos && pos < col->len);
1783  assert(col->rows[pos] != NULL);
1784  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1785  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1786 
1787  row = col->rows[pos];
1788  assert((row->lppos >= 0) == (pos < col->nlprows));
1789 
1790  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1791  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1792 
1793  if( col->linkpos[pos] == -1 )
1794  col->nunlinked--;
1795 
1796  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1797  if( pos < col->nlprows )
1798  {
1799  colMoveCoef(col, col->nlprows-1, pos);
1800  col->nlprows--;
1801  pos = col->nlprows;
1802  }
1803 
1804  /* move last coefficient to position of empty slot */
1805  colMoveCoef(col, col->len-1, pos);
1806  col->len--;
1807 
1808  coefChanged(row, col, lp);
1809 
1810  return SCIP_OKAY;
1811 }
1812 
1813 /** changes a coefficient at given position of an LP column */
1814 static
1816  SCIP_COL* col, /**< LP column */
1817  SCIP_SET* set, /**< global SCIP settings */
1818  SCIP_LP* lp, /**< current LP data */
1819  int pos, /**< position in column vector to change */
1820  SCIP_Real val /**< value of coefficient */
1821  )
1822 {
1823  assert(col != NULL);
1824  assert(col->var != NULL);
1825  assert(0 <= pos && pos < col->len);
1826  assert(col->rows[pos] != NULL);
1827  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1828 
1829  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1830  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1831 
1832  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1833  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1834 
1835  if( SCIPsetIsZero(set, val) )
1836  {
1837  /* delete existing coefficient */
1838  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1839  }
1840  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1841  {
1842  /* change existing coefficient */
1843  col->vals[pos] = val;
1844  coefChanged(col->rows[pos], col, lp);
1845  }
1846 
1847  return SCIP_OKAY;
1848 }
1849 
1850 
1851 
1852 
1853 /*
1854  * local row changing methods
1855  */
1856 
1857 /** update row norms after addition of coefficient */
1858 static
1860  SCIP_ROW* row, /**< LP row */
1861  SCIP_SET* set, /**< global SCIP settings */
1862  SCIP_COL* col, /**< column of added coefficient */
1863  SCIP_Real val, /**< value of added coefficient */
1864  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1865  )
1866 {
1867  SCIP_Real absval;
1868 
1869  assert(row != NULL);
1870  assert(row->nummaxval >= 0);
1871  assert(row->numminval >= 0);
1872  assert(set != NULL);
1873  assert(col != NULL);
1874 
1875  absval = REALABS(val);
1876  assert(!SCIPsetIsZero(set, absval));
1877 
1878  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1879  if( col->lppos >= 0 )
1880  {
1881  /* update squared Euclidean norm and sum norm */
1882  row->sqrnorm += SQR(absval);
1883  row->sumnorm += absval;
1884 
1885  /* update objective function scalar product */
1886  row->objprod += val * col->unchangedobj;
1887  }
1888 
1889  if( updateidxvals )
1890  {
1891  /* update min/maxidx */
1892  row->minidx = MIN(row->minidx, col->index);
1893  row->maxidx = MAX(row->maxidx, col->index);
1894 
1895  /* update maximal and minimal non-zero value */
1896  if( row->nummaxval > 0 )
1897  {
1898  if( SCIPsetIsGT(set, absval, row->maxval) )
1899  {
1900  row->maxval = absval;
1901  row->nummaxval = 1;
1902  }
1903  else if( SCIPsetIsGE(set, absval, row->maxval) )
1904  row->nummaxval++;
1905  }
1906  if( row->numminval > 0 )
1907  {
1908  if( SCIPsetIsLT(set, absval, row->minval) )
1909  {
1910  row->minval = absval;
1911  row->numminval = 1;
1912  }
1913  else if( SCIPsetIsLE(set, absval, row->minval) )
1914  row->numminval++;
1915  }
1916  }
1917  else
1918  {
1919  assert(row->minidx <= col->index);
1920  assert(row->maxidx >= col->index);
1921  assert(row->numminval <= 0 || SCIPsetIsGE(set, absval, row->minval));
1922  assert(row->nummaxval <= 0 || SCIPsetIsLE(set, absval, row->maxval));
1923  }
1924 }
1925 
1926 /** update row norms after deletion of coefficient */
1927 static
1929  SCIP_ROW* row, /**< LP row */
1930  SCIP_SET* set, /**< global SCIP settings */
1931  SCIP_COL* col, /**< column of deleted coefficient */
1932  SCIP_Real val, /**< value of deleted coefficient */
1933  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1934  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1935  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1936  )
1937 {
1938  SCIP_Real absval;
1939 
1940  assert(row != NULL);
1941  assert(row->nummaxval >= 0);
1942  assert(row->numminval >= 0);
1943  assert(set != NULL);
1944  assert(col != NULL);
1945 
1946  absval = REALABS(val);
1947  assert(!SCIPsetIsZero(set, absval));
1948  assert(row->nummaxval == 0 || SCIPsetIsGE(set, row->maxval, absval));
1949  assert(row->numminval == 0 || SCIPsetIsLE(set, row->minval, absval));
1950 
1951  /* update min/maxidx validity */
1952  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
1953  row->validminmaxidx = FALSE;
1954 
1955  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1956  if( forcenormupdate || col->lppos >= 0 )
1957  {
1958  /* update squared Euclidean norm and sum norm */
1959  row->sqrnorm -= SQR(absval);
1960  row->sqrnorm = MAX(row->sqrnorm, 0.0);
1961  row->sumnorm -= absval;
1962  row->sumnorm = MAX(row->sumnorm, 0.0);
1963 
1964  /* update objective function scalar product */
1965  row->objprod -= val * col->unchangedobj;
1966  }
1967 
1968  if( updateval )
1969  {
1970  /* update maximal and minimal non-zero value */
1971  if( row->nummaxval > 0 )
1972  {
1973  if( SCIPsetIsGE(set, absval, row->maxval) )
1974  row->nummaxval--;
1975  }
1976  if( row->numminval > 0 )
1977  {
1978  if( SCIPsetIsLE(set, absval, row->minval) )
1979  row->numminval--;
1980  }
1981  }
1982 }
1983 
1984 /** adds a previously non existing coefficient to an LP row */
1985 static
1987  SCIP_ROW* row, /**< LP row */
1988  BMS_BLKMEM* blkmem, /**< block memory */
1989  SCIP_SET* set, /**< global SCIP settings */
1990  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1991  SCIP_LP* lp, /**< current LP data */
1992  SCIP_COL* col, /**< LP column */
1993  SCIP_Real val, /**< value of coefficient */
1994  int linkpos /**< position of row in the column's row array, or -1 */
1995  )
1996 {
1997  int pos;
1998 
1999  assert(row != NULL);
2000  assert(row->nlpcols <= row->len);
2001  assert(blkmem != NULL);
2002  assert(col != NULL);
2003  assert(col->var != NULL);
2004  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2005  assert(!SCIPsetIsZero(set, val));
2006  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2007 
2008  if( row->nlocks > 0 )
2009  {
2010  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2011  return SCIP_INVALIDDATA;
2012  }
2013 
2014  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2015  assert(row->cols != NULL);
2016  assert(row->vals != NULL);
2017 
2018  pos = row->len;
2019  row->len++;
2020 
2021  /* 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
2022  * part of the row's arrays
2023  */
2024  if( col->lppos >= 0 && linkpos >= 0 )
2025  {
2026  /* move the first non-LP/not linked column to the end */
2027  if( row->nlpcols < pos )
2028  {
2029  rowMoveCoef(row, row->nlpcols, pos);
2030  pos = row->nlpcols;
2031  }
2032  row->nlpcols++;
2033  }
2034 
2035  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2036  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2037 
2038  /* insert the column at the correct position and update the links */
2039  row->cols[pos] = col;
2040  row->cols_index[pos] = col->index;
2041  row->vals[pos] = val;
2042  row->linkpos[pos] = linkpos;
2043  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2044  if( linkpos == -1 )
2045  {
2046  row->nunlinked++;
2047 
2048  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2049  * of the column is not complete
2050  */
2051  if( row->lppos >= 0 )
2052  {
2053  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2054  * has to be updated
2055  */
2056  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2057  if( col->lppos >= 0 )
2058  pos = row->nlpcols-1;
2059  linkpos = row->linkpos[pos];
2060 
2061  assert(0 <= linkpos && linkpos < col->len);
2062  assert(col->rows[linkpos] == row);
2063  assert(row->cols[pos] == col);
2064  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2065  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2066  }
2067  }
2068  else
2069  {
2070  assert(col->linkpos[linkpos] == -1);
2071  assert(col->nunlinked > 0);
2072  col->linkpos[linkpos] = pos;
2073  col->nunlinked--;
2074 
2075  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2076  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2077  */
2078  if( row->lppos >= 0 )
2079  {
2080  col->nlprows++;
2081  colSwapCoefs(col, linkpos, col->nlprows-1);
2082 
2083  /* if no swap was necessary, mark lprows to be unsorted */
2084  if( linkpos == col->nlprows-1 )
2085  col->lprowssorted = FALSE;
2086  }
2087  }
2088 
2089  /* update the sorted flags */
2090  if( col->lppos >= 0 && linkpos >= 0 )
2091  {
2092  assert(row->nlpcols >= 1);
2093  assert(row->cols[row->nlpcols-1] == col);
2094  if( row->nlpcols > 1 )
2095  {
2096  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2097  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2098  }
2099  }
2100  else
2101  {
2102  assert(row->len - row->nlpcols >= 1);
2103  assert(row->cols[row->len-1] == col);
2104  if( row->len - row->nlpcols > 1 )
2105  {
2106  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2107  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2108  }
2109  }
2110 
2111  /* update row norm */
2112  rowAddNorms(row, set, col, val, TRUE);
2113 
2114  coefChanged(row, col, lp);
2115 
2116  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2117  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2118 
2119  /* issue row coefficient changed event */
2120  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2121 
2122  return SCIP_OKAY;
2123 }
2124 
2125 /** deletes coefficient at given position from row */
2126 static
2128  SCIP_ROW* row, /**< row to be changed */
2129  BMS_BLKMEM* blkmem, /**< block memory */
2130  SCIP_SET* set, /**< global SCIP settings */
2131  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2132  SCIP_LP* lp, /**< current LP data */
2133  int pos /**< position in row vector to delete */
2134  )
2135 {
2136  SCIP_COL* col;
2137  SCIP_Real val;
2138 
2139  assert(row != NULL);
2140  assert(set != NULL);
2141  assert(0 <= pos && pos < row->len);
2142  assert(row->cols[pos] != NULL);
2143  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2144 
2145  col = row->cols[pos];
2146  val = row->vals[pos];
2147  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2148 
2149  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2150  val, SCIPvarGetName(col->var), pos, row->name);*/
2151 
2152  if( row->nlocks > 0 )
2153  {
2154  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2155  return SCIP_INVALIDDATA;
2156  }
2157 
2158  if( row->linkpos[pos] == -1 )
2159  row->nunlinked--;
2160 
2161  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2162  if( pos < row->nlpcols )
2163  {
2164  rowMoveCoef(row, row->nlpcols-1, pos);
2165  assert(!row->lpcolssorted);
2166  row->nlpcols--;
2167  pos = row->nlpcols;
2168  }
2169 
2170  /* move last coefficient to position of empty slot */
2171  rowMoveCoef(row, row->len-1, pos);
2172  row->len--;
2173 
2174  /* update norms */
2175  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2176 
2177  coefChanged(row, col, lp);
2178 
2179  /* issue row coefficient changed event */
2180  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2181 
2182  return SCIP_OKAY;
2183 }
2184 
2185 /** changes a coefficient at given position of an LP row */
2186 static
2188  SCIP_ROW* row, /**< LP row */
2189  BMS_BLKMEM* blkmem, /**< block memory */
2190  SCIP_SET* set, /**< global SCIP settings */
2191  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2192  SCIP_LP* lp, /**< current LP data */
2193  int pos, /**< position in row vector to change */
2194  SCIP_Real val /**< value of coefficient */
2195  )
2196 {
2197  SCIP_COL* col;
2198 
2199  assert(row != NULL);
2200  assert(0 <= pos && pos < row->len);
2201 
2202  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2203  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2204 
2205  if( row->nlocks > 0 )
2206  {
2207  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2208  return SCIP_INVALIDDATA;
2209  }
2210 
2211  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2212  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2213  col = row->cols[pos];
2214  assert(row->cols[pos] != NULL);
2215 
2216  if( SCIPsetIsZero(set, val) )
2217  {
2218  /* delete existing coefficient */
2219  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2220  }
2221  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2222  {
2223  SCIP_Real oldval;
2224 
2225  oldval = row->vals[pos];
2226 
2227  /* change existing coefficient */
2228  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2229  row->vals[pos] = val;
2230  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2231  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2232  coefChanged(row, col, lp);
2233 
2234  /* issue row coefficient changed event */
2235  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2236  }
2237 
2238  return SCIP_OKAY;
2239 }
2240 
2241 /** notifies LP row, that its sides were changed */
2242 static
2244  SCIP_ROW* row, /**< LP row */
2245  SCIP_SET* set, /**< global SCIP settings */
2246  SCIP_LP* lp, /**< current LP data */
2247  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2248  )
2249 {
2250  assert(row != NULL);
2251  assert(lp != NULL);
2252 
2253  if( row->lpipos >= 0 )
2254  {
2255  /* insert row in the chgrows list (if not already there) */
2256  if( !row->lhschanged && !row->rhschanged )
2257  {
2258  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2259  lp->chgrows[lp->nchgrows] = row;
2260  lp->nchgrows++;
2261  }
2262 
2263  /* mark side change in the row */
2264  switch( sidetype )
2265  {
2266  case SCIP_SIDETYPE_LEFT:
2267  row->lhschanged = TRUE;
2268  break;
2269  case SCIP_SIDETYPE_RIGHT:
2270  row->rhschanged = TRUE;
2271  break;
2272  default:
2273  SCIPerrorMessage("unknown row side type\n");
2274  SCIPABORT();
2275  return SCIP_INVALIDDATA; /*lint !e527*/
2276  }
2277 
2278  /* mark the current LP unflushed */
2279  lp->flushed = FALSE;
2280 
2281  assert(lp->nchgrows > 0);
2282  }
2283 
2284  return SCIP_OKAY;
2285 }
2286 
2287 
2288 
2289 
2290 /*
2291  * double linked coefficient matrix methods
2292  */
2293 
2294 /** insert column coefficients in corresponding rows */
2295 static
2297  SCIP_COL* col, /**< column data */
2298  BMS_BLKMEM* blkmem, /**< block memory */
2299  SCIP_SET* set, /**< global SCIP settings */
2300  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2301  SCIP_LP* lp /**< current LP data */
2302  )
2303 {
2304  int i;
2305 
2306  assert(col != NULL);
2307  assert(col->var != NULL);
2308  assert(blkmem != NULL);
2309  assert(set != NULL);
2310  assert(lp != NULL);
2311 
2312  if( col->nunlinked > 0 )
2313  {
2314  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2315 
2316  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2317  for( i = col->nlprows; i < col->len; ++i )
2318  {
2319  assert(!SCIPsetIsZero(set, col->vals[i]));
2320  if( col->linkpos[i] == -1 )
2321  {
2322  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2323  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2324  }
2325  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2326  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2327  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2328  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2329  }
2330  }
2331  assert(col->nunlinked == 0);
2332 
2333  checkLinks(lp);
2334 
2335  return SCIP_OKAY;
2336 }
2337 
2338 /** removes column coefficients from corresponding rows */
2339 static
2341  SCIP_COL* col, /**< column data */
2342  BMS_BLKMEM* blkmem, /**< block memory */
2343  SCIP_SET* set, /**< global SCIP settings */
2344  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2345  SCIP_LP* lp /**< current LP data */
2346  )
2347 {
2348  int i;
2349 
2350  assert(col != NULL);
2351  assert(col->var != NULL);
2352  assert(blkmem != NULL);
2353  assert(set != NULL);
2354  assert(lp != NULL);
2355 
2356  if( col->nunlinked < col->len )
2357  {
2358  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2359  for( i = 0; i < col->len; ++i )
2360  {
2361  if( col->linkpos[i] >= 0 )
2362  {
2363  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2364  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2365  col->linkpos[i] = -1;
2366  col->nunlinked++;
2367  }
2368  }
2369  }
2370  assert(col->nunlinked == col->len);
2371 
2372  checkLinks(lp);
2373 
2374  return SCIP_OKAY;
2375 }
2376 
2377 /** insert row coefficients in corresponding columns */
2378 static
2380  SCIP_ROW* row, /**< row data */
2381  BMS_BLKMEM* blkmem, /**< block memory */
2382  SCIP_SET* set, /**< global SCIP settings */
2383  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2384  SCIP_LP* lp /**< current LP data */
2385  )
2386 {
2387  int i;
2388 
2389  assert(row != NULL);
2390  assert(blkmem != NULL);
2391  assert(set != NULL);
2392  assert(lp != NULL);
2393 
2394  if( row->nunlinked > 0 )
2395  {
2396  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2397 
2398  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2399  for( i = row->nlpcols; i < row->len; ++i )
2400  {
2401  assert(!SCIPsetIsZero(set, row->vals[i]));
2402  if( row->linkpos[i] == -1 )
2403  {
2404  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2405  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2406  }
2407  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2408  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2409  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2410  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2411  }
2412  }
2413  assert(row->nunlinked == 0);
2414 
2415  checkLinks(lp);
2416 
2417  return SCIP_OKAY;
2418 }
2419 
2420 /** removes row coefficients from corresponding columns */
2421 static
2423  SCIP_ROW* row, /**< row data */
2424  SCIP_SET* set, /**< global SCIP settings */
2425  SCIP_LP* lp /**< current LP data */
2426  )
2427 {
2428  int i;
2429 
2430  assert(row != NULL);
2431  assert(set != NULL);
2432  assert(lp != NULL);
2433 
2434  if( row->nunlinked < row->len )
2435  {
2436  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2437  for( i = 0; i < row->len; ++i )
2438  {
2439  if( row->linkpos[i] >= 0 )
2440  {
2441  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2442  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2443  row->nunlinked++;
2444  }
2445  }
2446  }
2447  assert(row->nunlinked == row->len);
2448 
2449  return SCIP_OKAY;
2450 }
2451 
2452 
2453 
2454 
2455 /*
2456  * local LP parameter methods
2457  */
2458 
2459 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2460 static
2462  SCIP_LP* lp, /**< current LP data */
2463  SCIP_LPPARAM lpparam, /**< LP parameter */
2464  int value, /**< value to set parameter to */
2465  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2466  )
2467 {
2468  SCIP_RETCODE retcode;
2469 
2470  assert(lp != NULL);
2471  assert(success != NULL);
2472 
2473  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2474 
2475  /* check, if parameter is unknown */
2476  if( retcode == SCIP_PARAMETERUNKNOWN )
2477  {
2478  *success = FALSE;
2479  return SCIP_OKAY;
2480  }
2481  *success = TRUE;
2482 
2483  return retcode;
2484 }
2485 
2486 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2487 static
2489  SCIP_LP* lp, /**< current LP data */
2490  SCIP_LPPARAM lpparam, /**< LP parameter */
2491  SCIP_Bool value, /**< value to set parameter to */
2492  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2493  )
2494 {
2495  return lpSetIntpar(lp, lpparam, (int)value, success);
2496 }
2497 
2498 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2499 static
2501  SCIP_LP* lp, /**< current LP data */
2502  SCIP_LPPARAM lpparam, /**< LP parameter */
2503  SCIP_Real value, /**< value to set parameter to */
2504  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2505  )
2506 {
2507  SCIP_RETCODE retcode;
2508 
2509  assert(lp != NULL);
2510  assert(success != NULL);
2511 
2512  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2513 
2514  /* check, if parameter is unknown */
2515  if( retcode == SCIP_PARAMETERUNKNOWN )
2516  {
2517  *success = FALSE;
2518  return SCIP_OKAY;
2519  }
2520  *success = TRUE;
2521 
2522  return retcode;
2523 }
2524 
2525 #ifndef NDEBUG
2526 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2527 static
2529  SCIP_LP* lp, /**< current LP data */
2530  SCIP_LPPARAM lpparam, /**< LP parameter */
2531  int value /**< value parameter should have */
2532  )
2533 {
2534  SCIP_RETCODE retcode;
2535  int lpivalue;
2536 
2537  assert(lp != NULL);
2538 
2539  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2540 
2541  /* ignore unknown parameter error */
2542  if( retcode == SCIP_PARAMETERUNKNOWN )
2543  return SCIP_OKAY;
2544 
2545  /* check value */
2546  assert(lpivalue == value);
2547 
2548  return retcode;
2549 }
2550 
2551 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2552 static
2554  SCIP_LP* lp, /**< current LP data */
2555  SCIP_LPPARAM lpparam, /**< LP parameter */
2556  SCIP_Bool value /**< value parameter should have */
2557  )
2558 {
2559  return lpCheckIntpar(lp, lpparam, (int)value);
2560 }
2561 
2562 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2563 static
2565  SCIP_LP* lp, /**< current LP data */
2566  SCIP_LPPARAM lpparam, /**< LP parameter */
2567  SCIP_Real value /**< value parameter should have */
2568  )
2569 {
2570  SCIP_RETCODE retcode;
2571  SCIP_Real lpivalue;
2572 
2573  assert(lp != NULL);
2574 
2575  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2576 
2577  /* ignore unknown parameter error */
2578  if( retcode == SCIP_PARAMETERUNKNOWN )
2579  return SCIP_OKAY;
2580 
2581  /* check value */
2582  assert(lpivalue == value); /*lint !e777*/
2583 
2584  return retcode;
2585 }
2586 #else
2587 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2588 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2589 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2590 #endif
2591 
2592 /** should the objective limit of the LP solver be disabled */
2593 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2594 
2595 /** sets the upper objective limit of the LP solver */
2596 static
2598  SCIP_LP* lp, /**< current LP data */
2599  SCIP_SET* set, /**< global SCIP settings */
2600  SCIP_Real uobjlim /**< new feasibility tolerance */
2601  )
2602 {
2603  assert(lp != NULL);
2604  assert(set != NULL);
2605 
2606  /* we disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2607  * solver's objective limit handling, so we return here and do not apply the objective limit
2608  */
2609  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2610  return SCIP_OKAY;
2611 
2612  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2613  if( SCIPsetIsInfinity(set, uobjlim) )
2614  uobjlim = SCIPlpiInfinity(lp->lpi);
2615 
2617 
2618  if( uobjlim != lp->lpiuobjlim ) /*lint !e777*/
2619  {
2620  SCIP_Bool success;
2621 
2622  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_UOBJLIM, uobjlim, &success) );
2623  if( success )
2624  {
2625  /* mark the current solution invalid */
2626  lp->solved = FALSE;
2627  lp->primalfeasible = FALSE;
2628  lp->lpobjval = SCIP_INVALID;
2630  lp->lpiuobjlim = uobjlim;
2631  }
2632  }
2633 
2634  return SCIP_OKAY;
2635 }
2636 
2637 /** sets the feasibility tolerance of the LP solver */
2638 static
2640  SCIP_LP* lp, /**< current LP data */
2641  SCIP_Real feastol, /**< new feasibility tolerance */
2642  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2643  )
2644 {
2645  assert(lp != NULL);
2646  assert(feastol >= 0.0);
2647  assert(success != NULL);
2648 
2650 
2651  if( feastol != lp->lpifeastol ) /*lint !e777*/
2652  {
2653  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2654  if( *success )
2655  {
2656  if( lp->nrows > 0 && feastol < lp->lpifeastol )
2657  {
2658  /* mark the current solution invalid */
2659  lp->solved = FALSE;
2660  lp->primalfeasible = FALSE;
2661  lp->lpobjval = SCIP_INVALID;
2663  }
2664  lp->lpifeastol = feastol;
2665  }
2666  }
2667  else
2668  *success = FALSE;
2669 
2670  return SCIP_OKAY;
2671 }
2672 
2673 /** sets the reduced costs feasibility tolerance of the LP solver */
2674 static
2676  SCIP_LP* lp, /**< current LP data */
2677  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2678  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2679  )
2680 {
2681  assert(lp != NULL);
2682  assert(dualfeastol >= 0.0);
2683  assert(success != NULL);
2684 
2686 
2687  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2688  {
2689  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2690  if( *success )
2691  {
2692  if( lp->nrows > 0 && dualfeastol < lp->lpidualfeastol )
2693  {
2694  /* mark the current solution invalid */
2695  lp->solved = FALSE;
2696  lp->dualfeasible = FALSE;
2697  lp->lpobjval = SCIP_INVALID;
2699  }
2700  lp->lpidualfeastol = dualfeastol;
2701  }
2702  }
2703  else
2704  *success = FALSE;
2705 
2706  return SCIP_OKAY;
2707 }
2708 
2709 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2710 static
2712  SCIP_LP* lp, /**< current LP data */
2713  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2714  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2715  )
2716 {
2717  assert(lp != NULL);
2718  assert(barrierconvtol >= 0.0);
2719  assert(success != NULL);
2720 
2722 
2723  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2724  {
2725  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2726  if( *success )
2727  {
2728  if( lp->nrows > 0 && barrierconvtol < lp->lpibarrierconvtol
2730  {
2731  /* mark the current solution invalid */
2732  lp->solved = FALSE;
2733  lp->dualfeasible = FALSE;
2734  lp->lpobjval = SCIP_INVALID;
2736  }
2737  lp->lpibarrierconvtol = barrierconvtol;
2738  }
2739  }
2740  else
2741  *success = FALSE;
2742 
2743  return SCIP_OKAY;
2744 }
2745 
2746 /** sets the FROMSCRATCH setting of the LP solver */
2747 static
2749  SCIP_LP* lp, /**< current LP data */
2750  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2751  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2752  )
2753 {
2754  assert(lp != NULL);
2755  assert(success != NULL);
2756 
2758 
2759  if( fromscratch != lp->lpifromscratch )
2760  {
2761  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2762  if( *success )
2763  lp->lpifromscratch = fromscratch;
2764  }
2765  else
2766  *success = FALSE;
2767 
2768  return SCIP_OKAY;
2769 }
2770 
2771 /** sets the FASTMIP setting of the LP solver */
2772 static
2774  SCIP_LP* lp, /**< current LP data */
2775  int fastmip, /**< new FASTMIP setting */
2776  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2777  )
2778 {
2779  assert(lp != NULL);
2780  assert(success != NULL);
2781  assert(0 <= fastmip && fastmip <= 1);
2782 
2784 
2785  if( fastmip != lp->lpifastmip )
2786  {
2787  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2788  if( *success )
2789  lp->lpifastmip = fastmip;
2790  }
2791  else
2792  *success = FALSE;
2793 
2794  return SCIP_OKAY;
2795 }
2796 
2797 /** sets the SCALING setting of the LP solver */
2798 static
2800  SCIP_LP* lp, /**< current LP data */
2801  int scaling, /**< new SCALING setting */
2802  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2803  )
2804 {
2805  assert(lp != NULL);
2806  assert(success != NULL);
2807 
2809 
2810  if( scaling != lp->lpiscaling )
2811  {
2812  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2813  if( *success )
2814  lp->lpiscaling = scaling;
2815  }
2816  else
2817  *success = FALSE;
2818 
2819  return SCIP_OKAY;
2820 }
2821 
2822 /** sets the number of THREADS of the LP solver */
2823 static
2825  SCIP_LP* lp, /**< current LP data */
2826  int threads, /**< new number of threads used to solve the LP */
2827  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2828  )
2829 {
2830  assert(lp != NULL);
2831  assert(success != NULL);
2832 
2834 
2835  if( threads != lp->lpithreads )
2836  {
2837  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2838  if( *success )
2839  lp->lpithreads = threads;
2840  }
2841  else
2842  *success = FALSE;
2843 
2844  return SCIP_OKAY;
2845 }
2846 
2847 /** sets the PRESOLVING setting of the LP solver */
2848 static
2850  SCIP_LP* lp, /**< current LP data */
2851  SCIP_Bool presolving, /**< new PRESOLVING setting */
2852  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2853  )
2854 {
2855  assert(lp != NULL);
2856  assert(success != NULL);
2857 
2859 
2860  if( presolving != lp->lpipresolving )
2861  {
2862  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2863  if( *success )
2864  lp->lpipresolving = presolving;
2865  }
2866  else
2867  *success = FALSE;
2868 
2869  return SCIP_OKAY;
2870 }
2871 
2872 /** sets the ROWREPSWITCH setting of the LP solver */
2873 static
2875  SCIP_LP* lp, /**< current LP data */
2876  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2877  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2878  )
2879 {
2880  assert(lp != NULL);
2881  assert(success != NULL);
2882 
2884 
2885  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2886  {
2887  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2888  if( *success )
2889  lp->lpirowrepswitch = rowrepswitch;
2890  }
2891  else
2892  *success = FALSE;
2893 
2894  return SCIP_OKAY;
2895 }
2896 
2897 /** sets the iteration limit of the LP solver */
2898 static
2900  SCIP_LP* lp, /**< current LP data */
2901  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2902  )
2903 {
2904  SCIP_Bool success;
2905 
2906  assert(lp != NULL);
2907  assert(itlim >= -1);
2908 
2909  if( itlim == -1 )
2910  itlim = INT_MAX;
2911 
2913 
2914  if( itlim != lp->lpiitlim )
2915  {
2916  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2917  if( success )
2918  {
2919  if( itlim > lp->lpiitlim )
2920  {
2921  /* mark the current solution invalid */
2922  lp->solved = FALSE;
2923  lp->lpobjval = SCIP_INVALID;
2925  }
2926  lp->lpiitlim = itlim;
2927  }
2928  }
2929 
2930  return SCIP_OKAY;
2931 }
2932 
2933 /** sets the pricing strategy of the LP solver */
2934 static
2936  SCIP_LP* lp, /**< current LP data */
2937  SCIP_PRICING pricing /**< pricing strategy */
2938  )
2939 {
2940  SCIP_Bool success;
2941 
2942  assert(lp != NULL);
2943 
2945 
2946  if( pricing != lp->lpipricing )
2947  {
2948  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
2949  if( success )
2950  lp->lpipricing = pricing;
2951  }
2952 
2953  return SCIP_OKAY;
2954 }
2955 
2956 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
2957 static
2959  SCIP_LP* lp, /**< current LP data */
2960  char pricingchar /**< character representing the pricing strategy */
2961  )
2962 {
2963  SCIP_PRICING pricing;
2964 
2965  switch( pricingchar )
2966  {
2967  case 'l':
2968  pricing = SCIP_PRICING_LPIDEFAULT;
2969  break;
2970  case 'a':
2971  pricing = SCIP_PRICING_AUTO;
2972  break;
2973  case 'f':
2974  pricing = SCIP_PRICING_FULL;
2975  break;
2976  case 'p':
2977  pricing = SCIP_PRICING_PARTIAL;
2978  break;
2979  case 's':
2980  pricing = SCIP_PRICING_STEEP;
2981  break;
2982  case 'q':
2983  pricing = SCIP_PRICING_STEEPQSTART;
2984  break;
2985  case 'd':
2986  pricing = SCIP_PRICING_DEVEX;
2987  break;
2988  default:
2989  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
2990  return SCIP_INVALIDDATA;
2991  }
2992 
2993  SCIP_CALL( lpSetPricing(lp, pricing) );
2994 
2995  return SCIP_OKAY;
2996 }
2997 
2998 /** sets the verbosity of the LP solver */
2999 static
3001  SCIP_LP* lp, /**< current LP data */
3002  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3003  )
3004 {
3005  SCIP_Bool success;
3006 
3007  assert(lp != NULL);
3008 
3010 
3011  if( lpinfo != lp->lpilpinfo )
3012  {
3013  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3014  if( success )
3015  lp->lpilpinfo = lpinfo;
3016  }
3017 
3018  return SCIP_OKAY;
3019 }
3020 
3021 /** sets the CONDITIONLIMIT setting of the LP solver */
3022 static
3024  SCIP_LP* lp, /**< current LP data */
3025  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3026  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3027  )
3028 {
3029  assert(lp != NULL);
3030  assert(success != NULL);
3031 
3033 
3034  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3035  {
3036  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3037  if( *success )
3038  lp->lpiconditionlimit = condlimit;
3039  }
3040  else
3041  *success = FALSE;
3042 
3043  return SCIP_OKAY;
3044 }
3045 
3046 /** sets the type of timer of the LP solver */
3047 static
3049  SCIP_LP* lp, /**< current LP data */
3050  SCIP_CLOCKTYPE timing, /**< new timing value */
3051  SCIP_Bool enabled, /**< is timing enabled? */
3052  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3053  )
3054 {
3055  int lptiming;
3056 
3057  assert(lp != NULL);
3058  assert(success != NULL);
3059  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2);
3060 
3062 
3063  if( !enabled )
3064  lptiming = 0;
3065  else
3066  lptiming = (int) timing;
3067 
3068  if( lptiming != lp->lpitiming ) /*lint !e777*/
3069  {
3070  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3071  if( *success )
3072  lp->lpitiming = lptiming;
3073  }
3074  else
3075  *success = FALSE;
3076 
3077  return SCIP_OKAY;
3078 }
3079 
3080 /** sets the initial random seed of the LP solver */
3081 static
3083  SCIP_LP* lp, /**< current LP data */
3084  int randomseed, /**< new initial random seed */
3085  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3086  )
3087 {
3088  assert(lp != NULL);
3089  assert(success != NULL);
3090 
3091  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3092 
3093  if( randomseed == 0 )
3094  {
3095  lp->lpirandomseed = randomseed;
3096  *success = TRUE;
3097  }
3098  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3099  {
3100  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3101  if( *success )
3102  lp->lpirandomseed = randomseed;
3103  }
3104  else
3105  *success = FALSE;
3106 
3107  return SCIP_OKAY;
3108 }
3109 
3110 /** sets the LP solution polishing method */
3111 static
3113  SCIP_LP* lp, /**< current LP data */
3114  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3115  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3116  )
3117 {
3118  assert(lp != NULL);
3119  assert(success != NULL);
3120 
3121  if( polishing != lp->lpisolutionpolishing )
3122  {
3123  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3124  if( *success )
3125  lp->lpisolutionpolishing = polishing;
3126  }
3127  else
3128  *success = FALSE;
3129 
3130  return SCIP_OKAY;
3131 }
3132 
3133 /*
3134  * Column methods
3135  */
3136 
3137 /** creates an LP column */
3139  SCIP_COL** col, /**< pointer to column data */
3140  BMS_BLKMEM* blkmem, /**< block memory */
3141  SCIP_SET* set, /**< global SCIP settings */
3142  SCIP_STAT* stat, /**< problem statistics */
3143  SCIP_VAR* var, /**< variable, this column represents */
3144  int len, /**< number of nonzeros in the column */
3145  SCIP_ROW** rows, /**< array with rows of column entries */
3146  SCIP_Real* vals, /**< array with coefficients of column entries */
3147  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3148  )
3149 {
3150  int i;
3151 
3152  assert(col != NULL);
3153  assert(blkmem != NULL);
3154  assert(set != NULL);
3155  assert(stat != NULL);
3156  assert(var != NULL);
3157  assert(len >= 0);
3158  assert(len == 0 || (rows != NULL && vals != NULL));
3159 
3160  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3161 
3162  if( len > 0 )
3163  {
3164  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3165  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3166  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3167 
3168  for( i = 0; i < len; ++i )
3169  {
3170  assert(rows[i] != NULL);
3171  assert(!SCIPsetIsZero(set, vals[i]));
3172  (*col)->linkpos[i] = -1;
3173  }
3174  }
3175  else
3176  {
3177  (*col)->rows = NULL;
3178  (*col)->vals = NULL;
3179  (*col)->linkpos = NULL;
3180  }
3181 
3182  (*col)->var = var;
3183  (*col)->obj = SCIPvarGetObj(var);
3184  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3185  (*col)->lb = SCIPvarGetLbLocal(var);
3186  (*col)->ub = SCIPvarGetUbLocal(var);
3187  (*col)->flushedobj = 0.0;
3188  (*col)->flushedlb = 0.0;
3189  (*col)->flushedub = 0.0;
3190  (*col)->index = stat->ncolidx;
3191  SCIPstatIncrement(stat, set, ncolidx);
3192  (*col)->size = len;
3193  (*col)->len = len;
3194  (*col)->nlprows = 0;
3195  (*col)->nunlinked = len;
3196  (*col)->lppos = -1;
3197  (*col)->lpipos = -1;
3198  (*col)->lpdepth = -1;
3199  (*col)->primsol = 0.0;
3200  (*col)->redcost = SCIP_INVALID;
3201  (*col)->farkascoef = SCIP_INVALID;
3202  (*col)->minprimsol = (*col)->ub;
3203  (*col)->maxprimsol = (*col)->lb;
3204  (*col)->sbdown = SCIP_INVALID;
3205  (*col)->sbup = SCIP_INVALID;
3206  (*col)->sbsolval = SCIP_INVALID;
3207  (*col)->sblpobjval = SCIP_INVALID;
3208  (*col)->sbnode = -1;
3209  (*col)->validredcostlp = -1;
3210  (*col)->validfarkaslp = -1;
3211  (*col)->validsblp = -1;
3212  (*col)->sbitlim = -1;
3213  (*col)->nsbcalls = 0;
3214  (*col)->age = 0;
3215  (*col)->obsoletenode = -1;
3216  (*col)->var_probindex = SCIPvarGetProbindex(var);
3217  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3218  (*col)->lprowssorted = TRUE;
3219  (*col)->nonlprowssorted = (len <= 1);
3220  (*col)->objchanged = FALSE;
3221  (*col)->lbchanged = FALSE;
3222  (*col)->ubchanged = FALSE;
3223  (*col)->coefchanged = FALSE;
3224  (*col)->integral = SCIPvarIsIntegral(var);
3225  (*col)->removable = removable;
3226  (*col)->sbdownvalid = FALSE;
3227  (*col)->sbupvalid = FALSE;
3228  (*col)->lazylb = SCIPvarGetLbLazy(var);
3229  (*col)->lazyub = SCIPvarGetUbLazy(var);
3230  (*col)->storedsolvals = NULL;
3231 
3232  return SCIP_OKAY;
3233 }
3234 
3235 /** frees an LP column */
3237  SCIP_COL** col, /**< pointer to LP column */
3238  BMS_BLKMEM* blkmem, /**< block memory */
3239  SCIP_SET* set, /**< global SCIP settings */
3240  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3241  SCIP_LP* lp /**< current LP data */
3242  )
3243 {
3244  assert(blkmem != NULL);
3245  assert(col != NULL);
3246  assert(*col != NULL);
3247  assert((*col)->var != NULL);
3248  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3249  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3250  assert((*col)->lppos == -1);
3251  assert((*col)->lpipos == -1);
3252 
3253  /* remove column indices from corresponding rows */
3254  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3255 
3256  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3257  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3258  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3259  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3260  BMSfreeBlockMemory(blkmem, col);
3261 
3262  return SCIP_OKAY;
3263 }
3264 
3265 /** output column to file stream */
3267  SCIP_COL* col, /**< LP column */
3268  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3269  FILE* file /**< output file (or NULL for standard output) */
3270  )
3271 {
3272  int r;
3273 
3274  assert(col != NULL);
3275  assert(col->var != NULL);
3276 
3277  /* print bounds */
3278  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3279 
3280  /* print coefficients */
3281  if( col->len == 0 )
3282  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3283  for( r = 0; r < col->len; ++r )
3284  {
3285  assert(col->rows[r] != NULL);
3286  assert(col->rows[r]->name != NULL);
3287  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3288  }
3289  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3290 }
3291 
3292 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3293  */
3295  SCIP_COL* col /**< column to be sorted */
3296  )
3297 {
3298  /* sort LP rows */
3299  colSortLP(col);
3300 
3301  /* sort non-LP rows */
3302  colSortNonLP(col);
3303 }
3304 
3305 /** adds a previously non existing coefficient to an LP column */
3307  SCIP_COL* col, /**< LP column */
3308  BMS_BLKMEM* blkmem, /**< block memory */
3309  SCIP_SET* set, /**< global SCIP settings */
3310  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3311  SCIP_LP* lp, /**< current LP data */
3312  SCIP_ROW* row, /**< LP row */
3313  SCIP_Real val /**< value of coefficient */
3314  )
3315 {
3316  assert(lp != NULL);
3317  assert(!lp->diving);
3318 
3319  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3320 
3321  checkLinks(lp);
3322 
3323  return SCIP_OKAY;
3324 }
3325 
3326 /** deletes existing coefficient from column */
3328  SCIP_COL* col, /**< column to be changed */
3329  BMS_BLKMEM* blkmem, /**< block memory */
3330  SCIP_SET* set, /**< global SCIP settings */
3331  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3332  SCIP_LP* lp, /**< current LP data */
3333  SCIP_ROW* row /**< coefficient to be deleted */
3334  )
3335 {
3336  int pos;
3337 
3338  assert(col != NULL);
3339  assert(col->var != NULL);
3340  assert(lp != NULL);
3341  assert(!lp->diving);
3342  assert(row != NULL);
3343 
3344  /* search the position of the row in the column's row vector */
3345  pos = colSearchCoef(col, row);
3346  if( pos == -1 )
3347  {
3348  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3349  return SCIP_INVALIDDATA;
3350  }
3351  assert(0 <= pos && pos < col->len);
3352  assert(col->rows[pos] == row);
3353 
3354  /* if row knows of the column, remove the column from the row's col vector */
3355  if( col->linkpos[pos] >= 0 )
3356  {
3357  assert(row->cols[col->linkpos[pos]] == col);
3358  assert(row->cols_index[col->linkpos[pos]] == col->index);
3359  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3360  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3361  }
3362 
3363  /* delete the row from the column's row vector */
3364  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3365 
3366  checkLinks(lp);
3367 
3368  return SCIP_OKAY;
3369 }
3370 
3371 /** changes or adds a coefficient to an LP column */
3373  SCIP_COL* col, /**< 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  SCIP_ROW* row, /**< LP row */
3379  SCIP_Real val /**< value of coefficient */
3380  )
3381 {
3382  int pos;
3383 
3384  assert(col != NULL);
3385  assert(lp != NULL);
3386  assert(!lp->diving);
3387  assert(row != NULL);
3388 
3389  /* search the position of the row in the column's row vector */
3390  pos = colSearchCoef(col, row);
3391 
3392  /* check, if row already exists in the column's row vector */
3393  if( pos == -1 )
3394  {
3395  /* add previously not existing coefficient */
3396  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3397  }
3398  else
3399  {
3400  /* modify already existing coefficient */
3401  assert(0 <= pos && pos < col->len);
3402  assert(col->rows[pos] == row);
3403 
3404  /* if row knows of the column, change the corresponding coefficient in the row */
3405  if( col->linkpos[pos] >= 0 )
3406  {
3407  assert(row->cols[col->linkpos[pos]] == col);
3408  assert(row->cols_index[col->linkpos[pos]] == col->index);
3409  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3410  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3411  }
3412 
3413  /* change the coefficient in the column */
3414  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3415  }
3416 
3417  checkLinks(lp);
3418 
3419  return SCIP_OKAY;
3420 }
3421 
3422 /** increases value of an existing or non-existing coefficient in an LP column */
3424  SCIP_COL* col, /**< LP column */
3425  BMS_BLKMEM* blkmem, /**< block memory */
3426  SCIP_SET* set, /**< global SCIP settings */
3427  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3428  SCIP_LP* lp, /**< current LP data */
3429  SCIP_ROW* row, /**< LP row */
3430  SCIP_Real incval /**< value to add to the coefficient */
3431  )
3432 {
3433  int pos;
3434 
3435  assert(col != NULL);
3436  assert(lp != NULL);
3437  assert(!lp->diving);
3438  assert(row != NULL);
3439 
3440  if( SCIPsetIsZero(set, incval) )
3441  return SCIP_OKAY;
3442 
3443  /* search the position of the row in the column's row vector */
3444  pos = colSearchCoef(col, row);
3445 
3446  /* check, if row already exists in the column's row vector */
3447  if( pos == -1 )
3448  {
3449  /* add previously not existing coefficient */
3450  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3451  }
3452  else
3453  {
3454  /* modify already existing coefficient */
3455  assert(0 <= pos && pos < col->len);
3456  assert(col->rows[pos] == row);
3457 
3458  /* if row knows of the column, change the corresponding coefficient in the row */
3459  if( col->linkpos[pos] >= 0 )
3460  {
3461  assert(row->cols[col->linkpos[pos]] == col);
3462  assert(row->cols_index[col->linkpos[pos]] == col->index);
3463  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3464  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3465  }
3466 
3467  /* change the coefficient in the column */
3468  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3469  }
3470 
3471  checkLinks(lp);
3472 
3473  return SCIP_OKAY;
3474 }
3475 
3476 /** insert column in the chgcols list (if not already there) */
3477 static
3479  SCIP_COL* col, /**< LP column to change */
3480  SCIP_SET* set, /**< global SCIP settings */
3481  SCIP_LP* lp /**< current LP data */
3482  )
3483 {
3484  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3485  {
3486  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3487  lp->chgcols[lp->nchgcols] = col;
3488  lp->nchgcols++;
3489  }
3490 
3491  /* mark the current LP unflushed */
3492  lp->flushed = FALSE;
3493 
3494  return SCIP_OKAY;
3495 }
3496 
3497 /** Is the new value reliable or may we have cancellation?
3498  *
3499  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3500  * cancellations which can occur during increasing the oldvalue to the newvalue
3501  */
3502 static
3504  SCIP_SET* set, /**< global SCIP settings */
3505  SCIP_Real newvalue, /**< new value */
3506  SCIP_Real oldvalue /**< old reliable value */
3507  )
3508 {
3509  SCIP_Real quotient;
3510 
3511  assert(set != NULL);
3512  assert(oldvalue < SCIP_INVALID);
3513 
3514  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3515 
3516  return SCIPsetIsZero(set, quotient);
3517 }
3518 
3519 /** update norms of objective function vector */
3520 static
3522  SCIP_LP* lp, /**< current LP data */
3523  SCIP_SET* set, /**< global SCIP settings */
3524  SCIP_Real oldobj, /**< old objective value of variable */
3525  SCIP_Real newobj /**< new objective value of variable */
3526  )
3527 {
3528  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3529  {
3530  if( !lp->objsqrnormunreliable )
3531  {
3532  SCIP_Real oldvalue;
3533 
3534  oldvalue = lp->objsqrnorm;
3535  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3536 
3537  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3538  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3539  lp->objsqrnormunreliable = TRUE;
3540  else
3541  {
3542  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3543 
3544  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3545  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3546 
3547  assert(lp->objsqrnorm >= 0.0);
3548  }
3549  }
3550 
3551  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3552  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3553  }
3554 }
3555 
3556 /** changes objective value of column */
3558  SCIP_COL* col, /**< LP column to change */
3559  SCIP_SET* set, /**< global SCIP settings */
3560  SCIP_LP* lp, /**< current LP data */
3561  SCIP_Real newobj /**< new objective value */
3562  )
3563 {
3564  assert(col != NULL);
3565  assert(col->var != NULL);
3566  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3567  assert(SCIPvarGetCol(col->var) == col);
3568  assert(lp != NULL);
3569 
3570  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3571 
3572  /* only add actual changes */
3573  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3574  {
3575  /* only variables with a real position in the LPI can be inserted */
3576  if( col->lpipos >= 0 )
3577  {
3578  /* insert column in the chgcols list (if not already there) */
3579  SCIP_CALL( insertColChgcols(col, set, lp) );
3580 
3581  /* mark objective value change in the column */
3582  col->objchanged = TRUE;
3583 
3584  assert(lp->nchgcols > 0);
3585  }
3586  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3587  * LP and the LP has to be flushed
3588  */
3589  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3590  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3591  {
3592  /* mark the LP unflushed */
3593  lp->flushed = FALSE;
3594  }
3595  }
3596 
3597  /* store new objective function value */
3598  col->obj = newobj;
3599 
3600  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3601  if( !lp->divingobjchg )
3602  {
3603  SCIP_Real oldobj = col->unchangedobj;
3604 
3605  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3606  col->unchangedobj = newobj;
3607 
3608  /* update the objective function vector norms */
3609  lpUpdateObjNorms(lp, set, oldobj, newobj);
3610  }
3611 
3612  return SCIP_OKAY;
3613 }
3614 
3615 /** changes lower bound of column */
3617  SCIP_COL* col, /**< LP column to change */
3618  SCIP_SET* set, /**< global SCIP settings */
3619  SCIP_LP* lp, /**< current LP data */
3620  SCIP_Real newlb /**< new lower bound value */
3621  )
3622 {
3623  assert(col != NULL);
3624  assert(col->var != NULL);
3625  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3626  assert(SCIPvarGetCol(col->var) == col);
3627  assert(lp != NULL);
3628 
3629  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3630 
3631  /* only add actual changes */
3632  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3633  {
3634  /* only variables with a real position in the LPI can be inserted */
3635  if( col->lpipos >= 0 )
3636  {
3637  /* insert column in the chgcols list (if not already there) */
3638  SCIP_CALL( insertColChgcols(col, set, lp) );
3639 
3640  /* mark bound change in the column */
3641  col->lbchanged = TRUE;
3642 
3643  assert(lp->nchgcols > 0);
3644  }
3645  /* 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
3646  * flushed
3647  */
3648  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3649  {
3650  /* mark the LP unflushed */
3651  lp->flushed = FALSE;
3652  }
3653  }
3654 
3655  col->lb = newlb;
3656 
3657  return SCIP_OKAY;
3658 }
3659 
3660 /** changes upper bound of column */
3662  SCIP_COL* col, /**< LP column to change */
3663  SCIP_SET* set, /**< global SCIP settings */
3664  SCIP_LP* lp, /**< current LP data */
3665  SCIP_Real newub /**< new upper bound value */
3666  )
3667 {
3668  assert(col != NULL);
3669  assert(col->var != NULL);
3670  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3671  assert(SCIPvarGetCol(col->var) == col);
3672  assert(lp != NULL);
3673 
3674  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3675 
3676  /* only add actual changes */
3677  if( !SCIPsetIsEQ(set, col->ub, newub) )
3678  {
3679  /* only variables with a real position in the LPI can be inserted */
3680  if( col->lpipos >= 0 )
3681  {
3682  /* insert column in the chgcols list (if not already there) */
3683  SCIP_CALL( insertColChgcols(col, set, lp) );
3684 
3685  /* mark bound change in the column */
3686  col->ubchanged = TRUE;
3687 
3688  assert(lp->nchgcols > 0);
3689  }
3690  /* 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
3691  * flushed
3692  */
3693  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3694  {
3695  /* mark the LP unflushed */
3696  lp->flushed = FALSE;
3697  }
3698  }
3699 
3700  col->ub = newub;
3701 
3702  return SCIP_OKAY;
3703 }
3704 
3705 /** calculates the reduced costs of a column using the given dual solution vector */
3707  SCIP_COL* col, /**< LP column */
3708  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3709  )
3710 {
3711  SCIP_ROW* row;
3712  SCIP_Real redcost;
3713  int i;
3714 
3715  assert(col != NULL);
3716  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3717  assert(SCIPvarGetCol(col->var) == col);
3718  assert(dualsol != NULL);
3719 
3720  redcost = col->obj;
3721  for( i = 0; i < col->nlprows; ++i )
3722  {
3723  row = col->rows[i];
3724  assert(row != NULL);
3725  assert(row->lppos >= 0);
3726  redcost -= col->vals[i] * dualsol[row->lppos];
3727  }
3728 
3729  if( col->nunlinked > 0 )
3730  {
3731  for( i = col->nlprows; i < col->len; ++i )
3732  {
3733  row = col->rows[i];
3734  assert(row != NULL);
3735  assert(row->lppos == -1 || col->linkpos[i] == -1);
3736  if( row->lppos >= 0 )
3737  redcost -= col->vals[i] * dualsol[row->lppos];
3738  }
3739  }
3740 #ifndef NDEBUG
3741  else
3742  {
3743  for( i = col->nlprows; i < col->len; ++i )
3744  {
3745  row = col->rows[i];
3746  assert(row != NULL);
3747  assert(row->lppos == -1);
3748  assert(col->linkpos[i] >= 0);
3749  }
3750  }
3751 #endif
3752 
3753  return redcost;
3754 }
3755 
3756 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3757 static
3759  SCIP_COL* col /**< LP column */
3760  )
3761 {
3762  SCIP_ROW* row;
3763  SCIP_Real redcost;
3764  int i;
3765 
3766  assert(col != NULL);
3767  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3768  assert(SCIPvarGetCol(col->var) == col);
3769 
3770  redcost = col->obj;
3771  for( i = 0; i < col->nlprows; ++i )
3772  {
3773  row = col->rows[i];
3774  assert(row != NULL);
3775  assert(row->dualsol < SCIP_INVALID);
3776  assert(row->lppos >= 0);
3777  assert(col->linkpos[i] >= 0);
3778  redcost -= col->vals[i] * row->dualsol;
3779  }
3780 
3781  if( col->nunlinked > 0 )
3782  {
3783  for( i = col->nlprows; i < col->len; ++i )
3784  {
3785  row = col->rows[i];
3786  assert(row != NULL);
3787  assert(row->lppos >= 0 || row->dualsol == 0.0);
3788  assert(row->lppos == -1 || col->linkpos[i] == -1);
3789  if( row->lppos >= 0 )
3790  redcost -= col->vals[i] * row->dualsol;
3791  }
3792  }
3793 #ifndef NDEBUG
3794  else
3795  {
3796  for( i = col->nlprows; i < col->len; ++i )
3797  {
3798  row = col->rows[i];
3799  assert(row != NULL);
3800  assert(row->dualsol == 0.0);
3801  assert(row->lppos == -1);
3802  assert(col->linkpos[i] >= 0);
3803  }
3804  }
3805 #endif
3806 
3807  return redcost;
3808 }
3809 
3810 /** gets the reduced costs of a column in last LP or after recalculation */
3812  SCIP_COL* col, /**< LP column */
3813  SCIP_STAT* stat, /**< problem statistics */
3814  SCIP_LP* lp /**< current LP data */
3815  )
3816 {
3817  assert(col != NULL);
3818  assert(stat != NULL);
3819  assert(lp != NULL);
3820  assert(col->validredcostlp <= stat->lpcount);
3821  assert(lp->validsollp == stat->lpcount);
3822 
3823  if( col->validredcostlp < stat->lpcount )
3824  {
3825  col->redcost = colCalcInternalRedcost(col);
3826  col->validredcostlp = stat->lpcount;
3827  }
3828  assert(col->validredcostlp == stat->lpcount);
3829  assert(col->redcost < SCIP_INVALID);
3830 
3831  return col->redcost;
3832 }
3833 
3834 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3836  SCIP_COL* col, /**< LP column */
3837  SCIP_SET* set, /**< global SCIP settings */
3838  SCIP_STAT* stat, /**< problem statistics */
3839  SCIP_LP* lp /**< current LP data */
3840  )
3841 {
3842  assert(col != NULL);
3843  assert(set != NULL);
3844  assert(stat != NULL);
3845  assert(lp != NULL);
3846  assert(lp->validsollp == stat->lpcount);
3847 
3848  /* A column's reduced cost is defined as
3849  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3850  * The activity is equal to the activity of the corresponding row in the dual LP.
3851  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3852  * The sides of the dual row depend on the bounds of the column:
3853  * - lb == ub : dual row is a free row with infinite sides
3854  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3855  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3856  * - lb < ub <= 0: obj <= activity => redcost <= 0
3857  */
3858  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3859  {
3860  /* dual row is free */
3861  return SCIPsetInfinity(set);
3862  }
3863  else
3864  {
3865  SCIP_Real redcost;
3866 
3867  /* calculate reduced costs */
3868  redcost = SCIPcolGetRedcost(col, stat, lp);
3869 
3870  if( !SCIPsetIsNegative(set, col->lb) )
3871  {
3872  /* dual row is activity <= obj <=> redcost >= 0 */
3873  return redcost;
3874  }
3875  else if( SCIPsetIsPositive(set, col->ub) )
3876  {
3877  /* dual row is activity == obj <=> redcost == 0 */
3878  return -REALABS(redcost);
3879  }
3880  else
3881  {
3882  /* dual row is activity >= obj <=> redcost <= 0 */
3883  return -redcost;
3884  }
3885  }
3886 }
3887 
3888 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
3890  SCIP_COL* col, /**< LP column */
3891  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
3892  )
3893 {
3894  SCIP_ROW* row;
3895  SCIP_Real farkas;
3896  int i;
3897 
3898  assert(col != NULL);
3899  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3900  assert(SCIPvarGetCol(col->var) == col);
3901  assert(dualfarkas != NULL);
3902 
3903  farkas = 0.0;
3904  for( i = 0; i < col->nlprows; ++i )
3905  {
3906  row = col->rows[i];
3907  assert(row != NULL);
3908  assert(row->lppos >= 0);
3909  farkas += col->vals[i] * dualfarkas[row->lppos];
3910  }
3911 
3912  if( col->nunlinked > 0 )
3913  {
3914  for( i = col->nlprows; i < col->len; ++i )
3915  {
3916  row = col->rows[i];
3917  assert(row != NULL);
3918  assert(row->lppos == -1 || col->linkpos[i] == -1);
3919  if( row->lppos >= 0 )
3920  farkas += col->vals[i] * dualfarkas[row->lppos];
3921  }
3922  }
3923 #ifndef NDEBUG
3924  else
3925  {
3926  for( i = col->nlprows; i < col->len; ++i )
3927  {
3928  row = col->rows[i];
3929  assert(row != NULL);
3930  assert(row->lppos == -1);
3931  assert(col->linkpos[i] >= 0);
3932  }
3933  }
3934 #endif
3935 
3936  return farkas;
3937 }
3938 
3939 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
3940 static
3942  SCIP_COL* col /**< LP column */
3943  )
3944 {
3945  SCIP_ROW* row;
3946  SCIP_Real farkas;
3947  int i;
3948 
3949  assert(col != NULL);
3950  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3951  assert(SCIPvarGetCol(col->var) == col);
3952 
3953  farkas = 0.0;
3954  for( i = 0; i < col->nlprows; ++i )
3955  {
3956  row = col->rows[i];
3957  assert(row != NULL);
3958  assert(row->dualfarkas < SCIP_INVALID);
3959  assert(row->lppos >= 0);
3960  assert(col->linkpos[i] >= 0);
3961  farkas += col->vals[i] * row->dualfarkas;
3962  }
3963 
3964  if( col->nunlinked > 0 )
3965  {
3966  for( i = col->nlprows; i < col->len; ++i )
3967  {
3968  row = col->rows[i];
3969  assert(row != NULL);
3970  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
3971  assert(row->lppos == -1 || col->linkpos[i] == -1);
3972  if( row->lppos >= 0 )
3973  farkas += col->vals[i] * row->dualfarkas;
3974  }
3975  }
3976 #ifndef NDEBUG
3977  else
3978  {
3979  for( i = col->nlprows; i < col->len; ++i )
3980  {
3981  row = col->rows[i];
3982  assert(row != NULL);
3983  assert(row->dualfarkas == 0.0);
3984  assert(row->lppos == -1);
3985  assert(col->linkpos[i] >= 0);
3986  }
3987  }
3988 #endif
3989 
3990  return farkas;
3991 }
3992 
3993 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
3995  SCIP_COL* col, /**< LP column */
3996  SCIP_STAT* stat, /**< problem statistics */
3997  SCIP_LP* lp /**< current LP data */
3998  )
3999 {
4000  assert(col != NULL);
4001  assert(stat != NULL);
4002  assert(lp != NULL);
4003  assert(col->validfarkaslp <= stat->lpcount);
4004  assert(lp->validfarkaslp == stat->lpcount);
4005 
4006  if( col->validfarkaslp < stat->lpcount )
4007  {
4009  col->validfarkaslp = stat->lpcount;
4010  }
4011  assert(col->validfarkaslp == stat->lpcount);
4012  assert(col->farkascoef < SCIP_INVALID);
4013 
4014  return col->farkascoef;
4015 }
4016 
4017 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4018  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4019  */
4021  SCIP_COL* col, /**< LP column */
4022  SCIP_STAT* stat, /**< problem statistics */
4023  SCIP_LP* lp /**< current LP data */
4024  )
4025 {
4026  SCIP_Real farkascoef;
4027 
4028  assert(col != NULL);
4029 
4030  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4031 
4032  if( farkascoef > 0.0 )
4033  return col->ub * farkascoef;
4034  else
4035  return col->lb * farkascoef;
4036 }
4037 
4038 /** start strong branching - call before any strong branching */
4040  SCIP_LP* lp /**< LP data */
4041  )
4042 {
4043  assert(lp != NULL);
4044  assert(!lp->strongbranching);
4045 
4046  lp->strongbranching = TRUE;
4047  SCIPdebugMessage("starting strong branching ...\n");
4049 
4050  return SCIP_OKAY;
4051 }
4052 
4053 /** end strong branching - call after any strong branching */
4055  SCIP_LP* lp /**< LP data */
4056  )
4057 {
4058  assert(lp != NULL);
4059  assert(lp->strongbranching);
4060 
4061  lp->strongbranching = FALSE;
4062  SCIPdebugMessage("ending strong branching ...\n");
4064 
4065  return SCIP_OKAY;
4066 }
4067 
4068 /** sets strong branching information for a column variable */
4070  SCIP_COL* col, /**< LP column */
4071  SCIP_SET* set, /**< global SCIP settings */
4072  SCIP_STAT* stat, /**< dynamic problem statistics */
4073  SCIP_LP* lp, /**< LP data */
4074  SCIP_Real lpobjval, /**< objective value of the current LP */
4075  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4076  SCIP_Real sbdown, /**< dual bound after branching column down */
4077  SCIP_Real sbup, /**< dual bound after branching column up */
4078  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4079  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4080  SCIP_Longint iter, /**< total number of strong branching iterations */
4081  int itlim /**< iteration limit applied to the strong branching call */
4082  )
4083 {
4084  assert(col != NULL);
4085  assert(col->var != NULL);
4086  assert(SCIPcolIsIntegral(col));
4087  assert(SCIPvarIsIntegral(col->var));
4088  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4089  assert(SCIPvarGetCol(col->var) == col);
4090  assert(col->lpipos >= 0);
4091  assert(col->lppos >= 0);
4092  assert(set != NULL);
4093  assert(stat != NULL);
4094  assert(lp != NULL);
4095  assert(lp->strongbranchprobing);
4096  assert(col->lppos < lp->ncols);
4097  assert(lp->cols[col->lppos] == col);
4098  assert(itlim >= 1);
4099 
4100  col->sblpobjval = lpobjval;
4101  col->sbsolval = primsol;
4102  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4103  col->sbnode = stat->nnodes;
4104 
4105  col->sbitlim = itlim;
4106  col->nsbcalls++;
4107 
4108  col->sbdown = MIN(sbdown, lp->cutoffbound);
4109  col->sbup = MIN(sbup, lp->cutoffbound);
4110  col->sbdownvalid = sbdownvalid;
4111  col->sbupvalid = sbupvalid;
4112 
4113  SCIPstatIncrement(stat, set, nstrongbranchs);
4114  SCIPstatAdd(stat, set, nsblpiterations, iter);
4115  if( stat->nnodes == 1 )
4116  {
4117  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4118  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4119  }
4120 }
4121 
4122 /** invalidates strong branching information for a column variable */
4124  SCIP_COL* col, /**< LP column */
4125  SCIP_SET* set, /**< global SCIP settings */
4126  SCIP_STAT* stat, /**< dynamic problem statistics */
4127  SCIP_LP* lp /**< LP data */
4128  )
4129 {
4130  assert(col != NULL);
4131  assert(col->var != NULL);
4132  assert(SCIPcolIsIntegral(col));
4133  assert(SCIPvarIsIntegral(col->var));
4134  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4135  assert(SCIPvarGetCol(col->var) == col);
4136  assert(col->lpipos >= 0);
4137  assert(col->lppos >= 0);
4138  assert(set != NULL);
4139  assert(stat != NULL);
4140  assert(lp != NULL);
4141  assert(lp->strongbranchprobing);
4142  assert(col->lppos < lp->ncols);
4143  assert(lp->cols[col->lppos] == col);
4144 
4145  col->sbdown = SCIP_INVALID;
4146  col->sbup = SCIP_INVALID;
4147  col->sbdownvalid = FALSE;
4148  col->sbupvalid = FALSE;
4149  col->validsblp = -1;
4150  col->sbsolval = SCIP_INVALID;
4151  col->sblpobjval = SCIP_INVALID;
4152  col->sbnode = -1;
4153  col->sbitlim = -1;
4154 }
4155 
4156 
4157 /** gets strong branching information on a column variable */
4159  SCIP_COL* col, /**< LP column */
4160  SCIP_Bool integral, /**< should integral strong branching be performed? */
4161  SCIP_SET* set, /**< global SCIP settings */
4162  SCIP_STAT* stat, /**< dynamic problem statistics */
4163  SCIP_PROB* prob, /**< problem data */
4164  SCIP_LP* lp, /**< LP data */
4165  int itlim, /**< iteration limit for strong branchings */
4166  SCIP_Real* down, /**< stores dual bound after branching column down */
4167  SCIP_Real* up, /**< stores dual bound after branching column up */
4168  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4169  * otherwise, it can only be used as an estimate value */
4170  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4171  * otherwise, it can only be used as an estimate value */
4172  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4173  )
4174 {
4175  assert(col != NULL);
4176  assert(col->var != NULL);
4177  assert(SCIPcolIsIntegral(col));
4178  assert(SCIPvarIsIntegral(col->var));
4179  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4180  assert(SCIPvarGetCol(col->var) == col);
4181  assert(col->primsol < SCIP_INVALID);
4182  assert(col->lpipos >= 0);
4183  assert(col->lppos >= 0);
4184  assert(set != NULL);
4185  assert(stat != NULL);
4186  assert(lp != NULL);
4187  assert(lp->flushed);
4188  assert(lp->solved);
4189  assert(lp->strongbranching);
4190  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4191  assert(lp->validsollp == stat->lpcount);
4192  assert(col->lppos < lp->ncols);
4193  assert(lp->cols[col->lppos] == col);
4194  assert(itlim >= 1);
4195  /* assert(down != NULL);
4196  * assert(up != NULL); temporary hack for cloud branching
4197  */
4198  assert(lperror != NULL);
4199 
4200  *lperror = FALSE;
4201 
4202  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4203  {
4204  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4205  col->sbsolval = col->primsol;
4206  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4207  col->sbnode = stat->nnodes;
4208  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4209 
4210  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4211  if( lp->looseobjvalinf > 0 )
4212  {
4213  col->sbdown = -SCIPsetInfinity(set);
4214  col->sbup = -SCIPsetInfinity(set);
4215  col->sbdownvalid = FALSE;
4216  col->sbupvalid = FALSE;
4217  }
4218  else
4219  {
4220  SCIP_RETCODE retcode;
4221  SCIP_Real sbdown;
4222  SCIP_Real sbup;
4223  SCIP_Bool sbdownvalid;
4224  SCIP_Bool sbupvalid;
4225  int iter;
4226 
4227  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4228  SCIPvarGetName(col->var), col->primsol, itlim);
4229 
4230  /* start timing */
4231  SCIPclockStart(stat->strongbranchtime, set);
4232 
4233  /* call LPI strong branching */
4234  col->sbitlim = itlim;
4235  col->nsbcalls++;
4236 
4237  sbdown = lp->lpobjval;
4238  sbup = lp->lpobjval;
4239 
4240  if( integral )
4241  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4242  else
4243  {
4244  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4245  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4246  }
4247 
4248 
4249  /* check return code for errors */
4250  if( retcode == SCIP_LPERROR )
4251  {
4252  *lperror = TRUE;
4253  col->sbdown = SCIP_INVALID;
4254  col->sbup = SCIP_INVALID;
4255  col->sbdownvalid = FALSE;
4256  col->sbupvalid = FALSE;
4257  col->validsblp = -1;
4258  col->sbsolval = SCIP_INVALID;
4259  col->sblpobjval = SCIP_INVALID;
4260  col->sbnode = -1;
4261  }
4262  else
4263  {
4264  SCIP_Real looseobjval;
4265 
4266  *lperror = FALSE;
4267  SCIP_CALL( retcode );
4268 
4269  looseobjval = getFiniteLooseObjval(lp, set, prob);
4270  col->sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4271  col->sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4272 
4273  col->sbdownvalid = sbdownvalid;
4274  col->sbupvalid = sbupvalid;
4275 
4276  /* update strong branching statistics */
4277  if( iter == -1 )
4278  {
4279  /* calculate average iteration number */
4280  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4281  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4282  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4283  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4284  : 0;
4285  if( iter/2 >= itlim )
4286  iter = 2*itlim;
4287  }
4288  SCIPstatIncrement(stat, set, nstrongbranchs);
4289  SCIPstatAdd(stat, set, nsblpiterations, iter);
4290  if( stat->nnodes == 1 )
4291  {
4292  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4293  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4294  }
4295  }
4296 
4297  /* stop timing */
4298  SCIPclockStop(stat->strongbranchtime, set);
4299  }
4300  }
4301  assert(*lperror || col->sbdown < SCIP_INVALID);
4302  assert(*lperror || col->sbup < SCIP_INVALID);
4303 
4304  if( down != NULL)
4305  *down = col->sbdown;
4306  if( up != NULL )
4307  *up = col->sbup;
4308  if( downvalid != NULL )
4309  *downvalid = col->sbdownvalid;
4310  if( upvalid != NULL )
4311  *upvalid = col->sbupvalid;
4312 
4313  return SCIP_OKAY;
4314 }
4315 
4316 /** gets strong branching information on column variables */
4318  SCIP_COL** cols, /**< LP columns */
4319  int ncols, /**< number of columns */
4320  SCIP_Bool integral, /**< should integral strong branching be performed? */
4321  SCIP_SET* set, /**< global SCIP settings */
4322  SCIP_STAT* stat, /**< dynamic problem statistics */
4323  SCIP_PROB* prob, /**< problem data */
4324  SCIP_LP* lp, /**< LP data */
4325  int itlim, /**< iteration limit for strong branchings */
4326  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4327  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4328  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4329  * otherwise, they can only be used as an estimate value */
4330  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4331  * otherwise, they can only be used as an estimate value */
4332  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4333  )
4334 {
4335  SCIP_RETCODE retcode;
4336  SCIP_Real* sbdown;
4337  SCIP_Real* sbup;
4338  SCIP_Bool* sbdownvalid;
4339  SCIP_Bool* sbupvalid;
4340  SCIP_Real* primsols;
4341  SCIP_COL** subcols;
4342  int* lpipos;
4343  int* subidx;
4344  int nsubcols;
4345  int iter;
4346  int j;
4347 
4348  assert(cols != NULL);
4349  assert(set != NULL);
4350  assert(stat != NULL);
4351  assert(lp != NULL);
4352  assert(lp->flushed);
4353  assert(lp->solved);
4354  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4355  assert(lp->validsollp == stat->lpcount);
4356  assert(itlim >= 1);
4357  assert(down != NULL);
4358  assert(up != NULL);
4359  assert(lperror != NULL);
4360 
4361  *lperror = FALSE;
4362 
4363  if ( ncols <= 0 )
4364  return SCIP_OKAY;
4365 
4366  /* start timing */
4367  SCIPclockStart(stat->strongbranchtime, set);
4368 
4369  /* initialize storage */
4370  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4371  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4372  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4373  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4374  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4375  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4376  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4377  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4378 
4379  nsubcols = 0;
4380  for( j = 0; j < ncols; ++j )
4381  {
4382  SCIP_COL* col;
4383  col = cols[j];
4384 
4385  assert(col->lppos < lp->ncols);
4386  assert(lp->cols[col->lppos] == col);
4387  assert(SCIPcolIsIntegral(col));
4388  assert(SCIPvarIsIntegral(col->var));
4389  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4390  assert(SCIPvarGetCol(col->var) == col);
4391  assert(col->primsol < SCIP_INVALID);
4392  assert(col->lpipos >= 0);
4393  assert(col->lppos >= 0);
4394 
4395  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4396  {
4397  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4398  col->sbsolval = col->primsol;
4399  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4400  col->sbnode = stat->nnodes;
4401  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4402 
4403  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4404  if( lp->looseobjvalinf > 0 )
4405  {
4406  /* directly set up column and result vectors*/
4407  col->sbdown = -SCIPsetInfinity(set);
4408  col->sbup = -SCIPsetInfinity(set);
4409  col->sbdownvalid = FALSE;
4410  col->sbupvalid = FALSE;
4411  down[j] = col->sbdown;
4412  up[j] = col->sbup;
4413  if( downvalid != NULL )
4414  downvalid[j] = col->sbdownvalid;
4415  if( upvalid != NULL )
4416  upvalid[j] = col->sbupvalid;
4417  }
4418  else
4419  {
4420  col->sbitlim = itlim;
4421  col->nsbcalls++;
4422 
4423  lpipos[nsubcols] = col->lpipos;
4424  primsols[nsubcols] = col->primsol;
4425  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4426  subidx[nsubcols] = j;
4427  subcols[nsubcols++] = col;
4428  }
4429  }
4430  else
4431  {
4432  /* directly set up resulting values (use stored values) */
4433  down[j] = col->sbdown;
4434  up[j] = col->sbup;
4435  if( downvalid != NULL )
4436  downvalid[j] = col->sbdownvalid;
4437  if( upvalid != NULL )
4438  upvalid[j] = col->sbupvalid;
4439  }
4440  }
4441 
4442  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4443 
4444  /* call LPI strong branching */
4445  if ( integral )
4446  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4447  else
4448  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4449 
4450  /* check return code for errors */
4451  if( retcode == SCIP_LPERROR )
4452  {
4453  *lperror = TRUE;
4454 
4455  for( j = 0; j < nsubcols; ++j )
4456  {
4457  SCIP_COL* col;
4458  int idx;
4459 
4460  col = subcols[j];
4461  idx = subidx[j];
4462 
4463  col->sbdown = SCIP_INVALID;
4464  col->sbup = SCIP_INVALID;
4465  col->sbdownvalid = FALSE;
4466  col->sbupvalid = FALSE;
4467  col->validsblp = -1;
4468  col->sbsolval = SCIP_INVALID;
4469  col->sblpobjval = SCIP_INVALID;
4470  col->sbnode = -1;
4471 
4472  down[idx] = col->sbdown;
4473  up[idx] = col->sbup;
4474  if( downvalid != NULL )
4475  downvalid[idx] = col->sbdownvalid;
4476  if( upvalid != NULL )
4477  upvalid[idx] = col->sbupvalid;
4478  }
4479  }
4480  else
4481  {
4482  SCIP_Real looseobjval;
4483 
4484  *lperror = FALSE;
4485  SCIP_CALL( retcode );
4486 
4487  looseobjval = getFiniteLooseObjval(lp, set, prob);
4488 
4489  for( j = 0; j < nsubcols; ++j )
4490  {
4491  SCIP_COL* col;
4492  int idx;
4493 
4494  col = subcols[j];
4495  idx = subidx[j];
4496 
4497  assert( col->sbdown < SCIP_INVALID);
4498  assert( col->sbup < SCIP_INVALID);
4499 
4500  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4501  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4502  col->sbdownvalid = sbdownvalid[j];
4503  col->sbupvalid = sbupvalid[j];
4504 
4505  down[idx] = col->sbdown;
4506  up[idx] = col->sbup;
4507  if( downvalid != NULL )
4508  downvalid[idx] = col->sbdownvalid;
4509  if( upvalid != NULL )
4510  upvalid[idx] = col->sbupvalid;
4511  }
4512 
4513  /* update strong branching statistics */
4514  if( iter == -1 )
4515  {
4516  /* calculate average iteration number */
4517  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4518  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4519  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4520  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4521  : 0;
4522  if( iter/2 >= itlim )
4523  iter = 2*itlim;
4524  }
4525  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4526  SCIPstatAdd(stat, set, nsblpiterations, iter);
4527  if( stat->nnodes == 1 )
4528  {
4529  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4530  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4531  }
4532  }
4533 
4534  SCIPsetFreeBufferArray(set, &sbupvalid);
4535  SCIPsetFreeBufferArray(set, &sbdownvalid);
4536  SCIPsetFreeBufferArray(set, &sbup);
4537  SCIPsetFreeBufferArray(set, &sbdown);
4538  SCIPsetFreeBufferArray(set, &primsols);
4539  SCIPsetFreeBufferArray(set, &lpipos);
4540  SCIPsetFreeBufferArray(set, &subidx);
4541  SCIPsetFreeBufferArray(set, &subcols);
4542 
4543  /* stop timing */
4544  SCIPclockStop(stat->strongbranchtime, set);
4545 
4546  return SCIP_OKAY;
4547 }
4548 
4549 /** gets last strong branching information available for a column variable;
4550  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4551  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4552  */
4554  SCIP_COL* col, /**< LP column */
4555  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4556  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4557  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4558  * otherwise, it can only be used as an estimate value */
4559  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4560  * otherwise, it can only be used as an estimate value */
4561  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4562  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4563  )
4564 {
4565  assert(col != NULL);
4566 
4567  if( down != NULL )
4568  *down = col->sbdown;
4569  if( up != NULL )
4570  *up = col->sbup;
4571  if( downvalid != NULL )
4572  *downvalid = col->sbdownvalid;
4573  if( upvalid != NULL )
4574  *upvalid = col->sbupvalid;
4575  if( solval != NULL )
4576  *solval = col->sbsolval;
4577  if( lpobjval != NULL )
4578  *lpobjval = col->sblpobjval;
4579 }
4580 
4581 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4582  * the LP where the strong branching on this column was applied;
4583  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4584  */
4586  SCIP_COL* col, /**< LP column */
4587  SCIP_STAT* stat /**< dynamic problem statistics */
4588  )
4589 {
4590  assert(col != NULL);
4591  assert(stat != NULL);
4592 
4593  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->lpcount - stat->nsbdivinglps - col->validsblp);
4594 }
4595 
4596 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4598  SCIP_COL* col, /**< LP column */
4599  SCIP_STAT* stat /**< problem statistics */
4600  )
4601 {
4602  assert(col != NULL);
4603  assert(stat != NULL);
4604  assert(stat->nnodes > 0);
4605 
4606  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4607  col->obsoletenode = stat->nnodes;
4608 }
4609 
4610 
4611 /*
4612  * Row methods
4613  */
4614 
4615 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4616 static
4618  SCIP_ROW* row, /**< LP row */
4619  SCIP_SET* set /**< global SCIP settings */
4620  )
4621 {
4622  int i;
4623 
4624  assert(row != NULL);
4625  assert(set != NULL);
4626 
4627  row->sqrnorm = 0.0;
4628  row->sumnorm = 0.0;
4629  row->objprod = 0.0;
4630  row->maxval = 0.0;
4631  row->nummaxval = 1;
4632  row->minval = SCIPsetInfinity(set);
4633  row->numminval = 1;
4634  row->minidx = INT_MAX;
4635  row->maxidx = INT_MIN;
4636  row->validminmaxidx = TRUE;
4637  row->lpcolssorted = TRUE;
4638  row->nonlpcolssorted = TRUE;
4639 
4640  /* check, if row is sorted
4641  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4642  */
4643  for( i = 0; i < row->nlpcols; ++i )
4644  {
4645  assert(row->cols[i] != NULL);
4646  assert(!SCIPsetIsZero(set, row->vals[i]));
4647  assert(row->cols[i]->lppos >= 0);
4648  assert(row->linkpos[i] >= 0);
4649  assert(row->cols[i]->index == row->cols_index[i]);
4650 
4651  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4652  if( i > 0 )
4653  {
4654  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4655  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4656  }
4657  }
4658  for( i = row->nlpcols; i < row->len; ++i )
4659  {
4660  assert(row->cols[i] != NULL);
4661  assert(!SCIPsetIsZero(set, row->vals[i]));
4662  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4663  assert(row->cols[i]->index == row->cols_index[i]);
4664 
4665  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4666  if( i > row->nlpcols )
4667  {
4668  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4669  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4670  }
4671  }
4672 }
4673 
4674 /** calculates min/maxval and min/maxidx from scratch */
4675 static
4677  SCIP_ROW* row, /**< LP row */
4678  SCIP_SET* set /**< global SCIP settings */
4679  )
4680 {
4681  SCIP_COL* col;
4682  SCIP_Real absval;
4683  int i;
4684 
4685  assert(row != NULL);
4686  assert(set != NULL);
4687 
4688  row->maxval = 0.0;
4689  row->nummaxval = 1;
4690  row->minval = SCIPsetInfinity(set);
4691  row->numminval = 1;
4692  row->minidx = INT_MAX;
4693  row->maxidx = INT_MIN;
4694  row->validminmaxidx = TRUE;
4695 
4696  /* calculate maxval, minval, minidx, and maxidx */
4697  for( i = 0; i < row->len; ++i )
4698  {
4699  col = row->cols[i];
4700  assert(col != NULL);
4701  assert(!SCIPsetIsZero(set, row->vals[i]));
4702 
4703  absval = REALABS(row->vals[i]);
4704  assert(!SCIPsetIsZero(set, absval));
4705 
4706  /* update min/maxidx */
4707  row->minidx = MIN(row->minidx, col->index);
4708  row->maxidx = MAX(row->maxidx, col->index);
4709 
4710  /* update maximal and minimal non-zero value */
4711  if( row->nummaxval > 0 )
4712  {
4713  if( SCIPsetIsGT(set, absval, row->maxval) )
4714  {
4715  row->maxval = absval;
4716  row->nummaxval = 1;
4717  }
4718  else if( SCIPsetIsGE(set, absval, row->maxval) )
4719  row->nummaxval++;
4720  }
4721  if( row->numminval > 0 )
4722  {
4723  if( SCIPsetIsLT(set, absval, row->minval) )
4724  {
4725  row->minval = absval;
4726  row->numminval = 1;
4727  }
4728  else if( SCIPsetIsLE(set, absval, row->minval) )
4729  row->numminval++;
4730  }
4731  }
4732 }
4733 
4734 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4735 static
4737  SCIP_Real val, /**< value that should be scaled to an integral value */
4738  SCIP_Real scalar, /**< scalar that should be tried */
4739  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4740  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4741  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4742  )
4743 {
4744  SCIP_Real sval;
4745  SCIP_Real downval;
4746  SCIP_Real upval;
4747 
4748  assert(mindelta <= 0.0);
4749  assert(maxdelta >= 0.0);
4750 
4751  sval = val * scalar;
4752  downval = floor(sval);
4753  upval = ceil(sval);
4754 
4755  if( SCIPrelDiff(sval, downval) <= maxdelta )
4756  {
4757  if( intval != NULL )
4758  *intval = downval;
4759  return TRUE;
4760  }
4761  else if( SCIPrelDiff(sval, upval) >= mindelta )
4762  {
4763  if( intval != NULL )
4764  *intval = upval;
4765  return TRUE;
4766  }
4767 
4768  return FALSE;
4769 }
4770 
4771 /** scales row with given factor, and rounds coefficients to integers if close enough;
4772  * the constant is automatically moved to the sides;
4773  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4774  */
4775 static
4777  SCIP_ROW* row, /**< LP row */
4778  BMS_BLKMEM* blkmem, /**< block memory */
4779  SCIP_SET* set, /**< global SCIP settings */
4780  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4781  SCIP_STAT* stat, /**< problem statistics */
4782  SCIP_LP* lp, /**< current LP data */
4783  SCIP_Real scaleval, /**< value to scale row with */
4784  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4785  * if they are close to integral values? */
4786  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4787  * upto which the integral is used instead of the scaled real coefficient */
4788  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4789  * upto which the integral is used instead of the scaled real coefficient */
4790  )
4791 {
4792  SCIP_COL* col;
4793  SCIP_Real val;
4794  SCIP_Real newval;
4795  SCIP_Real intval;
4796  SCIP_Real mindelta;
4797  SCIP_Real maxdelta;
4798  SCIP_Real lb;
4799  SCIP_Real ub;
4800  SCIP_Bool mindeltainf;
4801  SCIP_Bool maxdeltainf;
4802  int oldlen;
4803  int c;
4804 
4805  assert(row != NULL);
4806  assert(row->len == 0 || row->cols != NULL);
4807  assert(row->len == 0 || row->vals != NULL);
4808  assert(SCIPsetIsPositive(set, scaleval));
4809  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4810  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4811 
4812  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4813 
4814  mindelta = 0.0;
4815  maxdelta = 0.0;
4816  mindeltainf = FALSE;
4817  maxdeltainf = FALSE;
4818  oldlen = row->len;
4819 
4820  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4821  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4822  * this rounding can lead to
4823  */
4824  row->integral = TRUE;
4825 
4826  c = 0;
4827  while( c < row->len )
4828  {
4829  col = row->cols[c];
4830  val = row->vals[c];
4831  assert(!SCIPsetIsZero(set, val));
4832 
4833  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4834  if( row->local )
4835  {
4836  lb = col->lb;
4837  ub = col->ub;
4838  }
4839  else
4840  {
4841  lb = SCIPvarGetLbGlobal(col->var);
4842  ub = SCIPvarGetUbGlobal(col->var);
4843  }
4844 
4845  /* calculate scaled coefficient */
4846  newval = val * scaleval;
4847  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
4848  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
4849  {
4850  if( !SCIPsetIsEQ(set, intval, newval) )
4851  {
4852  if( intval < newval )
4853  {
4854  mindelta += (intval - newval)*ub;
4855  maxdelta += (intval - newval)*lb;
4856  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
4857  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
4858  }
4859  else
4860  {
4861  mindelta += (intval - newval)*lb;
4862  maxdelta += (intval - newval)*ub;
4863  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
4864  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
4865  }
4866  }
4867  newval = intval;
4868  }
4869 
4870  if( !SCIPsetIsEQ(set, val, newval) )
4871  {
4872  /* if column knows of the row, change the corresponding coefficient in the column */
4873  if( row->linkpos[c] >= 0 )
4874  {
4875  assert(col->rows[row->linkpos[c]] == row);
4876  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
4877  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
4878  }
4879 
4880  /* change the coefficient in the row, and update the norms and integrality status */
4881  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
4882 
4883  /* current coefficient has been deleted from the row because it was almost zero */
4884  if( oldlen != row->len )
4885  {
4886  assert(row->len == oldlen - 1);
4887  c--;
4888  oldlen = row->len;
4889  }
4890 
4891  }
4892  else
4893  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
4894 
4895  ++c;
4896  }
4897 
4898  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
4899  * to not destroy feasibility due to rounding
4900  */
4901  /**@todo ensure that returned cut does not have infinite lhs and rhs */
4902  if( !SCIPsetIsInfinity(set, -row->lhs) )
4903  {
4904  if( mindeltainf )
4905  newval = -SCIPsetInfinity(set);
4906  else
4907  {
4908  newval = (row->lhs - row->constant) * scaleval + mindelta;
4909  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4910  newval = SCIPsetSumCeil(set, newval);
4911  }
4912  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
4913  }
4914  if( !SCIPsetIsInfinity(set, row->rhs) )
4915  {
4916  if( maxdeltainf )
4917  newval = SCIPsetInfinity(set);
4918  else
4919  {
4920  newval = (row->rhs - row->constant) * scaleval + maxdelta;
4921  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4922  newval = SCIPsetSumFloor(set, newval);
4923  }
4924  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
4925  }
4926 
4927  /* clear the row constant */
4928  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
4929 
4930  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
4931  debugRowPrint(set, row);
4932 
4933 #ifdef SCIP_DEBUG
4934  /* check integrality status of row */
4935  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
4936  {}
4937  assert(row->integral == (c == row->len));
4938 #endif
4939 
4940  /* invalid the activity */
4941  row->validactivitylp = -1;
4942 
4943  return SCIP_OKAY;
4944 }
4945 
4946 /** creates and captures an LP row */
4948  SCIP_ROW** row, /**< pointer to LP row data */
4949  BMS_BLKMEM* blkmem, /**< block memory */
4950  SCIP_SET* set, /**< global SCIP settings */
4951  SCIP_STAT* stat, /**< problem statistics */
4952  SCIP_LP* lp, /**< current LP data */
4953  const char* name, /**< name of row */
4954  int len, /**< number of nonzeros in the row */
4955  SCIP_COL** cols, /**< array with columns of row entries */
4956  SCIP_Real* vals, /**< array with coefficients of row entries */
4957  SCIP_Real lhs, /**< left hand side of row */
4958  SCIP_Real rhs, /**< right hand side of row */
4959  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
4960  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
4961  SCIP_Bool local, /**< is row only valid locally? */
4962  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
4963  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
4964  )
4965 {
4966  assert(row != NULL);
4967  assert(blkmem != NULL);
4968  assert(stat != NULL);
4969  assert(len >= 0);
4970  assert(len == 0 || (cols != NULL && vals != NULL));
4971  /* note, that the assert tries to avoid numerical troubles in the LP solver.
4972  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
4973  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
4974  */
4975  assert(lhs <= rhs);
4976 
4977  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
4978 
4979  (*row)->integral = TRUE;
4980  if( len > 0 )
4981  {
4982  SCIP_VAR* var;
4983  int i;
4984 
4985  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
4986  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
4987  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
4988  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
4989 
4990  for( i = 0; i < len; ++i )
4991  {
4992  assert(cols[i] != NULL);
4993  assert(!SCIPsetIsZero(set, vals[i]));
4994 
4995  var = cols[i]->var;
4996  (*row)->cols_index[i] = cols[i]->index;
4997  (*row)->linkpos[i] = -1;
4998  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
4999  {
5000  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5001  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5002  }
5003  else
5004  {
5005  (*row)->integral = FALSE;
5006  }
5007  }
5008  }
5009  else
5010  {
5011  (*row)->cols = NULL;
5012  (*row)->cols_index = NULL;
5013  (*row)->vals = NULL;
5014  (*row)->linkpos = NULL;
5015  }
5016 
5017  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5018  (*row)->constant = 0.0;
5019  (*row)->lhs = lhs;
5020  (*row)->rhs = rhs;
5021  (*row)->flushedlhs = -SCIPsetInfinity(set);
5022  (*row)->flushedrhs = SCIPsetInfinity(set);
5023  (*row)->sqrnorm = 0.0;
5024  (*row)->sumnorm = 0.0;
5025  (*row)->objprod = 0.0;
5026  (*row)->maxval = 0.0;
5027  (*row)->minval = SCIPsetInfinity(set);
5028  (*row)->dualsol = 0.0;
5029  (*row)->activity = SCIP_INVALID;
5030  (*row)->dualfarkas = 0.0;
5031  (*row)->pseudoactivity = SCIP_INVALID;
5032  (*row)->minactivity = SCIP_INVALID;
5033  (*row)->maxactivity = SCIP_INVALID;
5034  (*row)->origin = origin;
5035  (*row)->eventfilter = NULL;
5036  (*row)->index = stat->nrowidx;
5037  SCIPstatIncrement(stat, set, nrowidx);
5038  (*row)->size = len;
5039  (*row)->len = len;
5040  (*row)->nlpcols = 0;
5041  (*row)->nunlinked = len;
5042  (*row)->nuses = 0;
5043  (*row)->lppos = -1;
5044  (*row)->lpipos = -1;
5045  (*row)->lpdepth = -1;
5046  (*row)->minidx = INT_MAX;
5047  (*row)->maxidx = INT_MIN;
5048  (*row)->nummaxval = 0;
5049  (*row)->numminval = 0;
5050  (*row)->validactivitylp = -1;
5051  (*row)->validpsactivitydomchg = -1;
5052  (*row)->validactivitybdsdomchg = -1;
5053  (*row)->nlpsaftercreation = 0L;
5054  (*row)->activeinlpcounter = 0L;
5055  (*row)->age = 0;
5056  (*row)->rank = 0;
5057  (*row)->obsoletenode = -1;
5058  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5059  (*row)->lpcolssorted = TRUE;
5060  (*row)->nonlpcolssorted = (len <= 1);
5061  (*row)->delaysort = FALSE;
5062  (*row)->validminmaxidx = FALSE;
5063  (*row)->lhschanged = FALSE;
5064  (*row)->rhschanged = FALSE;
5065  (*row)->coefchanged = FALSE;
5066  (*row)->local = local;
5067  (*row)->modifiable = modifiable;
5068  (*row)->nlocks = 0;
5069  (*row)->origintype = origintype; /*lint !e641*/
5070  (*row)->removable = removable;
5071  (*row)->inglobalcutpool = FALSE;
5072  (*row)->storedsolvals = NULL;
5073 
5074  /* calculate row norms and min/maxidx, and check if row is sorted */
5075  rowCalcNorms(*row, set);
5076 
5077  /* capture the row */
5078  SCIProwCapture(*row);
5079 
5080  /* create event filter */
5081  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5082 
5083  return SCIP_OKAY;
5084 } /*lint !e715*/
5085 
5086 /** frees an LP row */
5088  SCIP_ROW** row, /**< pointer to LP row */
5089  BMS_BLKMEM* blkmem, /**< block memory */
5090  SCIP_SET* set, /**< global SCIP settings */
5091  SCIP_LP* lp /**< current LP data */
5092  )
5093 {
5094  assert(blkmem != NULL);
5095  assert(row != NULL);
5096  assert(*row != NULL);
5097  assert((*row)->nuses == 0);
5098  assert((*row)->lppos == -1);
5099  assert((*row)->eventfilter != NULL);
5100 
5101  /* remove column indices from corresponding rows */
5102  SCIP_CALL( rowUnlink(*row, set, lp) );
5103 
5104  /* free event filter */
5105  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5106 
5107  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5108  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5109  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5110  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5111  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5112  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5113  BMSfreeBlockMemory(blkmem, row);
5114 
5115  return SCIP_OKAY;
5116 }
5117 
5118 /** output row to file stream */
5120  SCIP_ROW* row, /**< LP row */
5121  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5122  FILE* file /**< output file (or NULL for standard output) */
5123  )
5124 {
5125  int i;
5126 
5127  assert(row != NULL);
5128 
5129  /* print row name */
5130  if( row->name != NULL && row->name[0] != '\0' )
5131  {
5132  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5133  }
5134 
5135  /* print left hand side */
5136  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5137 
5138  /* print coefficients */
5139  if( row->len == 0 )
5140  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5141  for( i = 0; i < row->len; ++i )
5142  {
5143  assert(row->cols[i] != NULL);
5144  assert(row->cols[i]->var != NULL);
5145  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5146  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5147  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5148  }
5149 
5150  /* print constant */
5151  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5152  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5153 
5154  /* print right hand side */
5155  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5156 }
5157 
5158 /** increases usage counter of LP row */
5160  SCIP_ROW* row /**< LP row */
5161  )
5162 {
5163  assert(row != NULL);
5164  assert(row->nuses >= 0);
5165  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5166 
5167  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5168  row->nuses++;
5169 }
5170 
5171 /** decreases usage counter of LP row, and frees memory if necessary */
5173  SCIP_ROW** row, /**< pointer to LP row */
5174  BMS_BLKMEM* blkmem, /**< block memory */
5175  SCIP_SET* set, /**< global SCIP settings */
5176  SCIP_LP* lp /**< current LP data */
5177  )
5178 {
5179  assert(blkmem != NULL);
5180  assert(row != NULL);
5181  assert(*row != NULL);
5182  assert((*row)->nuses >= 1);
5183  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5184 
5185  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5186  (*row)->nuses--;
5187  if( (*row)->nuses == 0 )
5188  {
5189  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5190  }
5191 
5192  *row = NULL;
5193 
5194  return SCIP_OKAY;
5195 }
5196 
5197 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5199  SCIP_ROW* row /**< LP row */
5200  )
5201 {
5202  assert(row != NULL);
5203 
5204  /* check, if row is modifiable */
5205  if( !row->modifiable )
5206  {
5207  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5208  row->nlocks++;
5209  }
5210 }
5211 
5212 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5214  SCIP_ROW* row /**< LP row */
5215  )
5216 {
5217  assert(row != NULL);
5218 
5219  /* check, if row is modifiable */
5220  if( !row->modifiable )
5221  {
5222  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5223  assert(row->nlocks > 0);
5224  row->nlocks--;
5225  }
5226 }
5227 
5228 /** adds a previously non existing coefficient to an LP row */
5230  SCIP_ROW* row, /**< LP row */
5231  BMS_BLKMEM* blkmem, /**< block memory */
5232  SCIP_SET* set, /**< global SCIP settings */
5233  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5234  SCIP_LP* lp, /**< current LP data */
5235  SCIP_COL* col, /**< LP column */
5236  SCIP_Real val /**< value of coefficient */
5237  )
5238 {
5239  assert(lp != NULL);
5240  assert(!lp->diving || row->lppos == -1);
5241 
5242  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5243 
5244  checkLinks(lp);
5245 
5246  return SCIP_OKAY;
5247 }
5248 
5249 /** deletes coefficient from row */
5251  SCIP_ROW* row, /**< row to be changed */
5252  BMS_BLKMEM* blkmem, /**< block memory */
5253  SCIP_SET* set, /**< global SCIP settings */
5254  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5255  SCIP_LP* lp, /**< current LP data */
5256  SCIP_COL* col /**< coefficient to be deleted */
5257  )
5258 {
5259  int pos;
5260 
5261  assert(row != NULL);
5262  assert(!row->delaysort);
5263  assert(lp != NULL);
5264  assert(!lp->diving || row->lppos == -1);
5265  assert(col != NULL);
5266  assert(col->var != NULL);
5267 
5268  /* search the position of the column in the row's col vector */
5269  pos = rowSearchCoef(row, col);
5270  if( pos == -1 )
5271  {
5272  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5273  return SCIP_INVALIDDATA;
5274  }
5275  assert(0 <= pos && pos < row->len);
5276  assert(row->cols[pos] == col);
5277  assert(row->cols_index[pos] == col->index);
5278 
5279  /* if column knows of the row, remove the row from the column's row vector */
5280  if( row->linkpos[pos] >= 0 )
5281  {
5282  assert(col->rows[row->linkpos[pos]] == row);
5283  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5284  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5285  }
5286 
5287  /* delete the column from the row's col vector */
5288  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5289 
5290  checkLinks(lp);
5291 
5292  return SCIP_OKAY;
5293 }
5294 
5295 /** changes or adds a coefficient to an LP row */
5297  SCIP_ROW* row, /**< LP row */
5298  BMS_BLKMEM* blkmem, /**< block memory */
5299  SCIP_SET* set, /**< global SCIP settings */
5300  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5301  SCIP_LP* lp, /**< current LP data */
5302  SCIP_COL* col, /**< LP column */
5303  SCIP_Real val /**< value of coefficient */
5304  )
5305 {
5306  int pos;
5307 
5308  assert(row != NULL);
5309  assert(!row->delaysort);
5310  assert(lp != NULL);
5311  assert(!lp->diving || row->lppos == -1);
5312  assert(col != NULL);
5313 
5314  /* search the position of the column in the row's col vector */
5315  pos = rowSearchCoef(row, col);
5316 
5317  /* check, if column already exists in the row's col vector */
5318  if( pos == -1 )
5319  {
5320  /* add previously not existing coefficient */
5321  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5322  }
5323  else
5324  {
5325  /* modify already existing coefficient */
5326  assert(0 <= pos && pos < row->len);
5327  assert(row->cols[pos] == col);
5328  assert(row->cols_index[pos] == col->index);
5329 
5330  /* if column knows of the row, change the corresponding coefficient in the column */
5331  if( row->linkpos[pos] >= 0 )
5332  {
5333  assert(col->rows[row->linkpos[pos]] == row);
5334  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5335  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5336  }
5337 
5338  /* change the coefficient in the row */
5339  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5340  }
5341 
5342  checkLinks(lp);
5343 
5344  return SCIP_OKAY;
5345 }
5346 
5347 /** increases value of an existing or non-existing coefficient in an LP row */
5349  SCIP_ROW* row, /**< LP row */
5350  BMS_BLKMEM* blkmem, /**< block memory */
5351  SCIP_SET* set, /**< global SCIP settings */
5352  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5353  SCIP_LP* lp, /**< current LP data */
5354  SCIP_COL* col, /**< LP column */
5355  SCIP_Real incval /**< value to add to the coefficient */
5356  )
5357 {
5358  int pos;
5359 
5360  assert(row != NULL);
5361  assert(lp != NULL);
5362  assert(!lp->diving || row->lppos == -1);
5363  assert(col != NULL);
5364 
5365  if( SCIPsetIsZero(set, incval) )
5366  return SCIP_OKAY;
5367 
5368  /* search the position of the column in the row's col vector */
5369  pos = rowSearchCoef(row, col);
5370 
5371  /* check, if column already exists in the row's col vector */
5372  if( pos == -1 )
5373  {
5374  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5375  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5376  }
5377  else
5378  {
5379  /* modify already existing coefficient */
5380  assert(0 <= pos && pos < row->len);
5381  assert(row->cols[pos] == col);
5382  assert(row->cols_index[pos] == col->index);
5383 
5384  /* if column knows of the row, change the corresponding coefficient in the column */
5385  if( row->linkpos[pos] >= 0 )
5386  {
5387  assert(col->rows[row->linkpos[pos]] == row);
5388  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5389  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5390  }
5391 
5392  /* change the coefficient in the row */
5393  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5394  }
5395 
5396  checkLinks(lp);
5397 
5398  /* invalid the activity */
5399  row->validactivitylp = -1;
5400 
5401  return SCIP_OKAY;
5402 }
5403 
5404 /** changes constant value of a row */
5406  SCIP_ROW* row, /**< LP row */
5407  BMS_BLKMEM* blkmem, /**< block memory */
5408  SCIP_SET* set, /**< global SCIP settings */
5409  SCIP_STAT* stat, /**< problem statistics */
5410  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5411  SCIP_LP* lp, /**< current LP data */
5412  SCIP_Real constant /**< new constant value */
5413  )
5414 {
5415  assert(row != NULL);
5416  assert(row->lhs <= row->rhs);
5417  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5418  assert(stat != NULL);
5419  assert(lp != NULL);
5420  assert(!lp->diving || row->lppos == -1);
5421 
5422  if( !SCIPsetIsEQ(set, constant, row->constant) )
5423  {
5424  SCIP_Real oldconstant;
5425 
5426  if( row->validpsactivitydomchg == stat->domchgcount )
5427  {
5428  assert(row->pseudoactivity < SCIP_INVALID);
5429  row->pseudoactivity += constant - row->constant;
5430  }
5431  if( row->validactivitybdsdomchg == stat->domchgcount )
5432  {
5433  assert(row->minactivity < SCIP_INVALID);
5434  assert(row->maxactivity < SCIP_INVALID);
5435  row->minactivity += constant - row->constant;
5436  row->maxactivity += constant - row->constant;
5437  }
5438 
5439  if( !SCIPsetIsInfinity(set, -row->lhs) )
5440  {
5441  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5442  }
5443  if( !SCIPsetIsInfinity(set, row->rhs) )
5444  {
5445  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5446  }
5447 
5448  oldconstant = row->constant;
5449 
5450  row->constant = constant;
5451 
5452  /* issue row constant changed event */
5453  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5454  }
5455 
5456  return SCIP_OKAY;
5457 }
5458 
5459 /** add constant value to a row */
5461  SCIP_ROW* row, /**< LP row */
5462  BMS_BLKMEM* blkmem, /**< block memory */
5463  SCIP_SET* set, /**< global SCIP settings */
5464  SCIP_STAT* stat, /**< problem statistics */
5465  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5466  SCIP_LP* lp, /**< current LP data */
5467  SCIP_Real addval /**< constant value to add to the row */
5468  )
5469 {
5470  assert(row != NULL);
5471  assert(row->lhs <= row->rhs);
5472  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5473  assert(stat != NULL);
5474  assert(lp != NULL);
5475  assert(!lp->diving || row->lppos == -1);
5476 
5477  if( !SCIPsetIsZero(set, addval) )
5478  {
5479  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5480  }
5481 
5482  return SCIP_OKAY;
5483 }
5484 
5485 /** changes left hand side of LP row */
5487  SCIP_ROW* row, /**< LP row */
5488  BMS_BLKMEM* blkmem, /**< block memory */
5489  SCIP_SET* set, /**< global SCIP settings */
5490  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5491  SCIP_LP* lp, /**< current LP data */
5492  SCIP_Real lhs /**< new left hand side */
5493  )
5494 {
5495  assert(row != NULL);
5496  assert(lp != NULL);
5497 
5498  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5499  {
5500  SCIP_Real oldlhs;
5501 
5502  oldlhs = row->lhs;
5503 
5504  row->lhs = lhs;
5505  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5506 
5507  if( !lp->diving )
5508  {
5509  /* issue row side changed event */
5510  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5511  }
5512  }
5513 
5514  return SCIP_OKAY;
5515 }
5516 
5517 /** changes right hand side of LP row */
5519  SCIP_ROW* row, /**< LP row */
5520  BMS_BLKMEM* blkmem, /**< block memory */
5521  SCIP_SET* set, /**< global SCIP settings */
5522  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5523  SCIP_LP* lp, /**< current LP data */
5524  SCIP_Real rhs /**< new right hand side */
5525  )
5526 {
5527  assert(row != NULL);
5528  assert(lp != NULL);
5529 
5530  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5531  {
5532  SCIP_Real oldrhs;
5533 
5534  oldrhs = row->rhs;
5535 
5536  row->rhs = rhs;
5537  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5538 
5539  if( !lp->diving )
5540  {
5541  /* issue row side changed event */
5542  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5543  }
5544  }
5545 
5546  return SCIP_OKAY;
5547 }
5548 
5549 /** changes the local flag of LP row */
5551  SCIP_ROW* row, /**< LP row */
5552  SCIP_Bool local /**< new value for local flag */
5553  )
5554 {
5555  assert(row != NULL);
5556 
5557  row->local = local;
5558 
5559  return SCIP_OKAY;
5560 }
5561 
5562 /** additional scalars that are tried in integrality scaling */
5563 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5564 static const int nscalars = 9;
5565 
5566 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5568  SCIP_ROW* row, /**< LP row */
5569  SCIP_SET* set, /**< global SCIP settings */
5570  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5571  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5572  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5573  SCIP_Real maxscale, /**< maximal allowed scalar */
5574  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5575  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5576  SCIP_Bool* success /**< stores whether returned value is valid */
5577  )
5578 {
5579 #ifndef NDEBUG
5580  SCIP_COL* col;
5581 #endif
5582  SCIP_Longint gcd;
5583  SCIP_Longint scm;
5584  SCIP_Longint nominator;
5585  SCIP_Longint denominator;
5586  SCIP_Real val;
5587  SCIP_Real absval;
5588  SCIP_Real minval;
5589  SCIP_Real scaleval;
5590  SCIP_Real twomultval;
5591  SCIP_Bool scalable;
5592  SCIP_Bool twomult;
5593  SCIP_Bool rational;
5594  int c;
5595  int s;
5596 
5597  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5598  assert(row != NULL);
5599  assert(row->len == 0 || row->cols != NULL);
5600  assert(row->len == 0 || row->cols_index != NULL);
5601  assert(row->len == 0 || row->vals != NULL);
5602  assert(maxdnom >= 1);
5603  assert(mindelta < 0.0);
5604  assert(maxdelta > 0.0);
5605  assert(success != NULL);
5606 
5607  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5608  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5609 
5610  if( intscalar != NULL )
5611  *intscalar = SCIP_INVALID;
5612  *success = FALSE;
5613 
5614  /* get minimal absolute non-zero value */
5615  minval = SCIP_REAL_MAX;
5616  for( c = 0; c < row->len; ++c )
5617  {
5618 #ifndef NDEBUG
5619  col = row->cols[c];
5620  assert(col != NULL);
5621  assert(col->var != NULL);
5622  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5623  assert(SCIPvarGetCol(col->var) == col);
5624 #endif
5625  val = row->vals[c];
5626  assert(!SCIPsetIsZero(set, val));
5627 
5628  if( val < mindelta || val > maxdelta )
5629  {
5630  absval = REALABS(val);
5631  minval = MIN(minval, absval);
5632  }
5633  }
5634  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5635  {
5636  /* all coefficients are zero (inside tolerances) */
5637  if( intscalar != NULL )
5638  *intscalar = 1.0;
5639  *success = TRUE;
5640  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5641 
5642  return SCIP_OKAY;
5643  }
5644  assert(minval > MIN(-mindelta, maxdelta));
5645  assert(SCIPsetIsPositive(set, minval));
5646  assert(!SCIPsetIsInfinity(set, minval));
5647 
5648  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5649  * and a power of 2
5650  */
5651  scaleval = 1.0/minval;
5652  scalable = (scaleval <= maxscale);
5653  for( c = 0; c < row->len && scalable; ++c )
5654  {
5655  /* don't look at continuous variables, if we don't have to */
5656  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5657  continue;
5658 
5659  /* check, if the coefficient can be scaled with a simple scalar */
5660  val = row->vals[c];
5661  absval = REALABS(val);
5662  while( scaleval <= maxscale
5663  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5664  {
5665  for( s = 0; s < nscalars; ++s )
5666  {
5667  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5668  {
5669  scaleval *= scalars[s];
5670  break;
5671  }
5672  }
5673  if( s >= nscalars )
5674  scaleval *= 2.0;
5675  }
5676  scalable = (scaleval <= maxscale);
5677  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5678  }
5679  if( scalable )
5680  {
5681  /* make row coefficients integral by dividing them by the smallest coefficient
5682  * (and multiplying them with a power of 2)
5683  */
5684  assert(scaleval <= maxscale);
5685  if( intscalar != NULL )
5686  *intscalar = scaleval;
5687  *success = TRUE;
5688  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5689 
5690  return SCIP_OKAY;
5691  }
5692 
5693  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5694  twomultval = 1.0;
5695  twomult = (twomultval <= maxscale);
5696  for( c = 0; c < row->len && twomult; ++c )
5697  {
5698  /* don't look at continuous variables, if we don't have to */
5699  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5700  continue;
5701 
5702  /* check, if the coefficient can be scaled with a simple scalar */
5703  val = row->vals[c];
5704  absval = REALABS(val);
5705  while( twomultval <= maxscale
5706  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5707  {
5708  for( s = 0; s < nscalars; ++s )
5709  {
5710  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5711  {
5712  twomultval *= scalars[s];
5713  break;
5714  }
5715  }
5716  if( s >= nscalars )
5717  twomultval *= 2.0;
5718  }
5719  twomult = (twomultval <= maxscale);
5720  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5721  val, twomultval, val*twomultval, twomult);
5722  }
5723  if( twomult )
5724  {
5725  /* make row coefficients integral by multiplying them with a power of 2 */
5726  assert(twomultval <= maxscale);
5727  if( intscalar != NULL )
5728  *intscalar = twomultval;
5729  *success = TRUE;
5730  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5731 
5732  return SCIP_OKAY;
5733  }
5734 
5735  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5736  * and the smallest common multiple of the denominators
5737  */
5738  gcd = 1;
5739  scm = 1;
5740  rational = (maxdnom > 1);
5741 
5742  /* first coefficient (to initialize gcd) */
5743  for( c = 0; c < row->len && rational; ++c )
5744  {
5745  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5746  {
5747  val = row->vals[c];
5748  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5749  if( rational && nominator != 0 )
5750  {
5751  assert(denominator > 0);
5752  gcd = ABS(nominator);
5753  scm = denominator;
5754  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5755  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5756  val, nominator, denominator, gcd, scm, rational);
5757  break;
5758  }
5759  }
5760  }
5761 
5762  /* remaining coefficients */
5763  for( ++c; c < row->len && rational; ++c )
5764  {
5765  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5766  {
5767  val = row->vals[c];
5768  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5769  if( rational && nominator != 0 )
5770  {
5771  assert(denominator > 0);
5772  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5773  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5774  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5775  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5776  val, nominator, denominator, gcd, scm, rational);
5777  }
5778  }
5779  }
5780 
5781  if( rational )
5782  {
5783  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5784  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5785  if( intscalar != NULL )
5786  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5787  *success = TRUE;
5788  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5789  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5790  }
5791  else
5792  {
5793  assert(!(*success));
5794  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5795  }
5796 
5797  return SCIP_OKAY;
5798 }
5799 
5800 /** tries to scale row, s.t. all coefficients become integral */
5802  SCIP_ROW* row, /**< LP row */
5803  BMS_BLKMEM* blkmem, /**< block memory */
5804  SCIP_SET* set, /**< global SCIP settings */
5805  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5806  SCIP_STAT* stat, /**< problem statistics */
5807  SCIP_LP* lp, /**< current LP data */
5808  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5809  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5810  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5811  SCIP_Real maxscale, /**< maximal value to scale row with */
5812  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5813  SCIP_Bool* success /**< stores whether row could be made rational */
5814  )
5815 {
5816  SCIP_Real intscalar;
5817 
5818  assert(success != NULL);
5819 
5820  /* calculate scalar to make coefficients integral */
5821  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5822  &intscalar, success) );
5823 
5824  if( *success )
5825  {
5826  /* scale the row */
5827  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
5828  }
5829 
5830  return SCIP_OKAY;
5831 }
5832 
5833 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
5834  * higher ones
5835  */
5837  SCIP_ROW* row /**< row to be sorted */
5838  )
5839 {
5840  assert(row != NULL);
5841 
5842  /* sort LP columns */
5843  rowSortLP(row);
5844 
5845  /* sort non-LP columns */
5846  rowSortNonLP(row);
5847 
5848 #ifdef SCIP_MORE_DEBUG
5849  /* check the sorting */
5850  {
5851  int c;
5852  if( !row->delaysort )
5853  {
5854  for( c = 1; c < row->nlpcols; ++c )
5855  assert(row->cols[c]->index >= row->cols[c-1]->index);
5856  for( c = row->nlpcols + 1; c < row->len; ++c )
5857  assert(row->cols[c]->index >= row->cols[c-1]->index);
5858  }
5859  }
5860 #endif
5861 }
5862 
5863 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
5864  * zero entries from row
5865  * the row must not be linked to the columns; otherwise, we would need to update the columns as
5866  * well, which is too expensive
5867  */
5868 static
5870  SCIP_ROW* row, /**< row to be sorted */
5871  SCIP_SET* set /**< global SCIP settings */
5872  )
5873 {
5874  assert(row != NULL);
5875  assert(!row->delaysort);
5876  assert(row->nunlinked == row->len);
5877  assert(row->nlpcols == 0);
5878 
5879  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
5880 
5881  /* do nothing on empty rows; if row is sorted, nothing has to be done */
5882  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
5883  {
5884  SCIP_COL** cols;
5885  int* cols_index;
5886  SCIP_Real* vals;
5887  int s;
5888  int t;
5889 
5890  /* make sure, the row is sorted */
5891  SCIProwSort(row);
5892  assert(row->lpcolssorted);
5893  assert(row->nonlpcolssorted);
5894 
5895  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
5896  cols = row->cols;
5897  cols_index = row->cols_index;
5898  vals = row->vals;
5899  assert(cols != NULL);
5900  assert(cols_index != NULL);
5901  assert(vals != NULL);
5902 
5903  t = 0;
5904  row->integral = TRUE;
5905  assert(!SCIPsetIsZero(set, vals[0]));
5906  assert(row->linkpos[0] == -1);
5907 
5908  for( s = 1; s < row->len; ++s )
5909  {
5910  assert(!SCIPsetIsZero(set, vals[s]));
5911  assert(row->linkpos[s] == -1);
5912 
5913  if( cols[s] == cols[t] )
5914  {
5915  /* merge entries with equal column */
5916  vals[t] += vals[s];
5917  }
5918  else
5919  {
5920  /* go to the next entry, overwriting current entry if coefficient is zero */
5921  if( !SCIPsetIsZero(set, vals[t]) )
5922  {
5923  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
5924  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
5925 
5926  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5927  t++;
5928  }
5929  cols[t] = cols[s];
5930  cols_index[t] = cols_index[s];
5931  vals[t] = vals[s];
5932  }
5933  }
5934  if( !SCIPsetIsZero(set, vals[t]) )
5935  {
5936  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5937  t++;
5938  }
5939  assert(s == row->len);
5940  assert(t <= row->len);
5941 
5942  row->len = t;
5943  row->nunlinked = t;
5944 
5945  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
5946  if( t < s )
5947  rowCalcNorms(row, set);
5948  }
5949 
5950 #ifndef NDEBUG
5951  /* check for double entries */
5952  {
5953  int i;
5954  int j;
5955 
5956  for( i = 0; i < row->len; ++i )
5957  {
5958  assert(row->cols[i] != NULL);
5959  assert(row->cols[i]->index == row->cols_index[i]);
5960  for( j = i+1; j < row->len; ++j )
5961  assert(row->cols[i] != row->cols[j]);
5962  }
5963  }
5964 #endif
5965 }
5966 
5967 /** enables delaying of row sorting */
5969  SCIP_ROW* row /**< LP row */
5970  )
5971 {
5972  assert(row != NULL);
5973  assert(!row->delaysort);
5974 
5975  row->delaysort = TRUE;
5976 }
5977 
5978 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
5980  SCIP_ROW* row, /**< LP row */
5981  SCIP_SET* set /**< global SCIP settings */
5982  )
5983 {
5984  assert(row != NULL);
5985  assert(row->delaysort);
5986 
5987  row->delaysort = FALSE;
5988  rowMerge(row, set);
5989 }
5990 
5991 /** recalculates the current activity of a row */
5993  SCIP_ROW* row, /**< LP row */
5994  SCIP_STAT* stat /**< problem statistics */
5995  )
5996 {
5997  SCIP_COL* col;
5998  int c;
5999 
6000  assert(row != NULL);
6001  assert(stat != NULL);
6002 
6003  row->activity = row->constant;
6004  for( c = 0; c < row->nlpcols; ++c )
6005  {
6006  col = row->cols[c];
6007  assert(col != NULL);
6008  assert(col->primsol < SCIP_INVALID);
6009  assert(col->lppos >= 0);
6010  assert(row->linkpos[c] >= 0);
6011  row->activity += row->vals[c] * col->primsol;
6012  }
6013 
6014  if( row->nunlinked > 0 )
6015  {
6016  for( c = row->nlpcols; c < row->len; ++c )
6017  {
6018  col = row->cols[c];
6019  assert(col != NULL);
6020  assert(col->lppos >= 0 || col->primsol == 0.0);
6021  assert(col->lppos == -1 || row->linkpos[c] == -1);
6022  if( col->lppos >= 0 )
6023  row->activity += row->vals[c] * col->primsol;
6024  }
6025  }
6026 #ifndef NDEBUG
6027  else
6028  {
6029  for( c = row->nlpcols; c < row->len; ++c )
6030  {
6031  col = row->cols[c];
6032  assert(col != NULL);
6033  assert(col->primsol == 0.0);
6034  assert(col->lppos == -1);
6035  assert(row->linkpos[c] >= 0);
6036  }
6037  }
6038 #endif
6039 
6040  row->validactivitylp = stat->lpcount;
6041 }
6042 
6043 /** returns the activity of a row in the current LP solution */
6045  SCIP_ROW* row, /**< LP row */
6046  SCIP_SET* set, /**< global SCIP settings */
6047  SCIP_STAT* stat, /**< problem statistics */
6048  SCIP_LP* lp /**< current LP data */
6049  )
6050 {
6051  SCIP_Real inf;
6052  SCIP_Real activity;
6053 
6054  assert(row != NULL);
6055  assert(stat != NULL);
6056  assert(lp != NULL);
6057  assert(row->validactivitylp <= stat->lpcount);
6058  assert(lp->validsollp == stat->lpcount);
6059 
6060  if( row->validactivitylp != stat->lpcount )
6061  SCIProwRecalcLPActivity(row, stat);
6062  assert(row->validactivitylp == stat->lpcount);
6063  assert(row->activity < SCIP_INVALID);
6064 
6065  activity = row->activity;
6066  inf = SCIPsetInfinity(set);
6067  activity = MAX(activity, -inf);
6068  activity = MIN(activity, +inf);
6069 
6070  return activity;
6071 }
6072 
6073 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6075  SCIP_ROW* row, /**< LP row */
6076  SCIP_SET* set, /**< global SCIP settings */
6077  SCIP_STAT* stat, /**< problem statistics */
6078  SCIP_LP* lp /**< current LP data */
6079  )
6080 {
6081  SCIP_Real activity;
6082 
6083  assert(row != NULL);
6084 
6085  activity = SCIProwGetLPActivity(row, set, stat, lp);
6086 
6087  return MIN(row->rhs - activity, activity - row->lhs);
6088 }
6089 
6090 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6091  *
6092  * @todo Implement calculation of activities similar to LPs.
6093  */
6095  SCIP_ROW* row, /**< LP row */
6096  SCIP_SET* set, /**< global SCIP settings */
6097  SCIP_STAT* stat /**< problem statistics */
6098  )
6099 {
6100  SCIP_Real inf;
6101  SCIP_Real activity;
6102  SCIP_COL* col;
6103  int c;
6104 
6105  assert( row != NULL );
6106  assert( stat != NULL );
6107 
6108  activity = row->constant;
6109  for (c = 0; c < row->nlpcols; ++c)
6110  {
6111  col = row->cols[c];
6112  assert( col != NULL );
6113  assert( col->lppos >= 0 );
6114  assert( col->var != NULL );
6115  assert( row->linkpos[c] >= 0 );
6116  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6117  }
6118 
6119  if ( row->nunlinked > 0 )
6120  {
6121  for (c = row->nlpcols; c < row->len; ++c)
6122  {
6123  col = row->cols[c];
6124  assert( col != NULL );
6125  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6126  if ( col->lppos >= 0 )
6127  {
6128  assert( col->var != NULL );
6129  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6130  }
6131  }
6132  }
6133 #ifndef NDEBUG
6134  else
6135  {
6136  for (c = row->nlpcols; c < row->len; ++c)
6137  {
6138  col = row->cols[c];
6139  assert( col != NULL );
6140  assert( col->lppos == -1 );
6141  assert( row->linkpos[c] >= 0 );
6142  }
6143  }
6144 #endif
6145  inf = SCIPsetInfinity(set);
6146  activity = MAX(activity, -inf);
6147  activity = MIN(activity, +inf);
6148 
6149  return MIN(row->rhs - activity, activity - row->lhs);
6150 }
6151 
6152 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6153  *
6154  * @todo Implement calculation of activities similar to LPs.
6155  */
6157  SCIP_ROW* row, /**< LP row */
6158  SCIP_SET* set, /**< global SCIP settings */
6159  SCIP_STAT* stat /**< problem statistics */
6160  )
6161 {
6162  SCIP_Real inf;
6163  SCIP_Real activity;
6164  SCIP_COL* col;
6165  int c;
6166 
6167  assert( row != NULL );
6168  assert( stat != NULL );
6169 
6170  activity = row->constant;
6171  for (c = 0; c < row->nlpcols; ++c)
6172  {
6173  col = row->cols[c];
6174  assert( col != NULL );
6175  assert( col->lppos >= 0 );
6176  assert( col->var != NULL );
6177  assert( row->linkpos[c] >= 0 );
6178  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6179  }
6180 
6181  if ( row->nunlinked > 0 )
6182  {
6183  for (c = row->nlpcols; c < row->len; ++c)
6184  {
6185  col = row->cols[c];
6186  assert( col != NULL );
6187  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6188  if ( col->lppos >= 0 )
6189  {
6190  assert( col->var != NULL );
6191  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6192  }
6193  }
6194  }
6195 #ifndef NDEBUG
6196  else
6197  {
6198  for (c = row->nlpcols; c < row->len; ++c)
6199  {
6200  col = row->cols[c];
6201  assert( col != NULL );
6202  assert( col->lppos == -1 );
6203  assert( row->linkpos[c] >= 0 );
6204  }
6205  }
6206 #endif
6207  inf = SCIPsetInfinity(set);
6208  activity = MAX(activity, -inf);
6209  activity = MIN(activity, +inf);
6210 
6211  return MIN(row->rhs - activity, activity - row->lhs);
6212 }
6213 
6214 /** calculates the current pseudo activity of a row */
6216  SCIP_ROW* row, /**< row data */
6217  SCIP_STAT* stat /**< problem statistics */
6218  )
6219 {
6220  SCIP_COL* col;
6221  int i;
6222 
6223  assert(row != NULL);
6224  assert(stat != NULL);
6225 
6226  row->pseudoactivity = row->constant;
6227  for( i = 0; i < row->len; ++i )
6228  {
6229  col = row->cols[i];
6230  assert(col != NULL);
6231  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6232  assert(col->var != NULL);
6233  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6234 
6235  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6236  }
6237  row->validpsactivitydomchg = stat->domchgcount;
6238  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6239 }
6240 
6241 /** returns the pseudo activity of a row in the current pseudo solution */
6243  SCIP_ROW* row, /**< LP row */
6244  SCIP_SET* set, /**< global SCIP settings */
6245  SCIP_STAT* stat /**< problem statistics */
6246  )
6247 {
6248  SCIP_Real inf;
6249  SCIP_Real activity;
6250 
6251  assert(row != NULL);
6252  assert(stat != NULL);
6253  assert(row->validpsactivitydomchg <= stat->domchgcount);
6254 
6255  /* check, if pseudo activity has to be calculated */
6256  if( row->validpsactivitydomchg != stat->domchgcount )
6257  SCIProwRecalcPseudoActivity(row, stat);
6258  assert(row->validpsactivitydomchg == stat->domchgcount);
6259  assert(row->pseudoactivity < SCIP_INVALID);
6260 
6261  activity = row->pseudoactivity;
6262  inf = SCIPsetInfinity(set);
6263  activity = MAX(activity, -inf);
6264  activity = MIN(activity, +inf);
6265 
6266  return activity;
6267 }
6268 
6269 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6271  SCIP_ROW* row, /**< LP row */
6272  SCIP_SET* set, /**< global SCIP settings */
6273  SCIP_STAT* stat /**< problem statistics */
6274  )
6275 {
6276  SCIP_Real pseudoactivity;
6277 
6278  assert(row != NULL);
6279 
6280  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6281 
6282  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6283 }
6284 
6285 /** returns the activity of a row for a given solution */
6287  SCIP_ROW* row, /**< LP row */
6288  SCIP_SET* set, /**< global SCIP settings */
6289  SCIP_STAT* stat, /**< problem statistics data */
6290  SCIP_SOL* sol /**< primal CIP solution */
6291  )
6292 {
6293  SCIP_COL* col;
6294  SCIP_Real inf;
6295  SCIP_Real activity;
6296  SCIP_Real solval;
6297  int i;
6298 
6299  assert(row != NULL);
6300 
6301  activity = row->constant;
6302  for( i = 0; i < row->len; ++i )
6303  {
6304  col = row->cols[i];
6305  assert(col != NULL);
6306  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6307  solval = SCIPsolGetVal(sol, set, stat, col->var);
6308  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6309  {
6310  if( SCIPsetIsInfinity(set, -row->lhs) )
6311  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6312  else if( SCIPsetIsInfinity(set, row->rhs) )
6313  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6314  else
6315  solval = (col->lb + col->ub)/2.0;
6316  }
6317  activity += row->vals[i] * solval;
6318  }
6319 
6320  inf = SCIPsetInfinity(set);
6321  activity = MAX(activity, -inf);
6322  activity = MIN(activity, +inf);
6323 
6324  return activity;
6325 }
6326 
6327 /** returns the feasibility of a row for the given solution */
6329  SCIP_ROW* row, /**< LP row */
6330  SCIP_SET* set, /**< global SCIP settings */
6331  SCIP_STAT* stat, /**< problem statistics data */
6332  SCIP_SOL* sol /**< primal CIP solution */
6333  )
6334 {
6335  SCIP_Real activity;
6336 
6337  assert(row != NULL);
6338 
6339  activity = SCIProwGetSolActivity(row, set, stat, sol);
6340 
6341  return MIN(row->rhs - activity, activity - row->lhs);
6342 }
6343 
6344 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6345 static
6347  SCIP_ROW* row, /**< row data */
6348  SCIP_SET* set, /**< global SCIP settings */
6349  SCIP_STAT* stat /**< problem statistics data */
6350  )
6351 {
6352  SCIP_COL* col;
6353  SCIP_Real val;
6354  SCIP_Bool mininfinite;
6355  SCIP_Bool maxinfinite;
6356  int i;
6357 
6358  assert(row != NULL);
6359  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6360  assert(stat != NULL);
6361 
6362  /* calculate activity bounds */
6363  mininfinite = FALSE;
6364  maxinfinite = FALSE;
6365  row->minactivity = row->constant;
6366  row->maxactivity = row->constant;
6367  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6368  {
6369  col = row->cols[i];
6370  assert(col != NULL);
6371  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6372  val = row->vals[i];
6373  if( val >= 0.0 )
6374  {
6375  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6376  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6377  if( !mininfinite )
6378  row->minactivity += val * col->lb;
6379  if( !maxinfinite )
6380  row->maxactivity += val * col->ub;
6381  }
6382  else
6383  {
6384  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6385  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6386  if( !mininfinite )
6387  row->minactivity += val * col->ub;
6388  if( !maxinfinite )
6389  row->maxactivity += val * col->lb;
6390  }
6391  }
6392 
6393  if( mininfinite )
6394  row->minactivity = -SCIPsetInfinity(set);
6395  if( maxinfinite )
6396  row->maxactivity = SCIPsetInfinity(set);
6397  row->validactivitybdsdomchg = stat->domchgcount;
6398 
6399  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6401  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6403 }
6404 
6405 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6407  SCIP_ROW* row, /**< LP row */
6408  SCIP_SET* set, /**< global SCIP settings */
6409  SCIP_STAT* stat /**< problem statistics data */
6410  )
6411 {
6412  assert(row != NULL);
6413  assert(stat != NULL);
6414  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6415 
6416  /* check, if activity bounds has to be calculated */
6417  if( row->validactivitybdsdomchg != stat->domchgcount )
6418  rowCalcActivityBounds(row, set, stat);
6419  assert(row->validactivitybdsdomchg == stat->domchgcount);
6420  assert(row->minactivity < SCIP_INVALID);
6421  assert(row->maxactivity < SCIP_INVALID);
6422 
6423  return row->minactivity;
6424 }
6425 
6426 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6428  SCIP_ROW* row, /**< LP row */
6429  SCIP_SET* set, /**< global SCIP settings */
6430  SCIP_STAT* stat /**< problem statistics data */
6431  )
6432 {
6433  assert(row != NULL);
6434  assert(stat != NULL);
6435  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6436 
6437  /* check, if activity bounds has to be calculated */
6438  if( row->validactivitybdsdomchg != stat->domchgcount )
6439  rowCalcActivityBounds(row, set, stat);
6440  assert(row->validactivitybdsdomchg == stat->domchgcount);
6441  assert(row->minactivity < SCIP_INVALID);
6442  assert(row->maxactivity < SCIP_INVALID);
6443 
6444  return row->maxactivity;
6445 }
6446 
6447 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6449  SCIP_ROW* row, /**< LP row */
6450  SCIP_SET* set, /**< global SCIP settings */
6451  SCIP_STAT* stat /**< problem statistics data */
6452  )
6453 {
6454  assert(row != NULL);
6455 
6456  if( row->modifiable )
6457  return FALSE;
6458  if( !SCIPsetIsInfinity(set, -row->lhs) )
6459  {
6460  SCIP_Real minactivity;
6461 
6462  minactivity = SCIProwGetMinActivity(row, set, stat);
6463  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6464  return FALSE;
6465  }
6466  if( !SCIPsetIsInfinity(set, row->rhs) )
6467  {
6468  SCIP_Real maxactivity;
6469 
6470  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6471  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6472  return FALSE;
6473  }
6474 
6475  return TRUE;
6476 }
6477 
6478 /** gets maximal absolute value of row vector coefficients */
6480  SCIP_ROW* row, /**< LP row */
6481  SCIP_SET* set /**< global SCIP settings */
6482  )
6483 {
6484  assert(row != NULL);
6485 
6486  if( row->nummaxval == 0 )
6487  rowCalcIdxsAndVals(row, set);
6488  assert(row->nummaxval > 0);
6489  assert(row->maxval >= 0.0 || row->len == 0);
6490 
6491  return row->maxval;
6492 }
6493 
6494 /** gets minimal absolute value of row vector's non-zero coefficients */
6496  SCIP_ROW* row, /**< LP row */
6497  SCIP_SET* set /**< global SCIP settings */
6498  )
6499 {
6500  assert(row != NULL);
6501 
6502  if( row->numminval == 0 )
6503  rowCalcIdxsAndVals(row, set);
6504  assert(row->numminval > 0);
6505  assert(row->minval >= 0.0 || row->len == 0);
6506 
6507  return row->minval;
6508 }
6509 
6510 /** gets maximal column index of row entries */
6512  SCIP_ROW* row, /**< LP row */
6513  SCIP_SET* set /**< global SCIP settings */
6514  )
6515 {
6516  assert(row != NULL);
6517 
6518  if( row->validminmaxidx == 0 )
6519  rowCalcIdxsAndVals(row, set);
6520  assert(row->maxidx >= 0 || row->len == 0);
6521  assert(row->validminmaxidx);
6522 
6523  return row->maxidx;
6524 }
6525 
6526 /** gets minimal column index of row entries */
6528  SCIP_ROW* row, /**< LP row */
6529  SCIP_SET* set /**< global SCIP settings */
6530  )
6531 {
6532  assert(row != NULL);
6533 
6534  if( row->validminmaxidx == 0 )
6535  rowCalcIdxsAndVals(row, set);
6536  assert(row->minidx >= 0 || row->len == 0);
6537  assert(row->validminmaxidx);
6538 
6539  return row->minidx;
6540 }
6541 
6542 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6544  SCIP_ROW* row, /**< LP row */
6545  SCIP_SET* set, /**< global SCIP settings */
6546  SCIP_STAT* stat, /**< problem statistics data */
6547  SCIP_LP* lp /**< current LP data */
6548  )
6549 {
6550  SCIP_Real norm;
6551  SCIP_Real feasibility;
6552  SCIP_Real eps;
6553 
6554  assert(set != NULL);
6555 
6556  switch( set->sepa_efficacynorm )
6557  {
6558  case 'e':
6559  norm = SCIProwGetNorm(row);
6560  break;
6561  case 'm':
6562  norm = SCIProwGetMaxval(row, set);
6563  break;
6564  case 's':
6565  norm = SCIProwGetSumNorm(row);
6566  break;
6567  case 'd':
6568  norm = (row->len == 0 ? 0.0 : 1.0);
6569  break;
6570  default:
6571  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6572  SCIPABORT();
6573  norm = 0.0; /*lint !e527*/
6574  }
6575 
6576  eps = SCIPsetSumepsilon(set);
6577  norm = MAX(norm, eps);
6578  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6579 
6580  return -feasibility / norm;
6581 }
6582 
6583 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6585  SCIP_ROW* row, /**< LP row */
6586  SCIP_SET* set, /**< global SCIP settings */
6587  SCIP_STAT* stat, /**< problem statistics data */
6588  SCIP_LP* lp, /**< current LP data */
6589  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6590  )
6591 {
6592  SCIP_Real efficacy;
6593 
6594  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6595 
6596  return SCIPsetIsEfficacious(set, root, efficacy);
6597 }
6598 
6599 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6601  SCIP_ROW* row, /**< LP row */
6602  SCIP_SET* set, /**< global SCIP settings */
6603  SCIP_STAT* stat, /**< problem statistics data */
6604  SCIP_SOL* sol /**< primal CIP solution */
6605  )
6606 {
6607  SCIP_Real norm;
6608  SCIP_Real feasibility;
6609  SCIP_Real eps;
6610 
6611  assert(set != NULL);
6612 
6613  switch( set->sepa_efficacynorm )
6614  {
6615  case 'e':
6616  norm = SCIProwGetNorm(row);
6617  break;
6618  case 'm':
6619  norm = SCIProwGetMaxval(row, set);
6620  break;
6621  case 's':
6622  norm = SCIProwGetSumNorm(row);
6623  break;
6624  case 'd':
6625  norm = (row->len == 0 ? 0.0 : 1.0);
6626  break;
6627  default:
6628  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6629  SCIPABORT();
6630  norm = 0.0; /*lint !e527*/
6631  }
6632 
6633  eps = SCIPsetSumepsilon(set);
6634  norm = MAX(norm, eps);
6635  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6636 
6637  return -feasibility / norm;
6638 }
6639 
6640 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6641  * efficacy
6642  */
6644  SCIP_ROW* row, /**< LP row */
6645  SCIP_SET* set, /**< global SCIP settings */
6646  SCIP_STAT* stat, /**< problem statistics data */
6647  SCIP_SOL* sol, /**< primal CIP solution */
6648  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6649  )
6650 {
6651  SCIP_Real efficacy;
6652 
6653  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6654 
6655  return SCIPsetIsEfficacious(set, root, efficacy);
6656 }
6657 
6658 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6660  SCIP_ROW* row, /**< LP row */
6661  SCIP_SET* set, /**< global SCIP settings */
6662  SCIP_STAT* stat /**< problem statistics data */
6663  )
6664 {
6665  SCIP_Real norm;
6666  SCIP_Real feasibility;
6667  SCIP_Real eps;
6668 
6669  assert(set != NULL);
6670 
6671  switch( set->sepa_efficacynorm )
6672  {
6673  case 'e':
6674  norm = SCIProwGetNorm(row);
6675  break;
6676  case 'm':
6677  norm = SCIProwGetMaxval(row, set);
6678  break;
6679  case 's':
6680  norm = SCIProwGetSumNorm(row);
6681  break;
6682  case 'd':
6683  norm = (row->len == 0 ? 0.0 : 1.0);
6684  break;
6685  default:
6686  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6687  SCIPABORT();
6688  norm = 0.0; /*lint !e527*/
6689  }
6690 
6691  eps = SCIPsetSumepsilon(set);
6692  norm = MAX(norm, eps);
6693  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6694 
6695  return -feasibility / norm;
6696 }
6697 
6698 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6700  SCIP_ROW* row, /**< LP row */
6701  SCIP_SET* set, /**< global SCIP settings */
6702  SCIP_STAT* stat /**< problem statistics data */
6703  )
6704 {
6705  SCIP_Real norm;
6706  SCIP_Real feasibility;
6707  SCIP_Real eps;
6708 
6709  assert(set != NULL);
6710 
6711  switch( set->sepa_efficacynorm )
6712  {
6713  case 'e':
6714  norm = SCIProwGetNorm(row);
6715  break;
6716  case 'm':
6717  norm = SCIProwGetMaxval(row, set);
6718  break;
6719  case 's':
6720  norm = SCIProwGetSumNorm(row);
6721  break;
6722  case 'd':
6723  norm = (row->len == 0 ? 0.0 : 1.0);
6724  break;
6725  default:
6726  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6727  SCIPABORT();
6728  norm = 0.0; /*lint !e527*/
6729  }
6730 
6731  eps = SCIPsetSumepsilon(set);
6732  norm = MAX(norm, eps);
6733  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6734 
6735  return -feasibility / norm;
6736 }
6737 
6738 /** returns the scalar product of the coefficient vectors of the two given rows
6739  *
6740  * @note the scalar product is computed w.r.t. the current LP columns only
6741  * @todo also consider non-LP columns for the computation?
6742  */
6744  SCIP_ROW* row1, /**< first LP row */
6745  SCIP_ROW* row2 /**< second LP row */
6746  )
6747 {
6748  SCIP_Real scalarprod;
6749  int* row1colsidx;
6750  int* row2colsidx;
6751  int i1;
6752  int i2;
6753 
6754  assert(row1 != NULL);
6755  assert(row2 != NULL);
6756 
6757  /* Sort the column indices of both rows.
6758  *
6759  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
6760  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
6761  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
6762  * for both or one of the non-LP columns for both.
6763  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
6764  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
6765  * columns can be added later and remain unlinked while all previously added columns might already be linked.
6766  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
6767  *
6768  * We distinguish the following cases:
6769  *
6770  * 1) both rows have no unlinked columns
6771  * -> we just check the LP partitions
6772  *
6773  * 2) exactly one row is completely unlinked, the other one is completely linked
6774  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
6775  * (thus all common LP columns are regarded)
6776  *
6777  * 3) we have unlinked and LP columns in both rows
6778  * -> we need to compare four partitions at once
6779  *
6780  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
6781  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
6782  * other row
6783  *
6784  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
6785  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
6786  *
6787  * 5) both rows are completely unlinked
6788  * -> we need to compare two partitions: both complete rows
6789  */
6790  SCIProwSort(row1);
6791  assert(row1->lpcolssorted);
6792  assert(row1->nonlpcolssorted);
6793  SCIProwSort(row2);
6794  assert(row2->lpcolssorted);
6795  assert(row2->nonlpcolssorted);
6796 
6797  assert(row1->nunlinked <= row1->len - row1->nlpcols);
6798  assert(row2->nunlinked <= row2->len - row2->nlpcols);
6799 
6800  row1colsidx = row1->cols_index;
6801  row2colsidx = row2->cols_index;
6802 
6803 #ifndef NDEBUG
6804  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
6805  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
6806  {
6807  i1 = 0;
6808  i2 = row2->nlpcols;
6809  while( i1 < row1->nlpcols && i2 < row2->len )
6810  {
6811  assert(row1->cols[i1] != row2->cols[i2]);
6812  if( row1->cols[i1]->index < row2->cols[i2]->index )
6813  ++i1;
6814  else
6815  {
6816  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6817  ++i2;
6818  }
6819  }
6820  assert(i1 == row1->nlpcols || i2 == row2->len);
6821 
6822  i1 = row1->nlpcols;
6823  i2 = 0;
6824  while( i1 < row1->len && i2 < row2->nlpcols )
6825  {
6826  assert(row1->cols[i1] != row2->cols[i2]);
6827  if( row1->cols[i1]->index < row2->cols[i2]->index )
6828  ++i1;
6829  else
6830  {
6831  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6832  ++i2;
6833  }
6834  }
6835  assert(i1 == row1->len || i2 == row2->nlpcols);
6836  }
6837 #endif
6838 
6839  /* The "easy" cases 1) and 2) */
6840  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
6841  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
6842  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
6843  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
6844  {
6845  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
6846  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
6847 
6848  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
6849  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
6850  */
6851  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
6852  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
6853  scalarprod = 0.0;
6854 
6855  /* calculate the scalar product */
6856  while( i1 >= 0 && i2 >= 0 )
6857  {
6858  assert(row1->cols[i1]->index == row1colsidx[i1]);
6859  assert(row2->cols[i2]->index == row2colsidx[i2]);
6860  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
6861  if( row1colsidx[i1] < row2colsidx[i2] )
6862  --i2;
6863  else if( row1colsidx[i1] > row2colsidx[i2] )
6864  --i1;
6865  else
6866  {
6867  scalarprod += row1->vals[i1] * row2->vals[i2];
6868  --i1;
6869  --i2;
6870  }
6871  }
6872  }
6873  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
6874  else
6875  {
6876  SCIP_Bool lpcols;
6877  int ilp1;
6878  int inlp1;
6879  int ilp2;
6880  int inlp2;
6881  int end1;
6882  int end2;
6883 
6884  scalarprod = 0;
6885  ilp1 = 0;
6886  ilp2 = 0;
6887 
6888  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
6889  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
6890  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
6891 
6892  /* handle the case of four partitions (case 3) until one partition is finished;
6893  * cases 4a), 4b), and 5) will fail the while-condition
6894  */
6895  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
6896  {
6897  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
6898  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
6899  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
6900  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
6901  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
6902  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
6903  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
6904  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
6905 
6906  /* rows have the same linked LP columns */
6907  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
6908  {
6909  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
6910  ++ilp1;
6911  ++ilp2;
6912  }
6913  /* LP column of row1 is the same as unlinked column of row2 */
6914  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
6915  {
6916  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
6917  ++ilp1;
6918  ++inlp2;
6919  }
6920  /* unlinked column of row1 is the same as LP column of row2 */
6921  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
6922  {
6923  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
6924  ++inlp1;
6925  ++ilp2;
6926  }
6927  /* two unlinked LP columns are the same */
6928  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
6929  {
6930  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
6931  ++inlp1;
6932  ++inlp2;
6933  }
6934  /* increase smallest counter */
6935  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
6936  {
6937  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
6938  {
6939  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
6940  ++ilp1;
6941  else
6942  ++ilp2;
6943  }
6944  else
6945  {
6946  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
6947  ++ilp1;
6948  else
6949  ++inlp2;
6950  }
6951  }
6952  else
6953  {
6954  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
6955  {
6956  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
6957  ++inlp1;
6958  else
6959  ++ilp2;
6960  }
6961  else
6962  {
6963  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
6964  ++inlp1;
6965  else
6966  ++inlp2;
6967  }
6968  }
6969  }
6970 
6971  /* One partition was completely handled, we just have to handle the three remaining partitions:
6972  * the remaining partition of this row and the two partitions of the other row.
6973  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
6974  */
6975  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
6976  {
6977  int tmpilp;
6978  int tmpinlp;
6979 
6980  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
6981 
6982  SCIPswapPointers((void**) &row1, (void**) &row2);
6983  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
6984  tmpilp = ilp1;
6985  tmpinlp = inlp1;
6986  ilp1 = ilp2;
6987  inlp1 = inlp2;
6988  ilp2 = tmpilp;
6989  inlp2 = tmpinlp;
6990  }
6991 
6992  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
6993  * -> this merges cases 4a) and 4b)
6994  */
6995  if( ilp1 == row1->nlpcols )
6996  {
6997  i1 = inlp1;
6998  end1 = row1->len;
6999  lpcols = FALSE;
7000  }
7001  else
7002  {
7003  assert(inlp1 == row1->len);
7004 
7005  i1 = ilp1;
7006  end1 = row1->nlpcols;
7007  lpcols = TRUE;
7008  }
7009 
7010  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7011  * case 5) will fail the while-condition
7012  */
7013  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7014  {
7015  assert(row1->cols[i1]->index == row1colsidx[i1]);
7016  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7017  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7018  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7019  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7020 
7021  /* current column in row 1 is the same as the current LP column in row 2 */
7022  if( row1colsidx[i1] == row2colsidx[ilp2] )
7023  {
7024  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7025  ++i1;
7026  ++ilp2;
7027  }
7028  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7029  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7030  {
7031  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7032  ++i1;
7033  ++inlp2;
7034  }
7035  /* increase smallest counter */
7036  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7037  {
7038  if( row1colsidx[i1] < row2colsidx[ilp2] )
7039  ++i1;
7040  else
7041  ++ilp2;
7042  }
7043  else
7044  {
7045  if( row1colsidx[i1] < row2colsidx[inlp2] )
7046  ++i1;
7047  else
7048  ++inlp2;
7049  }
7050  }
7051 
7052  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7053  * the two rows
7054  */
7055  if( i1 < end1 )
7056  {
7057  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7058  if( ilp2 == row2->nlpcols )
7059  {
7060  i2 = inlp2;
7061  end2 = row2->len;
7062  lpcols = FALSE;
7063  }
7064  else
7065  {
7066  assert(inlp2 == row2->len);
7067 
7068  i2 = ilp2;
7069  end2 = row2->nlpcols;
7070  }
7071 
7072  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7073  while( i1 < end1 && i2 < end2 )
7074  {
7075  assert(row1->cols[i1]->index == row1colsidx[i1]);
7076  assert(row2->cols[i2]->index == row2colsidx[i2]);
7077  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7078 
7079  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7080  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7081  {
7082  scalarprod += row1->vals[i1] * row2->vals[i2];
7083  ++i1;
7084  ++i2;
7085  }
7086  /* increase smallest counter */
7087  else if( row1colsidx[i1] < row2colsidx[i2] )
7088  ++i1;
7089  else
7090  ++i2;
7091  }
7092  }
7093  }
7094 
7095  return scalarprod;
7096 }
7097 
7098 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7099 static
7101  SCIP_ROW* row1, /**< first LP row */
7102  SCIP_ROW* row2 /**< second LP row */
7103  )
7104 {
7105  int prod;
7106  int* row1colsidx;
7107  int* row2colsidx;
7108  int i1;
7109  int i2;
7110 
7111  assert(row1 != NULL);
7112  assert(row2 != NULL);
7113 
7114  /* Sort the column indices of both rows.
7115  *
7116  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7117  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7118  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7119  * for both or one of the non-LP columns for both.
7120  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7121  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7122  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7123  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7124  *
7125  * We distinguish the following cases:
7126  *
7127  * 1) both rows have no unlinked columns
7128  * -> we just check the LP partitions
7129  *
7130  * 2) exactly one row is completely unlinked, the other one is completely linked
7131  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7132  * (thus all common LP columns are regarded)
7133  *
7134  * 3) we have unlinked and LP columns in both rows
7135  * -> we need to compare four partitions at once
7136  *
7137  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7138  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7139  * other row
7140  *
7141  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7142  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7143  *
7144  * 5) both rows are completely unlinked
7145  * -> we need to compare two partitions: both complete rows
7146  */
7147  SCIProwSort(row1);
7148  assert(row1->lpcolssorted);
7149  assert(row1->nonlpcolssorted);
7150  SCIProwSort(row2);
7151  assert(row2->lpcolssorted);
7152  assert(row2->nonlpcolssorted);
7153 
7154  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7155  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7156 
7157  row1colsidx = row1->cols_index;
7158  row2colsidx = row2->cols_index;
7159 
7160 #ifndef NDEBUG
7161  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7162  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7163  {
7164  i1 = 0;
7165  i2 = row2->nlpcols;
7166  while( i1 < row1->nlpcols && i2 < row2->len )
7167  {
7168  assert(row1->cols[i1] != row2->cols[i2]);
7169  if( row1->cols[i1]->index < row2->cols[i2]->index )
7170  ++i1;
7171  else
7172  {
7173  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7174  ++i2;
7175  }
7176  }
7177  assert(i1 == row1->nlpcols || i2 == row2->len);
7178 
7179  i1 = row1->nlpcols;
7180  i2 = 0;
7181  while( i1 < row1->len && i2 < row2->nlpcols )
7182  {
7183  assert(row1->cols[i1] != row2->cols[i2]);
7184  if( row1->cols[i1]->index < row2->cols[i2]->index )
7185  ++i1;
7186  else
7187  {
7188  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7189  ++i2;
7190  }
7191  }
7192  assert(i1 == row1->len || i2 == row2->nlpcols);
7193  }
7194 #endif
7195 
7196  /* The "easy" cases 1) and 2) */
7197  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7198  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7199  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7200  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7201  {
7202  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7203  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7204 
7205  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7206  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7207  */
7208  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7209  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7210  prod = 0;
7211 
7212  /* calculate the scalar product */
7213  while( i1 >= 0 && i2 >= 0 )
7214  {
7215  assert(row1->cols[i1]->index == row1colsidx[i1]);
7216  assert(row2->cols[i2]->index == row2colsidx[i2]);
7217  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7218  if( row1colsidx[i1] < row2colsidx[i2] )
7219  --i2;
7220  else if( row1colsidx[i1] > row2colsidx[i2] )
7221  --i1;
7222  else
7223  {
7224  ++prod;
7225  --i1;
7226  --i2;
7227  }
7228  }
7229  }
7230  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7231  else
7232  {
7233  SCIP_Bool lpcols;
7234  int ilp1;
7235  int inlp1;
7236  int ilp2;
7237  int inlp2;
7238  int end1;
7239  int end2;
7240 
7241  prod = 0;
7242  ilp1 = 0;
7243  ilp2 = 0;
7244 
7245  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7246  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7247  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7248 
7249  /* handle the case of four partitions (case 3) until one partition is finished;
7250  * cases 4a), 4b), and 5) will fail the while-condition
7251  */
7252  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7253  {
7254  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7255  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7256  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7257  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7258  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7259  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7260  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7261  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7262 
7263  /* rows have the same linked LP columns */
7264  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7265  {
7266  ++prod;
7267  ++ilp1;
7268  ++ilp2;
7269  }
7270  /* LP column of row1 is the same as unlinked column of row2 */
7271  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7272  {
7273  ++prod;
7274  ++ilp1;
7275  ++inlp2;
7276  }
7277  /* unlinked column of row1 is the same as LP column of row2 */
7278  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7279  {
7280  ++prod;
7281  ++inlp1;
7282  ++ilp2;
7283  }
7284  /* two unlinked LP columns are the same */
7285  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7286  {
7287  ++prod;
7288  ++inlp1;
7289  ++inlp2;
7290  }
7291  /* increase smallest counter */
7292  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7293  {
7294  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7295  {
7296  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7297  ++ilp1;
7298  else
7299  ++ilp2;
7300  }
7301  else
7302  {
7303  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7304  ++ilp1;
7305  else
7306  ++inlp2;
7307  }
7308  }
7309  else
7310  {
7311  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7312  {
7313  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7314  ++inlp1;
7315  else
7316  ++ilp2;
7317  }
7318  else
7319  {
7320  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7321  ++inlp1;
7322  else
7323  ++inlp2;
7324  }
7325  }
7326  }
7327 
7328  /* One partition was completely handled, we just have to handle the three remaining partitions:
7329  * the remaining partition of this row and the two partitions of the other row.
7330  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7331  */
7332  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7333  {
7334  int tmpilp;
7335  int tmpinlp;
7336 
7337  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7338 
7339  SCIPswapPointers((void**) &row1, (void**) &row2);
7340  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7341  tmpilp = ilp1;
7342  tmpinlp = inlp1;
7343  ilp1 = ilp2;
7344  inlp1 = inlp2;
7345  ilp2 = tmpilp;
7346  inlp2 = tmpinlp;
7347  }
7348 
7349  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7350  * -> this merges cases 4a) and 4b)
7351  */
7352  if( ilp1 == row1->nlpcols )
7353  {
7354  i1 = inlp1;
7355  end1 = row1->len;
7356  lpcols = FALSE;
7357  }
7358  else
7359  {
7360  assert(inlp1 == row1->len);
7361 
7362  i1 = ilp1;
7363  end1 = row1->nlpcols;
7364  lpcols = TRUE;
7365  }
7366 
7367  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7368  * case 5) will fail the while-condition
7369  */
7370  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7371  {
7372  assert(row1->cols[i1]->index == row1colsidx[i1]);
7373  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7374  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7375  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7376  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7377 
7378  /* current column in row 1 is the same as the current LP column in row 2 */
7379  if( row1colsidx[i1] == row2colsidx[ilp2] )
7380  {
7381  ++prod;
7382  ++i1;
7383  ++ilp2;
7384  }
7385  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7386  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7387  {
7388  ++prod;
7389  ++i1;
7390  ++inlp2;
7391  }
7392  /* increase smallest counter */
7393  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7394  {
7395  if( row1colsidx[i1] < row2colsidx[ilp2] )
7396  ++i1;
7397  else
7398  ++ilp2;
7399  }
7400  else
7401  {
7402  if( row1colsidx[i1] < row2colsidx[inlp2] )
7403  ++i1;
7404  else
7405  ++inlp2;
7406  }
7407  }
7408 
7409  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7410  * the two rows
7411  */
7412  if( i1 < end1 )
7413  {
7414  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7415  if( ilp2 == row2->nlpcols )
7416  {
7417  i2 = inlp2;
7418  end2 = row2->len;
7419  lpcols = FALSE;
7420  }
7421  else
7422  {
7423  assert(inlp2 == row2->len);
7424 
7425  i2 = ilp2;
7426  end2 = row2->nlpcols;
7427  }
7428 
7429  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7430  while( i1 < end1 && i2 < end2 )
7431  {
7432  assert(row1->cols[i1]->index == row1colsidx[i1]);
7433  assert(row2->cols[i2]->index == row2colsidx[i2]);
7434  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7435 
7436  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7437  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7438  {
7439  ++prod;
7440  ++i1;
7441  ++i2;
7442  }
7443  /* increase smallest counter */
7444  else if( row1colsidx[i1] < row2colsidx[i2] )
7445  ++i1;
7446  else
7447  ++i2;
7448  }
7449  }
7450  }
7451 
7452  return prod;
7453 }
7454 
7455 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7456  * p = |v*w|/(|v|*|w|);
7457  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7458  */
7460  SCIP_ROW* row1, /**< first LP row */
7461  SCIP_ROW* row2, /**< second LP row */
7462  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7463  )
7464 {
7465  SCIP_Real parallelism;
7466  SCIP_Real scalarprod;
7467 
7468  switch( orthofunc )
7469  {
7470  case 'e':
7471  scalarprod = SCIProwGetScalarProduct(row1, row2);
7472  if( scalarprod == 0.0 )
7473  {
7474  parallelism = 0.0;
7475  break;
7476  }
7477 
7478  if( SCIProwGetNorm(row1) == 0.0 )
7479  {
7480  /* In theory, this should not happen if the scalarproduct is not zero
7481  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7482  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7483  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7484  */
7485  int i;
7486  for( i = 0; i < row1->len; ++i )
7487  if( row1->cols[i]->lppos >= 0 )
7488  row1->sqrnorm += SQR(row1->vals[i]);
7489  assert(SCIProwGetNorm(row1) != 0.0);
7490  }
7491 
7492  if( SCIProwGetNorm(row2) == 0.0 )
7493  {
7494  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7495  int i;
7496  for( i = 0; i < row2->len; ++i )
7497  if( row2->cols[i]->lppos >= 0 )
7498  row2->sqrnorm += SQR(row2->vals[i]);
7499  assert(SCIProwGetNorm(row2) != 0.0);
7500  }
7501 
7502  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7503  break;
7504 
7505  case 'd':
7506  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7507  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7508  break;
7509 
7510  default:
7511  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7512  SCIPABORT();
7513  parallelism = 0.0; /*lint !e527*/
7514  }
7515 
7516  return parallelism;
7517 }
7518 
7519 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7520  * o = 1 - |v*w|/(|v|*|w|);
7521  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7522  */
7524  SCIP_ROW* row1, /**< first LP row */
7525  SCIP_ROW* row2, /**< second LP row */
7526  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7527  )
7528 {
7529  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7530 }
7531 
7532 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7533  * function, if the value is 0, it is orthogonal to the objective function
7534  */
7536  SCIP_ROW* row, /**< LP row */
7537  SCIP_SET* set, /**< global SCIP settings */
7538  SCIP_LP* lp /**< current LP data */
7539  )
7540 {
7541  SCIP_Real prod;
7542  SCIP_Real parallelism;
7543 
7544  assert(row != NULL);
7545  assert(lp != NULL);
7546 
7547  if( lp->objsqrnormunreliable )
7548  SCIPlpRecalculateObjSqrNorm(set, lp);
7549 
7550  assert(!lp->objsqrnormunreliable);
7551  assert(lp->objsqrnorm >= 0.0);
7552 
7553  checkRowSqrnorm(row);
7554  checkRowObjprod(row);
7555 
7556  prod = row->sqrnorm * lp->objsqrnorm;
7557 
7558  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7559  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7560  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7561  parallelism = MIN(parallelism, 1.0);
7562  parallelism = MAX(parallelism, 0.0);
7563 
7564  return parallelism;
7565 }
7566 
7567 /** includes event handler with given data in row's event filter */
7569  SCIP_ROW* row, /**< row */
7570  BMS_BLKMEM* blkmem, /**< block memory */
7571  SCIP_SET* set, /**< global SCIP settings */
7572  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7573  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7574  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7575  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7576  )
7577 {
7578  assert(row != NULL);
7579  assert(row->eventfilter != NULL);
7580  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7581  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7582 
7583  SCIPsetDebugMsg(set, "catch event of type 0x%"SCIP_EVENTTYPE_FORMAT" of row <%s> with handler %p and data %p\n",
7584  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7585 
7586  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7587 
7588  return SCIP_OKAY;
7589 }
7590 
7591 /** deletes event handler with given data from row's event filter */
7593  SCIP_ROW* row, /**< row */
7594  BMS_BLKMEM* blkmem, /**< block memory */
7595  SCIP_SET* set, /**< global SCIP settings */
7596  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7597  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7598  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7599  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7600  )
7601 {
7602  assert(row != NULL);
7603  assert(row->eventfilter != NULL);
7604 
7605  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7606 
7607  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7608 
7609  return SCIP_OKAY;
7610 }
7611 
7612 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7614  SCIP_ROW* row, /**< LP row */
7615  SCIP_STAT* stat /**< problem statistics */
7616  )
7617 {
7618  assert(row != NULL);
7619  assert(stat != NULL);
7620  assert(stat->nnodes > 0);
7621 
7622  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7623  row->obsoletenode = stat->nnodes;
7624 }
7625 
7626 /*
7627  * LP solver data update
7628  */
7629 
7630 /** resets column data to represent a column not in the LP solver */
7631 static
7633  SCIP_COL* col /**< column to be marked deleted */
7634  )
7635 {
7636  assert(col != NULL);
7637 
7638  col->lpipos = -1;
7639  col->primsol = 0.0;
7640  col->redcost = SCIP_INVALID;
7641  col->farkascoef = SCIP_INVALID;
7642  col->sbdown = SCIP_INVALID;
7643  col->sbup = SCIP_INVALID;
7644  col->sbdownvalid = FALSE;
7645  col->sbupvalid = FALSE;
7646  col->validredcostlp = -1;
7647  col->validfarkaslp = -1;
7648  col->sbitlim = -1;
7649  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7650 }
7651 
7652 /** applies all cached column removals to the LP solver */
7653 static
7655  SCIP_LP* lp /**< current LP data */
7656  )
7657 {
7658  assert(lp != NULL);
7659  assert(lp->lpifirstchgcol <= lp->nlpicols);
7660  assert(lp->lpifirstchgcol <= lp->ncols);
7661 
7662  /* find the first column to change */
7663  while( lp->lpifirstchgcol < lp->nlpicols
7664  && lp->lpifirstchgcol < lp->ncols
7665  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7666  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7667  {
7668  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7669  lp->lpifirstchgcol++;
7670  }
7671 
7672  /* shrink LP to the part which didn't change */
7673  if( lp->lpifirstchgcol < lp->nlpicols )
7674  {
7675  int i;
7676 
7677  assert(!lp->diving);
7678  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7679  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7680  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7681  {
7682  markColDeleted(lp->lpicols[i]);
7683  }
7684  lp->nlpicols = lp->lpifirstchgcol;
7685  lp->flushdeletedcols = TRUE;
7686  lp->updateintegrality = TRUE;
7687 
7688  /* mark the LP unsolved */
7689  lp->solved = FALSE;
7690  lp->primalfeasible = FALSE;
7691  lp->lpobjval = SCIP_INVALID;
7693  }
7694  assert(lp->nlpicols == lp->lpifirstchgcol);
7695 
7696  return SCIP_OKAY;
7697 }
7698 
7699 /** computes for the given column the lower and upper bound that should be flushed into the LP
7700  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7701  * the bounds are explicitly added to the LP in any case
7702  */
7703 static
7705  SCIP_LP* lp, /**< current LP data */
7706  SCIP_SET* set, /**< global SCIP settings */
7707  SCIP_COL* col, /**< column to compute bounds for */
7708  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7709  SCIP_Real* lb, /**< pointer to store the new lower bound */
7710  SCIP_Real* ub /**< pointer to store the new upper bound */
7711  )
7712 {
7713  assert(lp != NULL);
7714  assert(set != NULL);
7715  assert(col != NULL);
7716  assert(lb != NULL);
7717  assert(ub != NULL);
7718 
7719  /* get the correct new lower bound:
7720  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7721  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7722  */
7723  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7724  (*lb) = -lpiinf;
7725  else
7726  (*lb) = col->lb;
7727  /* get the correct new upper bound:
7728  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7729  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7730  */
7731  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7732  (*ub) = lpiinf;
7733  else
7734  (*ub) = col->ub;
7735 }
7736 
7737 /** applies all cached column additions to the LP solver */
7738 static
7740  SCIP_LP* lp, /**< current LP data */
7741  BMS_BLKMEM* blkmem, /**< block memory */
7742  SCIP_SET* set, /**< global SCIP settings */
7743  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7744  )
7745 {
7746  SCIP_Real* obj;
7747  SCIP_Real* lb;
7748  SCIP_Real* ub;
7749  int* beg;
7750  int* ind;
7751  SCIP_Real* val;
7752  char** name;
7753  SCIP_COL* col;
7754  SCIP_Real lpiinf;
7755  int c;
7756  int pos;
7757  int nnonz;
7758  int naddcols;
7759  int naddcoefs;
7760  int i;
7761  int lpipos;
7762 
7763  assert(lp != NULL);
7764  assert(lp->lpifirstchgcol == lp->nlpicols);
7765  assert(blkmem != NULL);
7766  assert(set != NULL);
7767 
7768  /* if there are no columns to add, we are ready */
7769  if( lp->ncols == lp->nlpicols )
7770  return SCIP_OKAY;
7771 
7772  /* add the additional columns */
7773  assert(!lp->diving);
7774  assert(lp->ncols > lp->nlpicols);
7775  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
7776 
7777  /* get the solver's infinity value */
7778  lpiinf = SCIPlpiInfinity(lp->lpi);
7779 
7780  /* count the (maximal) number of added coefficients, calculate the number of added columns */
7781  naddcols = lp->ncols - lp->nlpicols;
7782  naddcoefs = 0;
7783  for( c = lp->nlpicols; c < lp->ncols; ++c )
7784  naddcoefs += lp->cols[c]->len;
7785  assert(naddcols > 0);
7786 
7787  /* get temporary memory for changes */
7788  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
7789  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
7790  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
7791  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
7792  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
7793  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
7794  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
7795 
7796  /* fill temporary memory with column data */
7797  nnonz = 0;
7798  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
7799  {
7800  col = lp->cols[c];
7801  assert(col != NULL);
7802  assert(col->var != NULL);
7803  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
7804  assert(SCIPvarGetCol(col->var) == col);
7805  assert(col->lppos == c);
7806  assert(nnonz + col->nlprows <= naddcoefs);
7807 
7808  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
7809  debugColPrint(set, col);
7810 
7811  /* Because the column becomes a member of the LP solver, it now can take values
7812  * different from zero. That means, we have to include the column in the corresponding
7813  * row vectors.
7814  */
7815  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
7816 
7817  lp->lpicols[c] = col;
7818  col->lpipos = c;
7819  col->primsol = SCIP_INVALID;
7820  col->redcost = SCIP_INVALID;
7821  col->farkascoef = SCIP_INVALID;
7822  col->sbdown = SCIP_INVALID;
7823  col->sbup = SCIP_INVALID;
7824  col->sbdownvalid = FALSE;
7825  col->sbupvalid = FALSE;
7826  col->validredcostlp = -1;
7827  col->validfarkaslp = -1;
7828  col->sbitlim = -1;
7829  col->objchanged = FALSE;
7830  col->lbchanged = FALSE;
7831  col->ubchanged = FALSE;
7832  col->coefchanged = FALSE;
7833  obj[pos] = col->obj;
7834 
7835  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
7836  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
7837 
7838  beg[pos] = nnonz;
7839  name[pos] = (char*)SCIPvarGetName(col->var);
7840 
7841  col->flushedobj = obj[pos];
7842  col->flushedlb = lb[pos];
7843  col->flushedub = ub[pos];
7844 
7845  for( i = 0; i < col->nlprows; ++i )
7846  {
7847  assert(col->rows[i] != NULL);
7848  lpipos = col->rows[i]->lpipos;
7849  if( lpipos >= 0 )
7850  {
7851  assert(lpipos < lp->nrows);
7852  assert(nnonz < naddcoefs);
7853  ind[nnonz] = lpipos;
7854  val[nnonz] = col->vals[i];
7855  nnonz++;
7856  }
7857  }
7858 #ifndef NDEBUG
7859  for( i = col->nlprows; i < col->len; ++i )
7860  {
7861  assert(col->rows[i] != NULL);
7862  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
7863  }
7864 #endif
7865  }
7866 
7867  /* call LP interface */
7868  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
7869  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
7870  lp->nlpicols = lp->ncols;
7871  lp->lpifirstchgcol = lp->nlpicols;
7872 
7873  /* free temporary memory */
7874  SCIPsetFreeBufferArray(set, &name);
7875  SCIPsetFreeBufferArray(set, &val);
7876  SCIPsetFreeBufferArray(set, &ind);
7877  SCIPsetFreeBufferArray(set, &beg);
7878  SCIPsetFreeBufferArray(set, &ub);
7879  SCIPsetFreeBufferArray(set, &lb);
7880  SCIPsetFreeBufferArray(set, &obj);
7881 
7882  lp->flushaddedcols = TRUE;
7883  lp->updateintegrality = TRUE;
7884 
7885  /* mark the LP unsolved */
7886  lp->solved = FALSE;
7887  lp->dualfeasible = FALSE;
7888  lp->lpobjval = SCIP_INVALID;
7890 
7891  return SCIP_OKAY;
7892 }
7893 
7894 /** resets row data to represent a row not in the LP solver */
7895 static
7897  SCIP_ROW* row /**< row to be marked deleted */
7898  )
7899 {
7900  assert(row != NULL);
7901 
7902  row->lpipos = -1;
7903  row->dualsol = 0.0;
7904  row->activity = SCIP_INVALID;
7905  row->dualfarkas = 0.0;
7906  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7907  row->validactivitylp = -1;
7908 }
7909 
7910 /** applies all cached row removals to the LP solver */
7911 static
7913  SCIP_LP* lp, /**< current LP data */
7914  BMS_BLKMEM* blkmem, /**< block memory */
7915  SCIP_SET* set /**< global SCIP settings */
7916  )
7917 {
7918  assert(lp != NULL);
7919  assert(lp->lpifirstchgrow <= lp->nlpirows);
7920  assert(lp->lpifirstchgrow <= lp->nrows);
7921 
7922  /* find the first row to change */
7923  while( lp->lpifirstchgrow < lp->nlpirows
7924  && lp->lpifirstchgrow < lp->nrows
7925  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
7926  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
7927  {
7928  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
7929  lp->lpifirstchgrow++;
7930  }
7931 
7932  /* shrink LP to the part which didn't change */
7933  if( lp->lpifirstchgrow < lp->nlpirows )
7934  {
7935  int i;
7936 
7937  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
7938  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
7939  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
7940  {
7941  markRowDeleted(lp->lpirows[i]);
7942  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
7943  }
7944  lp->nlpirows = lp->lpifirstchgrow;
7945  lp->flushdeletedrows = TRUE;
7946 
7947  /* mark the LP unsolved */
7948  lp->solved = FALSE;
7949  lp->dualfeasible = FALSE;
7950  lp->lpobjval = SCIP_INVALID;
7952  }
7953  assert(lp->nlpirows == lp->lpifirstchgrow);
7954 
7955  return SCIP_OKAY;
7956 }
7957 
7958 /** applies all cached row additions and removals to the LP solver */
7959 static
7961  SCIP_LP* lp, /**< current LP data */
7962  BMS_BLKMEM* blkmem, /**< block memory */
7963  SCIP_SET* set, /**< global SCIP settings */
7964  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7965  )
7966 {
7967  SCIP_Real* lhs;
7968  SCIP_Real* rhs;
7969  int* beg;
7970  int* ind;
7971  SCIP_Real* val;
7972  char** name;
7973  SCIP_ROW* row;
7974  SCIP_Real lpiinf;
7975  int r;
7976  int pos;
7977  int nnonz;
7978  int naddrows;
7979  int naddcoefs;
7980  int i;
7981  int lpipos;
7982 
7983  assert(lp != NULL);
7984  assert(lp->lpifirstchgrow == lp->nlpirows);
7985  assert(blkmem != NULL);
7986 
7987  /* if there are no rows to add, we are ready */
7988  if( lp->nrows == lp->nlpirows )
7989  return SCIP_OKAY;
7990 
7991  /* add the additional rows */
7992  assert(lp->nrows > lp->nlpirows);
7993  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
7994 
7995  /* get the solver's infinity value */
7996  lpiinf = SCIPlpiInfinity(lp->lpi);
7997 
7998  /* count the (maximal) number of added coefficients, calculate the number of added rows */
7999  naddrows = lp->nrows - lp->nlpirows;
8000  naddcoefs = 0;
8001  for( r = lp->nlpirows; r < lp->nrows; ++r )
8002  naddcoefs += lp->rows[r]->len;
8003  assert(naddrows > 0);
8004 
8005  /* get temporary memory for changes */
8006  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8007  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8008  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8009  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8010  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8011  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8012 
8013  /* fill temporary memory with row data */
8014  nnonz = 0;
8015  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8016  {
8017  row = lp->rows[r];
8018  assert(row != NULL);
8019  assert(row->lppos == r);
8020  assert(nnonz + row->nlpcols <= naddcoefs);
8021 
8022  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8023  debugRowPrint(set, row);
8024 
8025  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8026  * different from zero. That means, we have to include the row in the corresponding
8027  * column vectors.
8028  */
8029  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8030 
8031  SCIProwCapture(row);
8032  lp->lpirows[r] = row;
8033  row->lpipos = r;
8034  row->dualsol = SCIP_INVALID;
8035  row->activity = SCIP_INVALID;
8036  row->dualfarkas = SCIP_INVALID;
8037  row->validactivitylp = -1;
8038  row->lhschanged = FALSE;
8039  row->rhschanged = FALSE;
8040  row->coefchanged = FALSE;
8041  if( SCIPsetIsInfinity(set, -row->lhs) )
8042  lhs[pos] = -lpiinf;
8043  else
8044  lhs[pos] = row->lhs - row->constant;
8045  if( SCIPsetIsInfinity(set, row->rhs) )
8046  rhs[pos] = lpiinf;
8047  else
8048  rhs[pos] = row->rhs - row->constant;
8049  beg[pos] = nnonz;
8050  name[pos] = row->name;
8051 
8052  row->flushedlhs = lhs[pos];
8053  row->flushedrhs = rhs[pos];
8054 
8055  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8056  for( i = 0; i < row->nlpcols; ++i )
8057  {
8058  assert(row->cols[i] != NULL);
8059  lpipos = row->cols[i]->lpipos;
8060  if( lpipos >= 0 )
8061  {
8062  assert(lpipos < lp->ncols);
8063  assert(nnonz < naddcoefs);
8064  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8065  ind[nnonz] = lpipos;
8066  val[nnonz] = row->vals[i];
8067  nnonz++;
8068  }
8069  }
8070  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8071 #ifndef NDEBUG
8072  for( i = row->nlpcols; i < row->len; ++i )
8073  {
8074  assert(row->cols[i] != NULL);
8075  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8076  }
8077 #endif
8078  }
8079 
8080  /* call LP interface */
8081  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8082  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8083  lp->nlpirows = lp->nrows;
8084  lp->lpifirstchgrow = lp->nlpirows;
8085 
8086  /* free temporary memory */
8087  SCIPsetFreeBufferArray(set, &name);
8088  SCIPsetFreeBufferArray(set, &val);
8089  SCIPsetFreeBufferArray(set, &ind);
8090  SCIPsetFreeBufferArray(set, &beg);
8091  SCIPsetFreeBufferArray(set, &rhs);
8092  SCIPsetFreeBufferArray(set, &lhs);
8093 
8094  lp->flushaddedrows = TRUE;
8095 
8096  /* mark the LP unsolved */
8097  lp->solved = FALSE;
8098  lp->primalfeasible = FALSE;
8099  lp->lpobjval = SCIP_INVALID;
8101 
8102  return SCIP_OKAY;
8103 }
8104 
8105 /** applies all cached column bound and objective changes to the LP */
8106 static
8108  SCIP_LP* lp, /**< current LP data */
8109  SCIP_SET* set /**< global SCIP settings */
8110  )
8111 {
8112 #ifndef NDEBUG
8113  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8114 #endif
8115  SCIP_COL* col;
8116  int* objind;
8117  int* bdind;
8118  SCIP_Real* obj;
8119  SCIP_Real* lb;
8120  SCIP_Real* ub;
8121  SCIP_Real lpiinf;
8122  int nobjchg;
8123  int nbdchg;
8124  int i;
8125 
8126  assert(lp != NULL);
8127 
8128  if( lp->nchgcols == 0 )
8129  return SCIP_OKAY;
8130 
8131  /* get the solver's infinity value */
8132  lpiinf = SCIPlpiInfinity(lp->lpi);
8133 
8134  /* get temporary memory for changes */
8135  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8136  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8137  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8138  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8139  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8140 
8141  /* collect all cached bound and objective changes */
8142  nobjchg = 0;
8143  nbdchg = 0;
8144  for( i = 0; i < lp->nchgcols; ++i )
8145  {
8146  col = lp->chgcols[i];
8147  assert(col != NULL);
8148  assert(col->var != NULL);
8149  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8150  assert(SCIPvarGetCol(col->var) == col);
8151 
8152  if( col->lpipos >= 0 )
8153  {
8154 #ifndef NDEBUG
8155  /* do not check consistency of data with LPI in case of LPI=none */
8156  if( !lpinone )
8157  {
8158  SCIP_Real lpiobj;
8159  SCIP_Real lpilb;
8160  SCIP_Real lpiub;
8161 
8162  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8163  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8164  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8165  assert(SCIPsetIsFeasEQ(set, lpilb, col->flushedlb));
8166  assert(SCIPsetIsFeasEQ(set, lpiub, col->flushedub));
8167  }
8168 #endif
8169 
8170  if( col->objchanged )
8171  {
8172  SCIP_Real newobj;
8173 
8174  newobj = col->obj;
8175  if( col->flushedobj != newobj ) /*lint !e777*/
8176  {
8177  assert(nobjchg < lp->ncols);
8178  objind[nobjchg] = col->lpipos;
8179  obj[nobjchg] = newobj;
8180  nobjchg++;
8181  col->flushedobj = newobj;
8182  }
8183  col->objchanged = FALSE;
8184  }
8185 
8186  if( col->lbchanged || col->ubchanged )
8187  {
8188  SCIP_Real newlb;
8189  SCIP_Real newub;
8190 
8191  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8192  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8193 
8194  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8195  {
8196  assert(nbdchg < lp->ncols);
8197  bdind[nbdchg] = col->lpipos;
8198  lb[nbdchg] = newlb;
8199  ub[nbdchg] = newub;
8200  nbdchg++;
8201  col->flushedlb = newlb;
8202  col->flushedub = newub;
8203  }
8204  col->lbchanged = FALSE;
8205  col->ubchanged = FALSE;
8206  }
8207  }
8208  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8209  }
8210 
8211  /* change objective values in LP */
8212  if( nobjchg > 0 )
8213  {
8214  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8215  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8216 
8217  /* mark the LP unsolved */
8218  lp->solved = FALSE;
8219  lp->dualfeasible = FALSE;
8220  lp->lpobjval = SCIP_INVALID;
8222  }
8223 
8224  /* change bounds in LP */
8225  if( nbdchg > 0 )
8226  {
8227  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8228  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8229 
8230  /* mark the LP unsolved */
8231  lp->solved = FALSE;
8232  lp->primalfeasible = FALSE;
8233  lp->lpobjval = SCIP_INVALID;
8235  }
8236 
8237  lp->nchgcols = 0;
8238 
8239  /* free temporary memory */
8240  SCIPsetFreeBufferArray(set, &ub);
8241  SCIPsetFreeBufferArray(set, &lb);
8242  SCIPsetFreeBufferArray(set, &bdind);
8243  SCIPsetFreeBufferArray(set, &obj);
8244  SCIPsetFreeBufferArray(set, &objind);
8245 
8246  return SCIP_OKAY;
8247 }
8248 
8249 /** applies all cached row side changes to the LP */
8250 static
8252  SCIP_LP* lp, /**< current LP data */
8253  SCIP_SET* set /**< global SCIP settings */
8254  )
8255 {
8256 #ifndef NDEBUG
8257  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8258 #endif
8259  SCIP_ROW* row;
8260  int* ind;
8261  SCIP_Real* lhs;
8262  SCIP_Real* rhs;
8263  SCIP_Real lpiinf;
8264  int i;
8265  int nchg;
8266 
8267  assert(lp != NULL);
8268 
8269  if( lp->nchgrows == 0 )
8270  return SCIP_OKAY;
8271 
8272  /* get the solver's infinity value */
8273  lpiinf = SCIPlpiInfinity(lp->lpi);
8274 
8275  /* get temporary memory for changes */
8276  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8277  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8278  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8279 
8280  /* collect all cached left and right hand side changes */
8281  nchg = 0;
8282  for( i = 0; i < lp->nchgrows; ++i )
8283  {
8284  row = lp->chgrows[i];
8285  assert(row != NULL);
8286 
8287  if( row->lpipos >= 0 )
8288  {
8289 #ifndef NDEBUG
8290  /* do not check consistency of data with LPI in case of LPI=none */
8291  if( !lpinone )
8292  {
8293  SCIP_Real lpilhs;
8294  SCIP_Real lpirhs;
8295 
8296  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8297  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8298  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8299  }
8300 #endif
8301  if( row->lhschanged || row->rhschanged )
8302  {
8303  SCIP_Real newlhs;
8304  SCIP_Real newrhs;
8305 
8306  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8307  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8308  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8309  {
8310  assert(nchg < lp->nrows);
8311  ind[nchg] = row->lpipos;
8312  lhs[nchg] = newlhs;
8313  rhs[nchg] = newrhs;
8314  nchg++;
8315  row->flushedlhs = newlhs;
8316  row->flushedrhs = newrhs;
8317  }
8318  row->lhschanged = FALSE;
8319  row->rhschanged = FALSE;
8320  }
8321  }
8322  }
8323 
8324  /* change left and right hand sides in LP */
8325  if( nchg > 0 )
8326  {
8327  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8328  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8329 
8330  /* mark the LP unsolved */
8331  lp->solved = FALSE;
8332  lp->primalfeasible = FALSE;
8333  lp->lpobjval = SCIP_INVALID;
8335  }
8336 
8337  lp->nchgrows = 0;
8338 
8339  /* free temporary memory */
8340  SCIPsetFreeBufferArray(set, &rhs);
8341  SCIPsetFreeBufferArray(set, &lhs);
8342  SCIPsetFreeBufferArray(set, &ind);
8343 
8344  return SCIP_OKAY;
8345 }
8346 
8347 /** copy integrality information to the LP */
8348 static
8350  SCIP_LP* lp, /**< current LP data */
8351  SCIP_SET* set /**< global SCIP settings */
8352  )
8353 {
8354  int i;
8355  int nintegers;
8356  int* integerInfo;
8357  SCIP_VAR* var;
8358 
8359  assert(lp != NULL);
8360 
8361  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8362 
8363  /* count total number of integralities */
8364  nintegers = 0;
8365 
8366  for( i = 0; i < lp->ncols; ++i )
8367  {
8368  var = SCIPcolGetVar(lp->cols[i]);
8369  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8370  {
8371  integerInfo[i] = 1;
8372  ++nintegers;
8373  }
8374  else
8375  integerInfo[i] = 0;
8376  }
8377 
8378  /* only pass integrality information if integer variables are present */
8379  if( nintegers > 0 )
8380  {
8381  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8382  }
8383  else
8384  {
8386  }
8387 
8388  SCIPsetFreeBufferArray(set, &integerInfo);
8389 
8390  /* mark integralities to be updated */
8391  lp->updateintegrality = FALSE;
8392 
8393  return SCIP_OKAY;
8394 }
8395 
8396 /** applies all cached changes to the LP solver */
8398  SCIP_LP* lp, /**< current LP data */
8399  BMS_BLKMEM* blkmem, /**< block memory */
8400  SCIP_SET* set, /**< global SCIP settings */
8401  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8402  )
8403 {
8404  assert(lp != NULL);
8405  assert(blkmem != NULL);
8406 
8407  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",
8408  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8409 
8410  if( !lp->flushed )
8411  {
8412  lp->flushdeletedcols = FALSE;
8413  lp->flushaddedcols = FALSE;
8414  lp->flushdeletedrows = FALSE;
8415  lp->flushaddedrows = FALSE;
8416 
8417  SCIP_CALL( lpFlushDelCols(lp) );
8418  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8419  SCIP_CALL( lpFlushChgCols(lp, set) );
8420  SCIP_CALL( lpFlushChgRows(lp, set) );
8421  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8422  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8423 
8424  lp->flushed = TRUE;
8425 
8426  checkLinks(lp);
8427  }
8428 
8429  assert(lp->nlpicols == lp->ncols);
8430  assert(lp->lpifirstchgcol == lp->nlpicols);
8431  assert(lp->nlpirows == lp->nrows);
8432  assert(lp->lpifirstchgrow == lp->nlpirows);
8433  assert(lp->nchgcols == 0);
8434  assert(lp->nchgrows == 0);
8435 #ifndef NDEBUG
8436  {
8437  int ncols;
8438  int nrows;
8439 
8440  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8441  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8442  assert(ncols == lp->ncols);
8443  assert(nrows == lp->nrows);
8444  }
8445 #endif
8446 
8447  return SCIP_OKAY;
8448 }
8449 
8450 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8452  SCIP_LP* lp, /**< current LP data */
8453  SCIP_SET* set /**< global SCIP settings */
8454  )
8455 {
8456 #ifndef NDEBUG
8457  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8458 #endif
8459  int i;
8460 
8461  assert(lp != NULL);
8462 
8463 #ifndef NDEBUG
8464  /* check, if there are really no column or row deletions or coefficient changes left */
8465  while( lp->lpifirstchgcol < lp->nlpicols
8466  && lp->lpifirstchgcol < lp->ncols
8467  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8468  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8469  {
8470  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8471  lp->lpifirstchgcol++;
8472  }
8473  assert(lp->nlpicols == lp->lpifirstchgcol);
8474 
8475  while( lp->lpifirstchgrow < lp->nlpirows
8476  && lp->lpifirstchgrow < lp->nrows
8477  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8478  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8479  {
8480  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8481  lp->lpifirstchgrow++;
8482  }
8483  assert(lp->nlpirows == lp->lpifirstchgrow);
8484 #endif
8485 
8486  lp->lpifirstchgcol = lp->nlpicols;
8487  lp->lpifirstchgrow = lp->nlpirows;
8488 
8489  /* check, if there are really no column or row additions left */
8490  assert(lp->ncols == lp->nlpicols);
8491  assert(lp->nrows == lp->nlpirows);
8492 
8493  /* mark the changed columns to be unchanged, and check, if this is really correct */
8494  for( i = 0; i < lp->nchgcols; ++i )
8495  {
8496  SCIP_COL* col;
8497 
8498  col = lp->chgcols[i];
8499  assert(col != NULL);
8500  assert(col->var != NULL);
8501  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8502  assert(SCIPvarGetCol(col->var) == col);
8503 
8504  if( col->lpipos >= 0 )
8505  {
8506 #ifndef NDEBUG
8507  /* do not check consistency of data with LPI in case of LPI=none */
8508  if( !lpinone )
8509  {
8510  SCIP_Real lpiobj;
8511  SCIP_Real lpilb;
8512  SCIP_Real lpiub;
8513 
8514  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8515  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8516  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8517  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8518  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8519  assert(col->flushedobj == col->obj); /*lint !e777*/
8520  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8521  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8522  }
8523 #endif
8524  col->objchanged = FALSE;
8525  col->lbchanged = FALSE;
8526  col->ubchanged = FALSE;
8527  }
8528  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8529  }
8530  lp->nchgcols = 0;
8531 
8532  /* mark the changed rows to be unchanged, and check, if this is really correct */
8533  for( i = 0; i < lp->nchgrows; ++i )
8534  {
8535  SCIP_ROW* row;
8536 
8537  row = lp->chgrows[i];
8538  assert(row != NULL);
8539 
8540  if( row->lpipos >= 0 )
8541  {
8542 #ifndef NDEBUG
8543  /* do not check consistency of data with LPI in case of LPI=none */
8544  if( !lpinone )
8545  {
8546  SCIP_Real lpilhs;
8547  SCIP_Real lpirhs;
8548 
8549  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8550  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8551  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8552  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8553  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8554  }
8555 #endif
8556  row->lhschanged = FALSE;
8557  row->rhschanged = FALSE;
8558  }
8559  }
8560  lp->nchgrows = 0;
8561 
8562  /* mark the LP to be flushed */
8563  lp->flushed = TRUE;
8564 
8565  checkLinks(lp);
8566 
8567  return SCIP_OKAY;
8568 }
8569 
8570 
8571 
8572 
8573 /*
8574  * LP methods
8575  */
8576 
8577 /** updates link data after addition of column */
8578 static
8580  SCIP_COL* col, /**< LP column */
8581  SCIP_SET* set /**< global SCIP settings */
8582  )
8583 {
8584  SCIP_ROW* row;
8585  int i;
8586  int pos;
8587 
8588  assert(col != NULL);
8589  assert(col->lppos >= 0);
8590 
8591  /* update column arrays of all linked rows */
8592  for( i = 0; i < col->len; ++i )
8593  {
8594  pos = col->linkpos[i];
8595  if( pos >= 0 )
8596  {
8597  row = col->rows[i];
8598  assert(row != NULL);
8599  assert(row->linkpos[pos] == i);
8600  assert(row->cols[pos] == col);
8601  assert(row->nlpcols <= pos && pos < row->len);
8602 
8603  row->nlpcols++;
8604  rowSwapCoefs(row, pos, row->nlpcols-1);
8605  assert(row->cols[row->nlpcols-1] == col);
8606 
8607  /* if no swap was necessary, mark lpcols to be unsorted */
8608  if( pos == row->nlpcols-1 )
8609  row->lpcolssorted = FALSE;
8610 
8611  /* update norms */
8612  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8613  }
8614  }
8615 }
8616 
8617 /** updates link data after addition of row */
8618 static
8620  SCIP_ROW* row /**< LP row */
8621  )
8622 {
8623  SCIP_COL* col;
8624  int i;
8625  int pos;
8626 
8627  assert(row != NULL);
8628  assert(row->lppos >= 0);
8629 
8630  /* update row arrays of all linked columns */
8631  for( i = 0; i < row->len; ++i )
8632  {
8633  pos = row->linkpos[i];
8634  if( pos >= 0 )
8635  {
8636  col = row->cols[i];
8637  assert(col != NULL);
8638  assert(col->linkpos[pos] == i);
8639  assert(col->rows[pos] == row);
8640  assert(col->nlprows <= pos && pos < col->len);
8641 
8642  col->nlprows++;
8643  colSwapCoefs(col, pos, col->nlprows-1);
8644 
8645  /* if no swap was necessary, mark lprows to be unsorted */
8646  if( pos == col->nlprows-1 )
8647  col->lprowssorted = FALSE;
8648  }
8649  }
8650 }
8651 
8652 /** updates link data after removal of column */
8653 static
8655  SCIP_COL* col, /**< LP column */
8656  SCIP_SET* set /**< global SCIP settings */
8657  )
8658 {
8659  SCIP_ROW* row;
8660  int i;
8661  int pos;
8662 
8663  assert(col != NULL);
8664  assert(col->lppos == -1);
8665 
8666  /* update column arrays of all linked rows */
8667  for( i = 0; i < col->len; ++i )
8668  {
8669  pos = col->linkpos[i];
8670  if( pos >= 0 )
8671  {
8672  row = col->rows[i];
8673  assert(row != NULL);
8674  assert(row->linkpos[pos] == i);
8675  assert(row->cols[pos] == col);
8676  assert(0 <= pos && pos < row->nlpcols);
8677 
8678  /* update norms */
8679  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8680 
8681  row->nlpcols--;
8682  rowSwapCoefs(row, pos, row->nlpcols);
8683 
8684  /* if no swap was necessary, mark nonlpcols to be unsorted */
8685  if( pos == row->nlpcols )
8686  row->nonlpcolssorted = FALSE;
8687  }
8688  }
8689 }
8690 
8691 /** updates link data after removal of row */
8692 static
8694  SCIP_ROW* row /**< LP row */
8695  )
8696 {
8697  SCIP_COL* col;
8698  int i;
8699  int pos;
8700 
8701  assert(row != NULL);
8702  assert(row->lppos == -1);
8703 
8704  /* update row arrays of all linked columns */
8705  for( i = 0; i < row->len; ++i )
8706  {
8707  pos = row->linkpos[i];
8708  if( pos >= 0 )
8709  {
8710  col = row->cols[i];
8711  assert(col != NULL);
8712  assert(0 <= pos && pos < col->nlprows);
8713  assert(col->linkpos[pos] == i);
8714  assert(col->rows[pos] == row);
8715 
8716  col->nlprows--;
8717  colSwapCoefs(col, pos, col->nlprows);
8718 
8719  /* if no swap was necessary, mark lprows to be unsorted */
8720  if( pos == col->nlprows )
8721  col->nonlprowssorted = FALSE;
8722  }
8723  }
8724 }
8725 
8726 static
8728  SCIP_LP* lp, /**< LP data object */
8729  int initsize /**< initial size of the arrays */
8730  )
8731 {
8732  assert(lp != NULL);
8733  assert(lp->divechgsides == NULL);
8734  assert(lp->divechgsidetypes == NULL);
8735  assert(lp->divechgrows == NULL);
8736  assert(lp->ndivechgsides == 0);
8737  assert(lp->divechgsidessize == 0);
8738  assert(initsize > 0);
8739 
8740  lp->divechgsidessize = initsize;
8744 
8745  return SCIP_OKAY;
8746 }
8747 
8748 static
8750  SCIP_LP* lp, /**< LP data object */
8751  int minsize, /**< minimal number of elements */
8752  SCIP_Real growfact /**< growing factor */
8753  )
8754 {
8755  assert(lp != NULL);
8756  assert(lp->divechgsides != NULL);
8757  assert(lp->divechgsidetypes != NULL);
8758  assert(lp->divechgrows != NULL);
8759  assert(lp->ndivechgsides > 0);
8760  assert(lp->divechgsidessize > 0);
8761  assert(minsize > 0);
8762 
8763  if( minsize <= lp->divechgsidessize )
8764  return SCIP_OKAY;
8765 
8766  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
8770 
8771  return SCIP_OKAY;
8772 }
8773 
8774 static
8776  SCIP_LP* lp /**< LP data object */
8777  )
8778 {
8779  assert(lp != NULL);
8780  assert(lp->divechgsides != NULL);
8781  assert(lp->divechgsidetypes != NULL);
8782  assert(lp->divechgrows != NULL);
8783  assert(lp->ndivechgsides == 0);
8784  assert(lp->divechgsidessize > 0);
8785 
8789  lp->divechgsidessize = 0;
8790 }
8791 
8792 #define DIVESTACKINITSIZE 100
8793 
8794 /** creates empty LP data object */
8796  SCIP_LP** lp, /**< pointer to LP data object */
8797  SCIP_SET* set, /**< global SCIP settings */
8798  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
8799  SCIP_STAT* stat, /**< problem statistics */
8800  const char* name /**< problem name */
8801  )
8802 {
8803  SCIP_Bool success;
8804 
8805  assert(lp != NULL);
8806  assert(set != NULL);
8807  assert(stat != NULL);
8808  assert(name != NULL);
8809 
8810  SCIP_ALLOC( BMSallocMemory(lp) );
8811 
8812  /* open LP Solver interface */
8813  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
8814 
8815  (*lp)->lpicols = NULL;
8816  (*lp)->lpirows = NULL;
8817  (*lp)->chgcols = NULL;
8818  (*lp)->chgrows = NULL;
8819  (*lp)->cols = NULL;
8820  (*lp)->lazycols = NULL;
8821  (*lp)->rows = NULL;
8822  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
8823  (*lp)->lpobjval = 0.0;
8824  (*lp)->glbpseudoobjval = 0.0;
8825  (*lp)->relglbpseudoobjval = 0.0;
8826  (*lp)->glbpseudoobjvalid = TRUE;
8827  (*lp)->glbpseudoobjvalinf = 0;
8828  (*lp)->pseudoobjval = 0.0;
8829  (*lp)->relpseudoobjval = 0.0;
8830  (*lp)->pseudoobjvalid = TRUE;
8831  (*lp)->pseudoobjvalinf = 0;
8832  (*lp)->looseobjval = 0.0;
8833  (*lp)->rellooseobjval = 0.0;
8834  (*lp)->looseobjvalid = TRUE;
8835  (*lp)->looseobjvalinf = 0;
8836  (*lp)->nloosevars = 0;
8837  (*lp)->rootlpobjval = SCIP_INVALID;
8838  (*lp)->rootlooseobjval = SCIP_INVALID;
8839  (*lp)->cutoffbound = SCIPsetInfinity(set);
8840  (*lp)->objsqrnorm = 0.0;
8841  (*lp)->objsumnorm = 0.0;
8842  (*lp)->lpicolssize = 0;
8843  (*lp)->nlpicols = 0;
8844  (*lp)->lpirowssize = 0;
8845  (*lp)->nlpirows = 0;
8846  (*lp)->lpifirstchgcol = 0;
8847  (*lp)->lpifirstchgrow = 0;
8848  (*lp)->colssize = 0;
8849  (*lp)->ncols = 0;
8850  (*lp)->lazycolssize = 0;
8851  (*lp)->nlazycols = 0;
8852  (*lp)->rowssize = 0;
8853  (*lp)->nrows = 0;
8854  (*lp)->chgcolssize = 0;
8855  (*lp)->nchgcols = 0;
8856  (*lp)->chgrowssize = 0;
8857  (*lp)->nchgrows = 0;
8858  (*lp)->firstnewcol = 0;
8859  (*lp)->firstnewrow = 0;
8860  (*lp)->nremovablecols = 0;
8861  (*lp)->nremovablerows = 0;
8862  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
8863  (*lp)->validfarkaslp = -1;
8864  (*lp)->objsqrnormunreliable = FALSE;
8865  (*lp)->flushdeletedcols = FALSE;
8866  (*lp)->flushaddedcols = FALSE;
8867  (*lp)->flushdeletedrows = FALSE;
8868  (*lp)->flushaddedrows = FALSE;
8869  (*lp)->updateintegrality = TRUE;
8870  (*lp)->flushed = TRUE;
8871  (*lp)->solved = TRUE;
8872  (*lp)->primalfeasible = TRUE;
8873  (*lp)->dualfeasible = TRUE;
8874  (*lp)->solisbasic = FALSE;
8875  (*lp)->rootlpisrelax = TRUE;
8876  (*lp)->isrelax = TRUE;
8877  (*lp)->installing = FALSE;
8878  (*lp)->strongbranching = FALSE;
8879  (*lp)->strongbranchprobing = FALSE;
8880  (*lp)->probing = FALSE;
8881  (*lp)->diving = FALSE;
8882  (*lp)->divingobjchg = FALSE;
8883  (*lp)->divinglazyapplied = FALSE;
8884  (*lp)->divelpistate = NULL;
8885  (*lp)->divelpwasprimfeas = TRUE;
8886  (*lp)->divelpwasdualfeas = TRUE;
8887  (*lp)->divechgsides = NULL;
8888  (*lp)->divechgsidetypes = NULL;
8889  (*lp)->divechgrows = NULL;
8890  (*lp)->ndivechgsides = 0;
8891  (*lp)->divechgsidessize = 0;
8892  (*lp)->ndivingrows = 0;
8893  (*lp)->divinglpiitlim = INT_MAX;
8894  (*lp)->resolvelperror = FALSE;
8895  (*lp)->adjustlpval = FALSE;
8896  (*lp)->lpiuobjlim = SCIPlpiInfinity((*lp)->lpi);
8897  (*lp)->lpifeastol = SCIPsetLpfeastol(set);
8898  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
8899  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
8900  (*lp)->lpifromscratch = FALSE;
8901  (*lp)->lpifastmip = set->lp_fastmip;
8902  (*lp)->lpiscaling = set->lp_scaling;
8903  (*lp)->lpipresolving = set->lp_presolving;
8904  (*lp)->lpilpinfo = set->disp_lpinfo;
8905  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
8906  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
8907  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
8908  (*lp)->lpiitlim = INT_MAX;
8909  (*lp)->lpipricing = SCIP_PRICING_AUTO;
8910  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
8911  (*lp)->lpithreads = set->lp_threads;
8912  (*lp)->lpitiming = (int) set->time_clocktype;
8913  (*lp)->lpirandomseed = set->random_randomseed;
8914  (*lp)->storedsolvals = NULL;
8915 
8916  /* allocate arrays for diving */
8918 
8919  /* set default parameters in LP solver */
8920  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_UOBJLIM, (*lp)->lpiuobjlim, &success) );
8921  if( !success )
8922  {
8923  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8924  "LP Solver <%s>: upper objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
8926  }
8927  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
8928  (*lp)->lpihasfeastol = success;
8929  if( !success )
8930  {
8931  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8932  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8934  }
8935  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
8936  (*lp)->lpihasdualfeastol = success;
8937  if( !success )
8938  {
8939  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8940  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8942  }
8943  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
8944  (*lp)->lpihasbarrierconvtol = success;
8945  if( !success )
8946  {
8947  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8948  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8950  }
8951  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
8952  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
8953  (*lp)->lpihasfastmip = success;
8954  if( !success )
8955  {
8956  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8957  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
8959  }
8960  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
8961  (*lp)->lpihasscaling = success;
8962  if( !success )
8963  {
8964  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8965  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
8967  }
8968  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
8969  (*lp)->lpihaspresolving = success;
8970  if( !success )
8971  {
8972  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8973  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
8975  }
8976  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
8977  if( !success )
8978  {
8979  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8980  "LP Solver <%s>: clock type cannot be set\n",
8982  }
8983  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
8984  if( !success )
8985  {
8986  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8987  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
8989  }
8990  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
8991  if( !success )
8992  {
8993  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8994  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
8996  }
8997  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
8998  if( !success )
8999  {
9000  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9001  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9003  }
9004  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9005  (*lp)->lpihasrowrep = success;
9006  if( !success )
9007  {
9008  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9009  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9011  }
9012  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9013  (*lp)->lpihaspolishing = success;
9014  if( !success )
9015  {
9016  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9017  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9019  }
9020  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9021  if( !success )
9022  {
9023  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9024  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9026  }
9027  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9028  if( !success )
9029  {
9030  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9031  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9033  }
9034  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9035  if( (*lp)->lpirandomseed != 0 )
9036  {
9037  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9038  if( !success )
9039  {
9040  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9041  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9043  }
9044  }
9045 
9046  return SCIP_OKAY;
9047 }
9048 
9049 /** frees LP data object */
9051  SCIP_LP** lp, /**< pointer to LP data object */
9052  BMS_BLKMEM* blkmem, /**< block memory */
9053  SCIP_SET* set, /**< global SCIP settings */
9054  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9055  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9056  )
9057 {
9058  int i;
9059 
9060  assert(lp != NULL);
9061  assert(*lp != NULL);
9062 
9063  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9064 
9065  freeDiveChgSideArrays(*lp);
9066 
9067  /* release LPI rows */
9068  for( i = 0; i < (*lp)->nlpirows; ++i )
9069  {
9070  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9071  }
9072 
9073  if( (*lp)->lpi != NULL )
9074  {
9075  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9076  }
9077 
9078  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9079  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9080  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9081  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9082  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9083  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9084  BMSfreeMemoryArrayNull(&(*lp)->cols);
9085  BMSfreeMemoryArrayNull(&(*lp)->rows);
9086  BMSfreeMemory(lp);
9087 
9088  return SCIP_OKAY;
9089 }
9090 
9091 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9092  * changes to the LP solver
9093  */
9095  SCIP_LP* lp, /**< LP data */
9096  BMS_BLKMEM* blkmem, /**< block memory */
9097  SCIP_SET* set, /**< global SCIP settings */
9098  SCIP_STAT* stat, /**< problem statistics */
9099  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9100  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9101  )
9102 {
9103  assert(stat != NULL);
9104 
9105  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9106  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9107 
9108  /* mark the empty LP to be solved */
9110  lp->lpobjval = 0.0;
9111  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9112  lp->validfarkaslp = -1;
9113  lp->solved = TRUE;
9114  lp->primalfeasible = TRUE;
9115  lp->dualfeasible = TRUE;
9116  lp->solisbasic = FALSE;
9118 
9119  return SCIP_OKAY;
9120 }
9121 
9122 /** adds a column to the LP */
9124  SCIP_LP* lp, /**< LP data */
9125  SCIP_SET* set, /**< global SCIP settings */
9126  SCIP_COL* col, /**< LP column */
9127  int depth /**< depth in the tree where the column addition is performed */
9128  )
9129 {
9130  assert(lp != NULL);
9131  assert(!lp->diving);
9132  assert(col != NULL);
9133  assert(col->len == 0 || col->rows != NULL);
9134  assert(col->lppos == -1);
9135  assert(col->var != NULL);
9136  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9137  assert(SCIPvarGetCol(col->var) == col);
9138  assert(SCIPvarIsIntegral(col->var) == col->integral);
9139 
9140  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9141 #ifdef SCIP_DEBUG
9142  {
9143  int i;
9144  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9145  for( i = 0; i < col->len; ++i )
9146  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9147  SCIPsetDebugMsgPrint(set, "\n");
9148  }
9149 #endif
9150 
9151  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9152  lp->cols[lp->ncols] = col;
9153  col->lppos = lp->ncols;
9154  col->lpdepth = depth;
9155  col->age = 0;
9156  lp->ncols++;
9157  if( col->removable )
9158  lp->nremovablecols++;
9159 
9160  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9161  {
9162  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9163  lp->lazycols[lp->nlazycols] = col;
9164  lp->nlazycols++;
9165  }
9166 
9167  /* mark the current LP unflushed */
9168  lp->flushed = FALSE;
9169 
9170  /* update column arrays of all linked rows */
9171  colUpdateAddLP(col, set);
9172 
9173  /* update the objective function vector norms */
9174  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9175 
9176  checkLinks(lp);
9177 
9178  return SCIP_OKAY;
9179 }
9180 
9181 /** adds a row to the LP and captures it */
9183  SCIP_LP* lp, /**< LP data */
9184  BMS_BLKMEM* blkmem, /**< block memory buffers */
9185  SCIP_SET* set, /**< global SCIP settings */
9186  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9187  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9188  SCIP_ROW* row, /**< LP row */
9189  int depth /**< depth in the tree where the row addition is performed */
9190  )
9191 {
9192  assert(lp != NULL);
9193  assert(row != NULL);
9194  assert(row->len == 0 || row->cols != NULL);
9195  assert(row->lppos == -1);
9196 
9197  SCIProwCapture(row);
9198  SCIProwLock(row);
9199 
9200  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9201 #ifdef SCIP_DEBUG
9202  {
9203  int i;
9204  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9205  for( i = 0; i < row->len; ++i )
9206  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9207  if( !SCIPsetIsZero(set, row->constant) )
9208  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9209  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9210  }
9211 #endif
9212 
9213  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9214  lp->rows[lp->nrows] = row;
9215  row->lppos = lp->nrows;
9216  row->lpdepth = depth;
9217  row->age = 0;
9218  lp->nrows++;
9219  if( row->removable )
9220  lp->nremovablerows++;
9221 
9222  /* mark the current LP unflushed */
9223  lp->flushed = FALSE;
9224 
9225  /* update row arrays of all linked columns */
9226  rowUpdateAddLP(row);
9227 
9228  checkLinks(lp);
9229 
9230  rowCalcNorms(row, set);
9231 
9232  /* check, if row addition to LP events are tracked
9233  * if so, issue ROWADDEDLP event
9234  */
9235  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9236  {
9237  SCIP_EVENT* event;
9238 
9239  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9240  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9241  }
9242 
9243  return SCIP_OKAY;
9244 }
9245 
9246 
9247 #ifndef NDEBUG
9248 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9249  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9250  * the lazycols array
9251  */
9252 static
9254  SCIP_LP* lp, /**< LP data */
9255  SCIP_SET* set /**< global SCIP settings */
9256  )
9257 {
9258  SCIP_Bool contained;
9259  int c;
9260  int i;
9261 
9262  assert(lp != NULL);
9263 
9264  /* check if each column in the lazy column array has a counter part in the column array */
9265  for( i = 0; i < lp->nlazycols; ++i )
9266  {
9267  /* check if each lazy column has at least on lazy bound */
9268  assert(lp->lazycols[i] != NULL);
9269  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9270 
9271  contained = FALSE;
9272  for( c = 0; c < lp->ncols; ++c )
9273  {
9274  if( lp->lazycols[i] == lp->cols[c] )
9275  {
9276  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9277  contained = TRUE;
9278  }
9279  }
9280  assert(contained);
9281  }
9282 
9283  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9284  * array */
9285  for( c = 0; c < lp->ncols; ++c )
9286  {
9287  contained = FALSE;
9288  assert(lp->cols[c] != NULL);
9289 
9290  for( i = 0; i < lp->nlazycols; ++i )
9291  {
9292  if( lp->lazycols[i] == lp->cols[c] )
9293  {
9294  contained = TRUE;
9295  }
9296  }
9297 
9298  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9299  }
9300 }
9301 #else
9302 #define checkLazyColArray(lp, set) /**/
9303 #endif
9304 
9305 /** removes all columns after the given number of cols from the LP */
9307  SCIP_LP* lp, /**< LP data */
9308  SCIP_SET* set, /**< global SCIP settings */
9309  int newncols /**< new number of columns in the LP */
9310  )
9311 {
9312  SCIP_COL* col;
9313  int c;
9314 
9315  assert(lp != NULL);
9316 
9317  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9318  assert(0 <= newncols);
9319  assert(newncols <= lp->ncols);
9320 
9321  if( newncols < lp->ncols )
9322  {
9323  assert(!lp->diving);
9324 
9325  for( c = lp->ncols-1; c >= newncols; --c )
9326  {
9327  col = lp->cols[c];
9328  assert(col != NULL);
9329  assert(col->len == 0 || col->rows != NULL);
9330  assert(col->var != NULL);
9331  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9332  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9333  assert(col->lppos == c);
9334 
9335  /* mark column to be removed from the LP */
9336  col->lppos = -1;
9337  col->lpdepth = -1;
9338  lp->ncols--;
9339 
9340  /* count removable columns */
9341  if( col->removable )
9342  lp->nremovablecols--;
9343 
9344  /* update column arrays of all linked rows */
9345  colUpdateDelLP(col, set);
9346 
9347  /* update the objective function vector norms */
9348  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9349  }
9350  assert(lp->ncols == newncols);
9351  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9352 
9353  /* remove columns which are deleted from the lazy column array */
9354  c = 0;
9355  while( c < lp->nlazycols )
9356  {
9357  if( lp->lazycols[c]->lppos < 0 )
9358  {
9359  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9360  lp->nlazycols--;
9361  }
9362  else
9363  c++;
9364  }
9365 
9366  /* mark the current LP unflushed */
9367  lp->flushed = FALSE;
9368 
9369  checkLazyColArray(lp, set);
9370  checkLinks(lp);
9371  }
9372  assert(lp->nremovablecols <= lp->ncols);
9373 
9374  return SCIP_OKAY;
9375 }
9376 
9377 /** removes and releases all rows after the given number of rows from the LP */
9379  SCIP_LP* lp, /**< LP data */
9380  BMS_BLKMEM* blkmem, /**< block memory */
9381  SCIP_SET* set, /**< global SCIP settings */
9382  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9383  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9384  int newnrows /**< new number of rows in the LP */
9385  )
9386 {
9387  SCIP_ROW* row;
9388  int r;
9389 
9390  assert(lp != NULL);
9391  assert(0 <= newnrows && newnrows <= lp->nrows);
9392 
9393  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9394  if( newnrows < lp->nrows )
9395  {
9396  for( r = lp->nrows-1; r >= newnrows; --r )
9397  {
9398  row = lp->rows[r];
9399  assert(row != NULL);
9400  assert(row->len == 0 || row->cols != NULL);
9401  assert(row->lppos == r);
9402 
9403  /* mark row to be removed from the LP */
9404  row->lppos = -1;
9405  row->lpdepth = -1;
9406  lp->nrows--;
9407 
9408  /* count removable rows */
9409  if( row->removable )
9410  lp->nremovablerows--;
9411 
9412  /* update row arrays of all linked columns */
9413  rowUpdateDelLP(row);
9414 
9415  SCIProwUnlock(lp->rows[r]);
9416 
9417  /* check, if row deletion events are tracked
9418  * if so, issue ROWDELETEDLP event
9419  */
9420  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9421  {
9422  SCIP_EVENT* event;
9423 
9424  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9425  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9426  }
9427 
9428  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9429  }
9430  assert(lp->nrows == newnrows);
9431  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9432 
9433  /* mark the current LP unflushed */
9434  lp->flushed = FALSE;
9435 
9436  checkLinks(lp);
9437  }
9438  assert(lp->nremovablerows <= lp->nrows);
9439 
9440  return SCIP_OKAY;
9441 }
9442 
9443 /** removes all columns and rows from LP, releases all rows */
9445  SCIP_LP* lp, /**< LP data */
9446  BMS_BLKMEM* blkmem, /**< block memory */
9447  SCIP_SET* set, /**< global SCIP settings */
9448  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9449  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9450  )
9451 {
9452  assert(lp != NULL);
9453  assert(!lp->diving);
9454 
9455  SCIPsetDebugMsg(set, "clearing LP\n");
9456  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9457  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9458 
9459  return SCIP_OKAY;
9460 }
9461 
9462 /** remembers number of columns and rows to track the newly added ones */
9464  SCIP_LP* lp /**< current LP data */
9465  )
9466 {
9467  assert(lp != NULL);
9468  assert(!lp->diving);
9469 
9470  lp->firstnewrow = lp->nrows;
9471  lp->firstnewcol = lp->ncols;
9472 }
9473 
9474 /** sets the remembered number of columns and rows to the given values */
9476  SCIP_LP* lp, /**< current LP data */
9477  int nrows, /**< number of rows to set the size marker to */
9478  int ncols /**< number of columns to set the size marker to */
9479  )
9480 {
9481  assert(lp != NULL);
9482  assert(!lp->diving);
9483 
9484  lp->firstnewrow = nrows;
9485  lp->firstnewcol = ncols;
9486 }
9487 
9488 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9490  SCIP_LP* lp, /**< LP data */
9491  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9492  )
9493 {
9494  assert(lp != NULL);
9495  assert(lp->flushed);
9496  assert(lp->solved);
9497  assert(lp->solisbasic);
9498  assert(basisind != NULL);
9499 
9500  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9501 
9502  return SCIP_OKAY;
9503 }
9504 
9505 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9507  SCIP_LP* lp, /**< LP data */
9508  int* cstat, /**< array to store column basis status, or NULL */
9509  int* rstat /**< array to store row basis status, or NULL */
9510  )
9511 {
9512  assert(lp != NULL);
9513  assert(lp->flushed);
9514  assert(lp->solved);
9515  assert(lp->solisbasic);
9516 
9517  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9518 
9519  return SCIP_OKAY;
9520 }
9521 
9522 /** gets a row from the inverse basis matrix B^-1 */
9524  SCIP_LP* lp, /**< LP data */
9525  int r, /**< row number */
9526  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9527  int* inds, /**< array to store the non-zero indices, or NULL */
9528  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9529  * (-1: if we do not store sparsity informations) */
9530  )
9531 {
9532  assert(lp != NULL);
9533  assert(lp->flushed);
9534  assert(lp->solved);
9535  assert(lp->solisbasic);
9536  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9537  assert(coef != NULL);
9538 
9539  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9540 
9541  return SCIP_OKAY;
9542 }
9543 
9544 /** gets a column from the inverse basis matrix B^-1 */
9546  SCIP_LP* lp, /**< LP data */
9547  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9548  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9549  * to get the array which links the B^-1 column numbers to the row and
9550  * column numbers of the LP! c must be between 0 and nrows-1, since the
9551  * basis has the size nrows * nrows */
9552  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9553  int* inds, /**< array to store the non-zero indices, or NULL */
9554  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9555  * (-1: if we do not store sparsity informations) */
9556  )
9557 {
9558  assert(lp != NULL);
9559  assert(lp->flushed);
9560  assert(lp->solved);
9561  assert(lp->solisbasic);
9562  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9563  assert(coef != NULL);
9564 
9565  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9566 
9567  return SCIP_OKAY;
9568 }
9569 
9570 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9572  SCIP_LP* lp, /**< LP data */
9573  int r, /**< row number */
9574  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9575  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9576  int* inds, /**< array to store the non-zero indices, or NULL */
9577  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9578  * (-1: if we do not store sparsity informations) */
9579  )
9580 {
9581  assert(lp != NULL);
9582  assert(lp->flushed);
9583  assert(lp->solved);
9584  assert(lp->solisbasic);
9585  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9586  assert(coef != NULL);
9587 
9588  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9589 
9590  return SCIP_OKAY;
9591 }
9592 
9593 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9594  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9595  */
9597  SCIP_LP* lp, /**< LP data */
9598  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9599  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9600  int* inds, /**< array to store the non-zero indices, or NULL */
9601  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9602  * (-1: if we do not store sparsity informations) */
9603  )
9604 {
9605  assert(lp != NULL);
9606  assert(lp->flushed);
9607  assert(lp->solved);
9608  assert(lp->solisbasic);
9609  assert(0 <= c && c < lp->ncols);
9610  assert(coef != NULL);
9611 
9612  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9613 
9614  return SCIP_OKAY;
9615 }
9616 
9617 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9618  * LP row are swapped in the summation
9619  */
9621  SCIP_LP* lp, /**< LP data */
9622  SCIP_SET* set, /**< global SCIP settings */
9623  SCIP_PROB* prob, /**< problem data */
9624  SCIP_Real* weights, /**< row weights in row summation */
9625  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9626  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9627  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9628  )
9629 {
9630  SCIP_ROW* row;
9631  int r;
9632  int i;
9633  int idx;
9634  SCIP_Bool lhsinfinite;
9635  SCIP_Bool rhsinfinite;
9636 
9637  assert(lp != NULL);
9638  assert(prob != NULL);
9639  assert(weights != NULL);
9640  assert(sumcoef != NULL);
9641  assert(sumlhs != NULL);
9642  assert(sumrhs != NULL);
9643 
9644  /**@todo test, if a column based summation is faster */
9645 
9646  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9647  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9648  *sumlhs = 0.0;
9649  *sumrhs = 0.0;
9650  lhsinfinite = FALSE;
9651  rhsinfinite = FALSE;
9652  for( r = 0; r < lp->nrows; ++r )
9653  {
9654  if( !SCIPsetIsZero(set, weights[r]) )
9655  {
9656  row = lp->rows[r];
9657  assert(row != NULL);
9658  assert(row->len == 0 || row->cols != NULL);
9659  assert(row->len == 0 || row->cols_index != NULL);
9660  assert(row->len == 0 || row->vals != NULL);
9661 
9662  /* add the row coefficients to the sum */
9663  for( i = 0; i < row->len; ++i )
9664  {
9665  assert(row->cols[i] != NULL);
9666  assert(row->cols[i]->var != NULL);
9667  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9668  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9669  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9670  idx = row->cols[i]->var_probindex;
9671  assert(0 <= idx && idx < prob->nvars);
9672  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9673  }
9674 
9675  /* add the row sides to the sum, depending on the sign of the weight */
9676  if( weights[r] > 0.0 )
9677  {
9678  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9679  if( !lhsinfinite )
9680  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9681  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9682  if( !rhsinfinite )
9683  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9684  }
9685  else
9686  {
9687  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9688  if( !lhsinfinite )
9689  (*sumlhs) += weights[r] * (row->rhs - row->constant);
9690  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9691  if( !rhsinfinite )
9692  (*sumrhs) += weights[r] * (row->lhs - row->constant);
9693  }
9694  }
9695  }
9696 
9697  if( lhsinfinite )
9698  *sumlhs = -SCIPsetInfinity(set);
9699  if( rhsinfinite )
9700  *sumrhs = SCIPsetInfinity(set);
9701 
9702  return SCIP_OKAY;
9703 }
9704 
9705 /** stores LP state (like basis information) into LP state object */
9707  SCIP_LP* lp, /**< LP data */
9708  BMS_BLKMEM* blkmem, /**< block memory */
9709  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9710  )
9711 {
9712  assert(lp != NULL);
9713  assert(lp->flushed);
9714  assert(lp->solved);
9715  assert(blkmem != NULL);
9716  assert(lpistate != NULL);
9717 
9718  /* check whether there is no lp */
9719  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9720  *lpistate = NULL;
9721  else
9722  {
9723  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
9724  }
9725 
9726  return SCIP_OKAY;
9727 }
9728 
9729 /** loads LP state (like basis information) into solver */
9731  SCIP_LP* lp, /**< LP data */
9732  BMS_BLKMEM* blkmem, /**< block memory */
9733  SCIP_SET* set, /**< global SCIP settings */
9734  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9735  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
9736  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
9737  SCIP_Bool wasdualfeas /**< dual feasibility when LP state information was stored */
9738  )
9739 {
9740  assert(lp != NULL);
9741  assert(blkmem != NULL);
9742 
9743  /* flush changes to the LP solver */
9744  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9745  assert(lp->flushed);
9746 
9747  if( lp->solved && lp->solisbasic )
9748  return SCIP_OKAY;
9749 
9750  /* set LPI state in the LP solver */
9751  if( lpistate == NULL )
9752  lp->solisbasic = FALSE;
9753  else
9754  {
9755  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
9756  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
9757  }
9758  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
9759  * flushed and solved, also, e.g., when we hit the iteration limit
9760  */
9761  lp->primalfeasible = wasprimfeas;
9762  lp->dualfeasible = wasdualfeas;
9763 
9764  return SCIP_OKAY;
9765 }
9766 
9767 /** frees LP state information */
9769  SCIP_LP* lp, /**< LP data */
9770  BMS_BLKMEM* blkmem, /**< block memory */
9771  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9772  )
9773 {
9774  assert(lp != NULL);
9775 
9776  if( *lpistate != NULL )
9777  {
9778  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
9779  }
9780 
9781  return SCIP_OKAY;
9782 }
9783 
9784 /** stores pricing norms into LP norms object */
9786  SCIP_LP* lp, /**< LP data */
9787  BMS_BLKMEM* blkmem, /**< block memory */
9788  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9789  )
9790 {
9791  assert(lp != NULL);
9792  assert(lp->flushed);
9793  assert(lp->solved);
9794  assert(blkmem != NULL);
9795  assert(lpinorms != NULL);
9796 
9797  /* check whether there is no lp */
9798  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9799  *lpinorms = NULL;
9800  else
9801  {
9802  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
9803  }
9804 
9805  return SCIP_OKAY;
9806 }
9807 
9808 /** loads pricing norms from LP norms object into solver */
9810  SCIP_LP* lp, /**< LP data */
9811  BMS_BLKMEM* blkmem, /**< block memory */
9812  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
9813  )
9814 {
9815  assert(lp != NULL);
9816  assert(blkmem != NULL);
9817  assert(lp->flushed);
9818 
9819  /* set LPI norms in the LP solver */
9820  if( lpinorms != NULL )
9821  {
9822  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
9823  }
9824 
9825  return SCIP_OKAY;
9826 }
9827 
9828 /** frees pricing norms information */
9830  SCIP_LP* lp, /**< LP data */
9831  BMS_BLKMEM* blkmem, /**< block memory */
9832  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9833  )
9834 {
9835  assert(lp != NULL);
9836 
9837  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
9838 
9839  return SCIP_OKAY;
9840 }
9841 
9842 /** return the current cutoff bound of the lp */
9844  SCIP_LP* lp /**< current LP data */
9845  )
9846 {
9847  assert(lp != NULL);
9848 
9849  return lp->cutoffbound;
9850 }
9851 
9852 /** sets the upper objective limit of the LP solver */
9854  SCIP_LP* lp, /**< current LP data */
9855  SCIP_SET* set, /**< global SCIP settings */
9856  SCIP_PROB* prob, /**< problem data */
9857  SCIP_Real cutoffbound /**< new upper objective limit */
9858  )
9859 {
9860  assert(lp != NULL);
9861 
9862  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
9863 
9864  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
9865  * in SCIPendDive())
9866  */
9867  if( SCIPlpDivingObjChanged(lp) )
9868  {
9869  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
9870  return SCIP_OKAY;
9871  }
9872 
9873  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
9874  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
9875  {
9876  /* mark the current solution invalid */
9877  lp->solved = FALSE;
9878  lp->lpobjval = SCIP_INVALID;
9880  }
9881  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
9882  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
9883  */
9885  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
9886  {
9887  assert(lp->flushed);
9888  assert(lp->solved);
9890  }
9891 
9892  lp->cutoffbound = cutoffbound;
9893 
9894  return SCIP_OKAY;
9895 }
9896 
9897 /** returns the name of the given LP algorithm */
9898 static
9899 const char* lpalgoName(
9900  SCIP_LPALGO lpalgo /**< LP algorithm */
9901  )
9902 {
9903  switch( lpalgo )
9904  {
9906  return "primal simplex";
9908  return "dual simplex";
9909  case SCIP_LPALGO_BARRIER:
9910  return "barrier";
9912  return "barrier/crossover";
9913  default:
9914  SCIPerrorMessage("invalid LP algorithm\n");
9915  SCIPABORT();
9916  return "invalid"; /*lint !e527*/
9917  }
9918 }
9919 
9920 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
9921 static
9923  SCIP_LP* lp, /**< current LP data */
9924  SCIP_SET* set, /**< global SCIP settings */
9925  SCIP_STAT* stat, /**< problem statistics */
9926  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
9927  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
9928  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
9929  )
9930 {
9931  SCIP_Real timedelta;
9932  SCIP_RETCODE retcode;
9933  int iterations;
9934 
9935  assert(lp != NULL);
9936  assert(lp->flushed);
9937  assert(set != NULL);
9938  assert(stat != NULL);
9939  assert(lperror != NULL);
9940 
9941  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",
9942  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
9943 
9944  *lperror = FALSE;
9945 
9946 #if 0 /* for debugging: write all node LP's */
9947  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
9948  {
9949  char fname[SCIP_MAXSTRLEN];
9950  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
9951  SCIP_CALL( SCIPlpWrite(lp, fname) );
9952  SCIPmessagePrintInfo("wrote LP to file <%s> (primal simplex, uobjlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
9953  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol,
9954  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
9955  }
9956 #endif
9957 
9958  /* start timing */
9959  if( lp->diving || lp->probing )
9960  {
9961  if( lp->strongbranchprobing )
9962  SCIPclockStart(stat->strongbranchtime, set);
9963  else
9964  SCIPclockStart(stat->divinglptime, set);
9965 
9966  timedelta = 0.0; /* unused for diving or probing */
9967  }
9968  else
9969  {
9970  SCIPclockStart(stat->primallptime, set);
9971  timedelta = -SCIPclockGetTime(stat->primallptime);
9972  }
9973 
9974  /* call primal simplex */
9975  retcode = SCIPlpiSolvePrimal(lp->lpi);
9976  if( retcode == SCIP_LPERROR )
9977  {
9978  *lperror = TRUE;
9979  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
9980  }
9981  else
9982  {
9983  SCIP_CALL( retcode );
9984  }
9986  lp->solisbasic = TRUE;
9987 
9988  /* stop timing */
9989  if( lp->diving || lp->probing )
9990  {
9991  if( lp->strongbranchprobing )
9992  SCIPclockStop(stat->strongbranchtime, set);
9993  else
9994  SCIPclockStop(stat->divinglptime, set);
9995  }
9996  else
9997  {
9998  timedelta += SCIPclockGetTime(stat->primallptime);
9999  SCIPclockStop(stat->primallptime, set);
10000  }
10001 
10002  /* count number of iterations */
10003  SCIPstatIncrement(stat, set, lpcount);
10004  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10005  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10006  {
10007  if( !lp->strongbranchprobing )
10008  {
10009  SCIPstatIncrement(stat, set, nlps);
10010  SCIPstatAdd( stat, set, nlpiterations, iterations );
10011  }
10012  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10013  {
10014  SCIPstatIncrement(stat, set, nprimalresolvelps );
10015  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10016  }
10017  if( lp->diving || lp->probing )
10018  {
10019  if( lp->strongbranchprobing )
10020  {
10021  SCIPstatIncrement(stat, set, nsbdivinglps);
10022  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10023  }
10024  else
10025  {
10026  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10027  SCIPstatIncrement(stat, set, ndivinglps);
10028  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10029  }
10030  }
10031  else
10032  {
10033  SCIPstatIncrement(stat, set, nprimallps);
10034  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10035  }
10036  }
10037  else
10038  {
10039  if ( ! lp->diving && ! lp->probing )
10040  {
10041  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10042  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10043  }
10044 
10045  if ( keepsol && !(*lperror) )
10046  {
10047  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10048  if( lp->validsollp == stat->lpcount-1 )
10049  lp->validsollp = stat->lpcount;
10050  if( lp->validfarkaslp == stat->lpcount-1 )
10051  lp->validfarkaslp = stat->lpcount;
10052  }
10053  }
10054 
10055  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10056  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10057 
10058  return SCIP_OKAY;
10059 }
10060 
10061 /** calls LPI to perform dual simplex, measures time and counts iterations */
10062 static
10064  SCIP_LP* lp, /**< current LP data */
10065  SCIP_SET* set, /**< global SCIP settings */
10066  SCIP_STAT* stat, /**< problem statistics */
10067  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10068  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10069  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10070  )
10071 {
10072  SCIP_Real timedelta;
10073  SCIP_RETCODE retcode;
10074  int iterations;
10075 
10076  assert(lp != NULL);
10077  assert(lp->flushed);
10078  assert(set != NULL);
10079  assert(stat != NULL);
10080  assert(lperror != NULL);
10081 
10082  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",
10083  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10084 
10085  *lperror = FALSE;
10086 
10087 #if 0 /* for debugging: write all node LP's */
10088  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10089  {
10090  char fname[SCIP_MAXSTRLEN];
10091  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10092  SCIP_CALL( SCIPlpWrite(lp, fname) );
10093  SCIPmessagePrintInfo("wrote LP to file <%s> (dual simplex, uobjlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10094  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol,
10095  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10096  }
10097 #endif
10098 
10099  /* start timing */
10100  if( lp->diving || lp->probing )
10101  {
10102  if( lp->strongbranchprobing )
10103  SCIPclockStart(stat->strongbranchtime, set);
10104  else
10105  SCIPclockStart(stat->divinglptime, set);
10106 
10107  timedelta = 0.0; /* unused for diving or probing */
10108  }
10109  else
10110  {
10111  SCIPclockStart(stat->duallptime, set);
10112  timedelta = -SCIPclockGetTime(stat->duallptime);
10113  }
10114 
10115  /* call dual simplex */
10116  retcode = SCIPlpiSolveDual(lp->lpi);
10117  if( retcode == SCIP_LPERROR )
10118  {
10119  *lperror = TRUE;
10120  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10121  }
10122  else
10123  {
10124  SCIP_CALL( retcode );
10125  }
10127  lp->solisbasic = TRUE;
10128 
10129  /* stop timing */
10130  if( lp->diving || lp->probing )
10131  {
10132  if( lp->strongbranchprobing )
10133  SCIPclockStop(stat->strongbranchtime, set);
10134  else
10135  SCIPclockStop(stat->divinglptime, set);
10136  }
10137  else
10138  {
10139  timedelta += SCIPclockGetTime(stat->duallptime);
10140  SCIPclockStop(stat->duallptime, set);
10141  }
10142 
10143  /* count number of iterations */
10144  SCIPstatIncrement(stat, set, lpcount);
10145  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10146  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10147  {
10148  if( !lp->strongbranchprobing )
10149  {
10150  SCIPstatIncrement(stat, set, nlps);
10151  SCIPstatAdd(stat, set, nlpiterations, iterations);
10152  }
10153  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10154  {
10155  SCIPstatIncrement(stat, set, ndualresolvelps);
10156  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10157  }
10158  if( lp->diving || lp->probing )
10159  {
10160  if( lp->strongbranchprobing )
10161  {
10162  SCIPstatIncrement(stat, set, nsbdivinglps);
10163  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10164  }
10165  else
10166  {
10167  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10168  SCIPstatIncrement(stat, set, ndivinglps);
10169  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10170  }
10171  }
10172  else
10173  {
10174  SCIPstatIncrement(stat, set, nduallps);
10175  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10176  }
10177  }
10178  else
10179  {
10180  if ( ! lp->diving && ! lp->probing )
10181  {
10182  SCIPstatIncrement(stat, set, ndualzeroitlps);
10183  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10184  }
10185 
10186  if( keepsol && !(*lperror) )
10187  {
10188  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10189  if( lp->validsollp == stat->lpcount-1 )
10190  lp->validsollp = stat->lpcount;
10191  if( lp->validfarkaslp == stat->lpcount-1 )
10192  lp->validfarkaslp = stat->lpcount;
10193  }
10194  }
10195 
10196  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10197  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10198 
10199  return SCIP_OKAY;
10200 }
10201 
10202 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10203  *
10204  * We follow the approach of the following paper to find a lexicographically minimal optimal
10205  * solution:
10206  *
10207  * Zanette, Fischetti, Balas@n
10208  * Can pure cutting plane algorithms work?@n
10209  * IPCO 2008, Bertinoro, Italy.
10210  *
10211  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10212  * heuristic, i.e., we limit the number of components which are minimized.
10213  *
10214  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10215  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10216  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10217  * pivots that will not change the objective are allowed afterwards.
10218  *
10219  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10220  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10221  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10222  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10223  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10224  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10225  * reduced cost. We then choose the next variable and iterate.
10226  *
10227  * We stop the process once we do not find candidates or have performed a maximum number of
10228  * iterations.
10229  *
10230  * @todo Does this really produce a lexicographically minimal solution?
10231  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10232  * guarantee that these variables will not be changed in later stages? We can fix these variables
10233  * to their lower bound, but this destroys the basis.
10234  * @todo Should we use lexicographical minimization in diving/probing or not?
10235  */
10236 static
10238  SCIP_LP* lp, /**< current LP data */
10239  SCIP_SET* set, /**< global SCIP settings */
10240  SCIP_STAT* stat, /**< problem statistics */
10241  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10242  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10243  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10244  )
10245 {
10246  SCIP_Real timedelta;
10247  SCIP_RETCODE retcode;
10248  int totalIterations;
10249  int lexIterations;
10250  int iterations;
10251  int rounds;
10252 
10253  assert(lp != NULL);
10254  assert(lp->flushed);
10255  assert(set != NULL);
10256  assert(stat != NULL);
10257  assert(lperror != NULL);
10258 
10259  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",
10260  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10261 
10262  *lperror = FALSE;
10263 
10264  /* start timing */
10265  if( lp->diving || lp->probing )
10266  {
10267  if( lp->strongbranchprobing )
10268  SCIPclockStart(stat->strongbranchtime, set);
10269  else
10270  SCIPclockStart(stat->divinglptime, set);
10271 
10272  timedelta = 0.0; /* unused for diving or probing */
10273  }
10274  else
10275  {
10276  SCIPclockStart(stat->duallptime, set);
10277  timedelta = -SCIPclockGetTime(stat->duallptime);
10278  }
10279 
10280  /* call dual simplex for first lp */
10281  retcode = SCIPlpiSolveDual(lp->lpi);
10282  if( retcode == SCIP_LPERROR )
10283  {
10284  *lperror = TRUE;
10285  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10286  }
10287  else
10288  {
10289  SCIP_CALL( retcode );
10290  }
10291  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10292  totalIterations = iterations;
10293 
10294  /* stop timing */
10295  if( lp->diving || lp->probing )
10296  {
10297  if( lp->strongbranchprobing )
10298  SCIPclockStop(stat->strongbranchtime, set);
10299  else
10300  SCIPclockStop(stat->divinglptime, set);
10301  }
10302  else
10303  {
10304  timedelta += SCIPclockGetTime(stat->duallptime);
10305  SCIPclockStop(stat->duallptime, set);
10306  }
10307 
10308  /* count number of iterations */
10309  SCIPstatIncrement(stat, set, lpcount);
10310  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10311  {
10312  if( lp->strongbranchprobing )
10313  {
10314  SCIPstatAdd(stat, set, nlpiterations, iterations);
10315  }
10316  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10317  {
10318  SCIPstatIncrement(stat, set, ndualresolvelps);
10319  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10320  }
10321  if( lp->diving || lp->probing )
10322  {
10323  if( lp->strongbranchprobing )
10324  {
10325  SCIPstatIncrement(stat, set, nsbdivinglps);
10326  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10327  }
10328  else
10329  {
10330  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10331  SCIPstatIncrement(stat, set, ndivinglps);
10332  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10333  }
10334  }
10335  else
10336  {
10337  SCIPstatIncrement(stat, set, nduallps);
10338  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10339  }
10340  }
10341  else
10342  {
10343  if ( ! lp->diving && ! lp->probing )
10344  {
10345  SCIPstatIncrement(stat, set, ndualzeroitlps);
10346  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10347  }
10348  }
10349  lexIterations = 0;
10350 
10351  /* search for lexicographically minimal optimal solution */
10352  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10353  {
10354  SCIP_Bool chooseBasic;
10355  SCIP_Real* primsol;
10356  SCIP_Real* dualsol;
10357  SCIP_Real* redcost;
10358  int* cstat;
10359  int* rstat;
10360  SCIP_Real* newobj;
10361  SCIP_Real* newlb;
10362  SCIP_Real* newub;
10363  SCIP_Real* newlhs;
10364  SCIP_Real* newrhs;
10365  SCIP_Real* oldlb;
10366  SCIP_Real* oldub;
10367  SCIP_Real* oldlhs;
10368  SCIP_Real* oldrhs;
10369  SCIP_Real* oldobj;
10370  SCIP_Bool* fixedc;
10371  SCIP_Bool* fixedr;
10372  int* indcol;
10373  int* indrow;
10374  int* indallcol;
10375  int* indallrow;
10376  int nDualDeg;
10377  int r, c;
10378  int cntcol;
10379  int cntrow;
10380  int nruns;
10381  int pos;
10382 
10383  chooseBasic = set->lp_lexdualbasic;
10384 
10385  /* start timing */
10386  SCIPclockStart(stat->lexduallptime, set);
10387 
10388  /* get all solution information */
10389  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10390  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10391  if( chooseBasic )
10392  {
10393  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10394  }
10395  else
10396  primsol = NULL;
10397 
10398  /* get basic and nonbasic information */
10399  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10400  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10401 
10402  /* save bounds, lhs/rhs, and objective */
10403  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10404  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10405  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10406  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10407  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10408  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10409  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10410  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10411 
10412  /* get storage for several arrays */
10413  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10414  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10415  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10416 
10417  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10418  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10419  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10420 
10421  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10422  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10423 
10424  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10425  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10426 
10427  /* initialize: set objective to 0, get fixed variables */
10428  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10429  for( c = 0; c < lp->nlpicols; ++c )
10430  {
10431  newobj[c] = 0.0;
10432  indallcol[c] = c;
10433  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10434  fixedc[c] = TRUE;
10435  else
10436  fixedc[c] = FALSE;
10437  }
10438 
10439  /* initialize: get fixed slack variables */
10440  for( r = 0; r < lp->nlpirows; ++r )
10441  {
10442  indallrow[r] = r;
10443  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10444  fixedr[r] = TRUE;
10445  else
10446  fixedr[r] = FALSE;
10447  }
10448 
10449 #ifdef DEBUG_LEXDUAL
10450  {
10451  int j;
10452 
10453  if( !chooseBasic )
10454  {
10455  assert(primsol == NULL);
10456  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10457  }
10458  assert(primsol != NULL);
10459  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10460  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10461 
10462  for( j = 0; j < lp->nlpicols; ++j )
10463  {
10464  if( fixedc[j] )
10465  {
10466  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10467  }
10468  else
10469  {
10470  char type;
10471  switch( (SCIP_BASESTAT) cstat[j] )
10472  {
10473  case SCIP_BASESTAT_LOWER:
10474  type = 'l';
10475  break;
10476  case SCIP_BASESTAT_UPPER:
10477  type = 'u';
10478  break;
10479  case SCIP_BASESTAT_ZERO:
10480  type = 'z';
10481  break;
10482  case SCIP_BASESTAT_BASIC:
10483  type = 'b';
10484  break;
10485  default:
10486  type = '?';
10487  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10488  SCIPABORT();
10489  }
10490  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10491  }
10492  }
10493  SCIPsetDebugMsg(set, "\n\n");
10494 
10495  if( !chooseBasic )
10496  {
10497  SCIPsetFreeBufferArray(set, &primsol);
10498  assert(primsol == NULL);
10499  }
10500  }
10501 #endif
10502 
10503  /* perform lexicographic rounds */
10504  pos = -1;
10505  nruns = 0;
10506  rounds = 0;
10507  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10508  do
10509  {
10510  int oldpos;
10511 
10512  /* get current solution */
10513  if( chooseBasic )
10514  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10515  else
10516  {
10517  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10518  assert(primsol == NULL);
10519  }
10520 
10521  /* get current basis */
10522  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10523 
10524  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10525  nDualDeg = 0;
10526  cntcol = 0;
10527  oldpos = pos;
10528  pos = -1;
10529  for( c = 0; c < lp->nlpicols; ++c )
10530  {
10531  if( !fixedc[c] )
10532  {
10533  /* check whether variable is in basis */
10534  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10535  {
10536  /* store first candidate */
10537  if( pos == -1 && c > oldpos )
10538  {
10539  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10540  pos = c;
10541  }
10542  }
10543  else
10544  {
10545  /* reduced cost == 0 -> possible candidate */
10546  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10547  {
10548  ++nDualDeg;
10549  /* only if we have not yet found a candidate */
10550  if( pos == -1 && c > oldpos )
10551  {
10552  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10553  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10554  {
10555  newlb[cntcol] = oldlb[c];
10556  newub[cntcol] = oldlb[c];
10557  indcol[cntcol++] = c;
10558  fixedc[c] = TRUE;
10559  }
10560  else /* found a non-fixed candidate */
10561  {
10562  if( !chooseBasic )
10563  pos = c;
10564  }
10565  }
10566  }
10567  else
10568  {
10569  /* nonzero reduced cost -> variable can be fixed */
10570  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10571  {
10572  newlb[cntcol] = oldlb[c];
10573  newub[cntcol] = oldlb[c];
10574  }
10575  else
10576  {
10577  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10578  {
10579  newlb[cntcol] = oldub[c];
10580  newub[cntcol] = oldub[c];
10581  }
10582  else
10583  {
10584  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10585  newlb[cntcol] = 0.0;
10586  newub[cntcol] = 0.0;
10587  }
10588  }
10589  indcol[cntcol++] = c;
10590  fixedc[c] = TRUE;
10591  }
10592  }
10593  }
10594  }
10595 
10596  /* check rows */
10597  cntrow = 0;
10598  for( r = 0; r < lp->nlpirows; ++r )
10599  {
10600  if( !fixedr[r] )
10601  {
10602  /* consider only nonbasic rows */
10603  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
10604  {
10605  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
10606  if( SCIPsetIsFeasZero(set, dualsol[r]) )
10607  ++nDualDeg;
10608  else
10609  {
10610  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
10611  {
10612  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
10613  newlhs[cntrow] = oldlhs[r];
10614  newrhs[cntrow] = oldlhs[r];
10615  }
10616  else
10617  {
10618  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
10619  newlhs[cntrow] = oldrhs[r];
10620  newrhs[cntrow] = oldrhs[r];
10621  }
10622  indrow[cntrow++] = r;
10623  fixedr[r] = TRUE;
10624  }
10625  }
10626  }
10627  }
10628 
10629  if( nDualDeg > 0 && pos >= 0 )
10630  {
10631  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
10632 
10633  /* change objective */
10634  if( nruns == 0 )
10635  {
10636  /* set objective to appropriate unit vector for first run */
10637  newobj[pos] = 1.0;
10638  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
10639  }
10640  else
10641  {
10642  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
10643  SCIP_Real obj = 1.0;
10644  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
10645  }
10646 
10647  /* fix variables */
10648  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
10649  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
10650 
10651  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
10652  retcode = SCIPlpiSolvePrimal(lp->lpi);
10653  if( retcode == SCIP_LPERROR )
10654  {
10655  *lperror = TRUE;
10656  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10657  }
10658  else
10659  {
10660  SCIP_CALL( retcode );
10661  }
10662  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10663  lexIterations += iterations;
10664 
10665 #ifdef DEBUG_LEXDUAL
10666  if( iterations > 0 )
10667  {
10668  int j;
10669 
10670  if( !chooseBasic )
10671  {
10672  assert(primsol == NULL);
10673  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10674  }
10675  assert(primsol != NULL);
10676  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10677 
10678  for( j = 0; j < lp->nlpicols; ++j )
10679  {
10680  if( fixedc[j] )
10681  {
10682  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10683  }
10684  else
10685  {
10686  char cstart = '[';
10687  char cend = ']';
10688  char type;
10689 
10690  if(j == pos)
10691  {
10692  cstart = '*';
10693  cend = '*';
10694  }
10695 
10696  switch( (SCIP_BASESTAT) cstat[j] )
10697  {
10698  case SCIP_BASESTAT_LOWER:
10699  type = 'l';
10700  break;
10701  case SCIP_BASESTAT_UPPER:
10702  type = 'u';
10703  break;
10704  case SCIP_BASESTAT_ZERO:
10705  type = 'z';
10706  break;
10707  case SCIP_BASESTAT_BASIC:
10708  type = 'b';
10709  break;
10710  default:
10711  type = '?';
10712  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
10713  SCIPABORT();
10714  }
10715  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
10716  }
10717  }
10718  SCIPsetDebugMsg(set, "\n\n");
10719 
10720  if( !chooseBasic )
10721  {
10722  SCIPsetFreeBufferArray(set, &primsol);
10723  assert(primsol == NULL);
10724  }
10725  }
10726 #endif
10727 
10728  /* count only as round if iterations have been performed */
10729  if( iterations > 0 )
10730  ++rounds;
10731  ++nruns;
10732  }
10733  }
10734  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
10735 
10736  /* reset bounds, lhs/rhs, and obj */
10737  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
10738  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
10739  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
10740 
10741  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
10742  retcode = SCIPlpiSolveDual(lp->lpi);
10743  if( retcode == SCIP_LPERROR )
10744  {
10745  *lperror = TRUE;
10746  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10747  }
10748  else
10749  {
10750  SCIP_CALL( retcode );
10751  }
10752  assert(SCIPlpiIsOptimal(lp->lpi));
10753  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10754  lexIterations += iterations;
10755 
10756  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
10757 
10758  /* count number of iterations */
10759  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
10760  SCIPstatIncrement(stat, set, nlps);
10761 
10762  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10763  {
10764  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
10765  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10766  {
10767  SCIPstatIncrement(stat, set, nlexdualresolvelps);
10768  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
10769  }
10770  SCIPstatIncrement(stat, set, nlexduallps);
10771  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
10772 
10773  totalIterations += lexIterations;
10774  }
10775 
10776  /* free space */
10777  SCIPsetFreeBufferArray(set, &newobj);
10778 
10779  SCIPsetFreeBufferArray(set, &fixedr);
10780  SCIPsetFreeBufferArray(set, &fixedc);
10781 
10782  SCIPsetFreeBufferArray(set, &indallrow);
10783  SCIPsetFreeBufferArray(set, &indallcol);
10784 
10785  SCIPsetFreeBufferArray(set, &indrow);
10786  SCIPsetFreeBufferArray(set, &newrhs);
10787  SCIPsetFreeBufferArray(set, &newlhs);
10788 
10789  SCIPsetFreeBufferArray(set, &indcol);
10790  SCIPsetFreeBufferArray(set, &newub);
10791  SCIPsetFreeBufferArray(set, &newlb);
10792 
10793  SCIPsetFreeBufferArray(set, &oldobj);
10794  SCIPsetFreeBufferArray(set, &oldrhs);
10795  SCIPsetFreeBufferArray(set, &oldlhs);
10796  SCIPsetFreeBufferArray(set, &oldub);
10797  SCIPsetFreeBufferArray(set, &oldlb);
10798 
10799  SCIPsetFreeBufferArray(set, &rstat);
10800  SCIPsetFreeBufferArray(set, &cstat);
10801 
10802  SCIPsetFreeBufferArray(set, &redcost);
10803  SCIPsetFreeBufferArray(set, &dualsol);
10804  if( chooseBasic )
10805  SCIPsetFreeBufferArray(set, &primsol);
10806 
10807  /* stop timing */
10808  SCIPclockStop(stat->lexduallptime, set);
10809 
10810  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10811  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10812  }
10814  lp->solisbasic = TRUE;
10815 
10816  if( totalIterations > 0 && !lp->strongbranchprobing )
10817  SCIPstatIncrement(stat, set, nlps);
10818  else
10819  {
10820  if( keepsol && !(*lperror) )
10821  {
10822  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10823  if( lp->validsollp == stat->lpcount-1 )
10824  lp->validsollp = stat->lpcount;
10825  if( lp->validfarkaslp == stat->lpcount-1 )
10826  lp->validfarkaslp = stat->lpcount;
10827  }
10828  }
10829 
10830  return SCIP_OKAY;
10831 }
10832 
10833 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
10834 static
10836  SCIP_LP* lp, /**< current LP data */
10837  SCIP_SET* set, /**< global SCIP settings */
10838  SCIP_STAT* stat, /**< problem statistics */
10839  SCIP_Bool crossover, /**< should crossover be performed? */
10840  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10841  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10842  )
10843 {
10844  SCIP_Real timedelta;
10845  SCIP_RETCODE retcode;
10846  int iterations;
10847 
10848  assert(lp != NULL);
10849  assert(lp->flushed);
10850  assert(set != NULL);
10851  assert(stat != NULL);
10852  assert(lperror != NULL);
10853 
10854  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",
10855  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
10856  stat->nbarrierlps, stat->ndivinglps);
10857 
10858  *lperror = FALSE;
10859 
10860 #if 0 /* for debugging: write all node LP's */
10861  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10862  {
10863  char fname[SCIP_MAXSTRLEN];
10864  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10865  SCIP_CALL( SCIPlpWrite(lp, fname) );
10866  SCIPmessagePrintInfo("wrote LP to file <%s> (barrier, uobjlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10867  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
10868  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10869  }
10870 #endif
10871 
10872  /* start timing */
10873  if( lp->diving || lp->probing )
10874  {
10875  if( lp->strongbranchprobing )
10876  SCIPclockStart(stat->strongbranchtime, set);
10877  else
10878  SCIPclockStart(stat->divinglptime, set);
10879 
10880  timedelta = 0.0; /* unused for diving or probing */
10881  }
10882  else
10883  {
10884  SCIPclockStart(stat->barrierlptime, set);
10885  timedelta = -SCIPclockGetTime(stat->duallptime);
10886  }
10887 
10888  /* call barrier algorithm */
10889  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
10890  if( retcode == SCIP_LPERROR )
10891  {
10892  *lperror = TRUE;
10893  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10894  }
10895  else
10896  {
10897  SCIP_CALL( retcode );
10898  }
10900  lp->solisbasic = crossover;
10901 
10902  /* stop timing */
10903  if( lp->diving || lp->probing )
10904  {
10905  if( lp->strongbranchprobing )
10906  SCIPclockStop(stat->strongbranchtime, set);
10907  else
10908  SCIPclockStop(stat->divinglptime, set);
10909  }
10910  else
10911  {
10912  SCIPclockStop(stat->barrierlptime, set);
10913  timedelta = -SCIPclockGetTime(stat->duallptime);
10914  }
10915 
10916  /* count number of iterations */
10917  SCIPstatIncrement(stat, set, lpcount);
10918  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10919  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10920  {
10921  if( !lp->strongbranchprobing )
10922  {
10923  SCIPstatIncrement(stat, set, nlps);
10924  SCIPstatAdd(stat, set, nlpiterations, iterations);
10925  }
10926  if( lp->diving || lp->probing )
10927  {
10928  if( lp->strongbranchprobing )
10929  {
10930  SCIPstatIncrement(stat, set, nsbdivinglps);
10931  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10932  }
10933  else
10934  {
10935  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10936  SCIPstatIncrement(stat, set, ndivinglps);
10937  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10938  }
10939  }
10940  else
10941  {
10942  SCIPstatIncrement(stat, set, nbarrierlps);
10943  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
10944  }
10945  }
10946  else
10947  {
10948  if ( ! lp->diving && ! lp->probing )
10949  {
10950  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
10951  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
10952  }
10953 
10954  if( keepsol && !(*lperror) )
10955  {
10956  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10957  if( lp->validsollp == stat->lpcount-1 )
10958  lp->validsollp = stat->lpcount;
10959  if( lp->validfarkaslp == stat->lpcount-1 )
10960  lp->validfarkaslp = stat->lpcount;
10961  }
10962  }
10963 
10964  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
10965  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
10966 
10967  return SCIP_OKAY;
10968 }
10969 
10970 /** solves the LP with the given algorithm */
10971 static
10973  SCIP_LP* lp, /**< current LP data */
10974  SCIP_SET* set, /**< global SCIP settings */
10975  SCIP_STAT* stat, /**< problem statistics */
10976  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
10977  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10978  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10979  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
10980  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10981  )
10982 {
10983  SCIP_Real lptimelimit;
10984  SCIP_Bool success;
10985 
10986  assert(lp != NULL);
10987  assert(lp->flushed);
10988  assert(lperror != NULL);
10989 
10990  /* check if a time limit is set, and set time limit for LP solver accordingly */
10991  lptimelimit = SCIPlpiInfinity(lp->lpi);
10992  if( set->istimelimitfinite )
10993  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
10994 
10995  success = FALSE;
10996  if( lptimelimit > 0.0 )
10997  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
10998 
10999  if( lptimelimit <= 0.0 || !success )
11000  {
11001  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11002  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11003  *timelimit = TRUE;
11004  return SCIP_OKAY;
11005  }
11006  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %f seconds\n", lpalgoName(lpalgo), lptimelimit);
11007 
11008  /* call appropriate LP algorithm */
11009  switch( lpalgo )
11010  {
11012  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, lperror) );
11013  break;
11014 
11016  /* run dual lexicographic simplex if required */
11017  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11018  {
11019  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11020  }
11021  else
11022  {
11023  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11024  }
11025  break;
11026 
11027  case SCIP_LPALGO_BARRIER:
11028  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11029  break;
11030 
11032  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11033  break;
11034 
11035  default:
11036  SCIPerrorMessage("invalid LP algorithm\n");
11037  return SCIP_INVALIDDATA;
11038  }
11039 
11040  if( !(*lperror) )
11041  {
11042  /* check for primal and dual feasibility */
11044 
11045  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11046  }
11047 
11048  return SCIP_OKAY;
11049 }
11050 
11051 #define FEASTOLTIGHTFAC 0.001
11052 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11053 static
11055  SCIP_LP* lp, /**< current LP data */
11056  SCIP_SET* set, /**< global SCIP settings */
11057  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11058  SCIP_STAT* stat, /**< problem statistics */
11059  SCIP_PROB* prob, /**< problem data */
11060  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11061  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11062  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11063  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11064  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11065  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11066  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11067  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11068  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11069  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11070  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11071  )
11072 {
11073  SCIP_Bool success;
11074  SCIP_Bool success2;
11075  SCIP_Bool success3;
11076  SCIP_Bool simplex;
11077  SCIP_Bool itlimishard;
11078  SCIP_Bool usepolishing;
11079 
11080  assert(lp != NULL);
11081  assert(lp->flushed);
11082  assert(set != NULL);
11083  assert(stat != NULL);
11084  assert(lperror != NULL);
11085  assert(timelimit != NULL);
11086 
11087  *lperror = FALSE;
11088 
11089  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11090  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11091  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11092  * SCIP_LP such that we can return a primal ray
11093  */
11094  if( lp->looseobjvalinf > 0 )
11095  {
11096  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11097  return SCIP_ERROR;
11098  }
11099 
11100  /* check, whether we solve with a simplex algorithm */
11101  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11102 
11103  /* check whether the iteration limit is a hard one */
11104  itlimishard = (itlim == harditlim);
11105 
11106  /* check whether solution polishing should be used */
11107  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)))
11108  {
11109  usepolishing = TRUE;
11110  if( lp->updateintegrality )
11111  {
11112  SCIP_CALL( lpCopyIntegrality(lp, set) );
11113  }
11114  }
11115  else
11116  usepolishing = FALSE;
11117 
11118  /* solve with given settings (usually fast but imprecise) */
11119  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11120  {
11121  SCIP_CALL( lpSetUobjlim(lp, set, lp->cutoffbound) );
11122  }
11123  else
11124  {
11125  SCIP_CALL( lpSetUobjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) );
11126  }
11127  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11128  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * SCIPsetLpfeastol(set) : SCIPsetLpfeastol(set), &success) );
11129  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11130  &success) );
11131  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11132  : SCIPsetBarrierconvtol(set), &success) );
11133  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11134  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11135  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11136  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11137  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11138  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11139  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11140  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11141  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11142  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11143  SCIP_CALL( lpSetRandomseed(lp, SCIPsetInitializeRandomSeed(set, set->random_randomseed), &success) );
11144  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11145  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11146  resolve = FALSE; /* only the first solve should be counted as resolving call */
11147 
11148  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11149  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11150  return SCIP_OKAY;
11151  else if( !set->lp_checkstability )
11152  {
11153  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11154  if( success )
11155  {
11156  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11157  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11158  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11159  return SCIP_OKAY;
11160  }
11161  }
11162 
11163  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11164  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11165  */
11166 
11167  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11168  * do this only if the iteration limit was not exceeded in the last LP solving call
11169  */
11170  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11171  {
11172  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11173  if( success )
11174  {
11175  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11176  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again with %s without FASTMIP\n",
11177  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11178  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11179 
11180  /* check for stability */
11181  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11182  return SCIP_OKAY;
11183  else if( !set->lp_checkstability )
11184  {
11185  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11186  if( success )
11187  {
11188  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11189  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11190  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11191  return SCIP_OKAY;
11192  }
11193  }
11194  }
11195  }
11196 
11197  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11198  * and go directly to solving the LP from scratch
11199  */
11200  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11201  {
11202  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11203  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11204  if( success )
11205  {
11206  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11207  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again with %s %s scaling\n",
11208  stat->nnodes, stat->nlps, lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11209  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11210 
11211  /* check for stability */
11212  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11213  return SCIP_OKAY;
11214  else if( !set->lp_checkstability )
11215  {
11216  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11217  if( success )
11218  {
11219  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11220  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11221  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11222  return SCIP_OKAY;
11223  }
11224  }
11225 
11226  /* reset scaling */
11227  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11228  assert(success);
11229  }
11230  }
11231 
11232  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11233  * and go directly to solving the LP from scratch
11234  */
11235  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11236  {
11237  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11238  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11239  if( success )
11240  {
11241  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11242  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again with %s %s presolving\n",
11243  stat->nnodes, stat->nlps, lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11244  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11245 
11246  /* check for stability */
11247  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11248  return SCIP_OKAY;
11249  else if( !set->lp_checkstability )
11250  {
11251  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11252  if( success )
11253  {
11254  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11255  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11256  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11257  return SCIP_OKAY;
11258  }
11259  }
11260 
11261  /* reset presolving */
11262  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11263  assert(success);
11264  }
11265  }
11266 
11267  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11268  * do this only if the iteration limit was not exceeded in the last LP solving call
11269  */
11270  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11271  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11272  {
11273  success = FALSE;
11274  if( !tightprimfeastol )
11275  {
11276  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11277  }
11278 
11279  success2 = FALSE;
11280  if( !tightdualfeastol )
11281  {
11283  }
11284 
11285  success3 = FALSE;
11286  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11287  {
11289  }
11290 
11291  if( success || success2 || success3 )
11292  {
11293  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11294  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again with %s with tighter primal and dual feasibility tolerance\n",
11295  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11296  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11297 
11298  /* check for stability */
11299  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11300  return SCIP_OKAY;
11301  else if( !set->lp_checkstability )
11302  {
11303  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11304  if( success )
11305  {
11306  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11307  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11308  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11309  return SCIP_OKAY;
11310  }
11311  }
11312 
11313  /* reset feasibility tolerance */
11314  if( !tightprimfeastol )
11315  {
11316  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11317  }
11318  if( !tightdualfeastol )
11319  {
11320  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11321  }
11322  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11323  {
11324  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11325  }
11326  }
11327  }
11328 
11329  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11330  * the given iteration limit might be a soft one to restrict resolving calls only */
11331  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11332 
11333  /* if not already done, solve again from scratch */
11334  if( !fromscratch && simplex )
11335  {
11336  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11337  if( success )
11338  {
11339  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11340  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again from scratch with %s\n",
11341  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11342  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11343 
11344  /* check for stability */
11345  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11346  return SCIP_OKAY;
11347  else if( !set->lp_checkstability )
11348  {
11349  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11350  if( success )
11351  {
11352  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11353  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11354  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11355  return SCIP_OKAY;
11356  }
11357  }
11358  }
11359  }
11360 
11361  /* solve again, use other simplex this time */
11362  if( simplex )
11363  {
11365  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11366  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again from scratch with %s\n",
11367  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11368  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11369 
11370  /* check for stability */
11371  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11372  return SCIP_OKAY;
11373  else if( !set->lp_checkstability )
11374  {
11375  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11376  if( success )
11377  {
11378  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11379  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11380  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11381  return SCIP_OKAY;
11382  }
11383  }
11384 
11385  /* solve again with opposite scaling and other simplex */
11386  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11387  if( success )
11388  {
11389  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11390  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again from scratch with %s %s scaling\n",
11391  stat->nnodes, stat->nlps, lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11392  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11393 
11394  /* check for stability */
11395  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11396  return SCIP_OKAY;
11397  else if( !set->lp_checkstability )
11398  {
11399  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11400  if( success )
11401  {
11402  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11403  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11404  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11405  return SCIP_OKAY;
11406  }
11407  }
11408 
11409  /* reset scaling */
11410  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11411  assert(success);
11412  }
11413 
11414  /* solve again with opposite presolving and other simplex */
11415  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11416  if( success )
11417  {
11418  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11419  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again from scratch with %s %s presolving\n",
11420  stat->nnodes, stat->nlps, lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11421  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11422 
11423  /* check for stability */
11424  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11425  return SCIP_OKAY;
11426  else if( !set->lp_checkstability )
11427  {
11428  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11429  if( success )
11430  {
11431  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11432  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11433  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11434  return SCIP_OKAY;
11435  }
11436  }
11437 
11438  /* reset presolving */
11439  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11440  assert(success);
11441  }
11442 
11443  /* solve again with tighter feasibility tolerance, use other simplex this time */
11444  if( !tightprimfeastol || !tightdualfeastol )
11445  {
11446  success = FALSE;
11447  if( !tightprimfeastol )
11448  {
11449  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11450  }
11451 
11452  success2 = FALSE;
11453  if( !tightdualfeastol )
11454  {
11456  }
11457 
11458  if( success || success2 )
11459  {
11460  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11461  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- solve again from scratch with %s with tighter feasibility tolerance\n",
11462  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11463  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11464 
11465  /* check for stability */
11466  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11467  return SCIP_OKAY;
11468  else if( !set->lp_checkstability )
11469  {
11470  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11471  if( success )
11472  {
11473  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11474  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ignoring instability of %s\n",
11475  stat->nnodes, stat->nlps, lpalgoName(lpalgo));
11476  return SCIP_OKAY;
11477  }
11478  }
11479 
11480  /* reset feasibility tolerance */
11481  if( !tightprimfeastol )
11482  {
11483  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11484  }
11485  if( !tightdualfeastol )
11486  {
11487  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11488  }
11489  }
11490  }
11491  }
11492 
11493  /* nothing worked -- exit with an LPERROR */
11494  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT "\n",
11495  stat->nnodes, stat->nlps);
11496  *lperror = TRUE;
11497 
11498  return SCIP_OKAY;
11499 }
11500 
11501 /** adjust the LP objective value if its greater/less than +/- SCIPsetInfinity() */
11502 static
11504  SCIP_LP* lp, /**< current LP data */
11505  SCIP_SET* set, /**< global SCIP settings */
11506  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11507  )
11508 {
11509  assert(lp != NULL);
11510  assert(set != NULL);
11511 
11512  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11513  {
11514  if( !lp->adjustlpval )
11515  {
11516  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11517  lp->adjustlpval = TRUE;
11518  }
11519  lp->lpobjval = SCIPsetInfinity(set);
11520  }
11521  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11522  {
11523  if( !lp->adjustlpval )
11524  {
11525  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11526  lp->adjustlpval = TRUE;
11527  }
11528  lp->lpobjval = -SCIPsetInfinity(set);
11529  }
11530 }
11531 
11532 /** solves the LP with the given algorithm and evaluates return status */
11533 static
11535  SCIP_LP* lp, /**< current LP data */
11536  SCIP_SET* set, /**< global SCIP settings */
11537  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11538  SCIP_STAT* stat, /**< problem statistics */
11539  SCIP_PROB* prob, /**< problem data */
11540  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11541  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11542  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11543  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11544  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11545  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11546  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11547  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11548  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11549  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11550  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11551  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11552  )
11553 {
11554  SCIP_Bool solvedprimal;
11555  SCIP_Bool solveddual;
11556  SCIP_Bool timelimit;
11557  int itlim;
11558 
11559  assert(lp != NULL);
11560  assert(lp->flushed);
11561  assert(set != NULL);
11562  assert(stat != NULL);
11563  assert(lperror != NULL);
11564 
11565  checkLinks(lp);
11566 
11567  solvedprimal = FALSE;
11568  solveddual = FALSE;
11569  timelimit = FALSE;
11570 
11571  /* select the basic iteration limit depending on whether this is a resolving call or not */
11572  itlim = ( resolve ? resolveitlim : harditlim );
11573 
11574  SOLVEAGAIN:
11575  /* call simplex */
11576  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11577  keepsol, &timelimit, lperror) );
11578  resolve = FALSE; /* only the first solve should be counted as resolving call */
11579  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11580  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11581 
11582  /* check, if an error occurred */
11583  if( *lperror )
11584  {
11585  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11586  lp->solved = FALSE;
11588  return SCIP_OKAY;
11589  }
11590 
11591  /* check, if a time limit was exceeded */
11592  if( timelimit )
11593  {
11594  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11595  lp->solved = TRUE;
11597  lp->lpobjval = -SCIPsetInfinity(set);
11598  return SCIP_OKAY;
11599  }
11600 
11601  /* only one should return true */
11602  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11604 
11605  /* evaluate solution status */
11606  if( SCIPlpiIsOptimal(lp->lpi) )
11607  {
11608  assert(lp->primalfeasible);
11609  assert(lp->dualfeasible);
11611  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11612  adjustLPobjval(lp, set, messagehdlr);
11613 
11614  if( !SCIPsetIsInfinity(set, lp->lpiuobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) )
11615  {
11616  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11617  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiuobjlim);
11619  lp->lpobjval = SCIPsetInfinity(set);
11620  }
11621  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11622  * reached if the LP objective value is greater than the cutoff bound
11623  */
11625  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11626  }
11627  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11628  {
11629  assert(!lpCutoffDisabled(set));
11631  lp->lpobjval = SCIPsetInfinity(set);
11632  }
11633  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11634  {
11635  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11636  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11637  {
11638  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11639  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11640  goto SOLVEAGAIN;
11641  }
11643  lp->lpobjval = SCIPsetInfinity(set);
11644  }
11645  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11646  {
11647  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11648  if( needprimalray && !SCIPlpiHasPrimalRay(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11649  {
11650  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11651  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11652  goto SOLVEAGAIN;
11653  }
11655  lp->lpobjval = -SCIPsetInfinity(set);
11656  }
11657  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11658  {
11659  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11660  adjustLPobjval(lp, set, messagehdlr);
11662  }
11663  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11664  {
11665  lp->lpobjval = -SCIPsetInfinity(set);
11667  }
11668  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11669  {
11670  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11671  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11672  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11673  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11674  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11675  goto SOLVEAGAIN;
11676  }
11677  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11678  {
11679  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11680  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11681  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11682  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11683  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11684  goto SOLVEAGAIN;
11685  }
11686  else
11687  {
11688  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
11689  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
11691  return SCIP_LPERROR;
11692  }
11693 
11694  lp->solved = TRUE;
11695 
11696  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
11699 
11700  return SCIP_OKAY;
11701 }
11702 
11703 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
11704 static
11706  SCIP_LP* lp, /**< current LP data */
11707  BMS_BLKMEM* blkmem, /**< block memory */
11708  SCIP_SET* set, /**< global SCIP settings */
11709  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11710  SCIP_STAT* stat, /**< problem statistics */
11711  SCIP_PROB* prob, /**< problem data */
11712  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11713  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11714  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11715  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11716  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11717  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11718  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11719  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11720  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11721  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11722  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11723  )
11724 {
11725  SCIP_Bool resolve;
11726  char algo;
11727 
11728  assert(lp != NULL);
11729  assert(set != NULL);
11730  assert(lperror != NULL);
11731 
11732  /* flush changes to the LP solver */
11733  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
11734  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
11735 
11736  /* select LP algorithm to apply */
11737  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
11738  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
11739 
11740  switch( algo )
11741  {
11742  case 's':
11743  /* select simplex method */
11744  if( lp->dualfeasible || !lp->primalfeasible )
11745  {
11746  SCIPsetDebugMsg(set, "solving dual LP\n");
11747  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11748  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11749  }
11750  else
11751  {
11752  SCIPsetDebugMsg(set, "solving primal LP\n");
11753  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11754  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11755  }
11756  break;
11757 
11758  case 'p':
11759  SCIPsetDebugMsg(set, "solving primal LP\n");
11760  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11761  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11762  break;
11763 
11764  case 'd':
11765  SCIPsetDebugMsg(set, "solving dual LP\n");
11766  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11767  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11768  break;
11769 
11770  case 'b':
11771  SCIPsetDebugMsg(set, "solving barrier LP\n");
11772  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
11773  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11774  break;
11775 
11776  case 'c':
11777  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
11778  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
11779  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11780  break;
11781 
11782  default:
11783  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
11784  return SCIP_PARAMETERWRONGVAL;
11785  }
11786  assert(!(*lperror) || !lp->solved);
11787 
11788  return SCIP_OKAY;
11789 }
11790 
11791 #ifndef NDEBUG
11792 /** checks if the lazy bounds are valid */
11793 static
11795  SCIP_LP* lp, /**< LP data */
11796  SCIP_SET* set /**< global SCIP settings */
11797  )
11798 {
11799  SCIP_COL* col;
11800  int c;
11801 
11802  assert(lp->flushed);
11803 
11804  for( c = 0; c < lp->nlazycols; ++c )
11805  {
11806  col = lp->lazycols[c];
11807 
11808  /* in case lazy bounds are given, check that the primal solution satisfies them */
11809  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
11810  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
11811  }
11812 }
11813 #else
11814 #define checkLazyBounds(lp, set) /**/
11815 #endif
11816 
11817 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
11818  * diving
11819  */
11820 static
11822  SCIP_LP* lp, /**< LP data */
11823  SCIP_SET* set /**< global SCIP settings */
11824  )
11825 {
11826  SCIP_COL* col;
11827  int c;
11828 
11829  assert(lp->nlazycols > 0);
11830 
11831  /* return, if we are in diving, and bounds were already applied
11832  * or if we are not in diving and bounds were not applied
11833  */
11834  if( lp->diving == lp->divinglazyapplied )
11835  return SCIP_OKAY;
11836 
11837  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
11838  lp->diving, lp->divinglazyapplied);
11839 
11840  for( c = 0; c < lp->nlazycols; ++c )
11841  {
11842  col = lp->lazycols[c];
11843 
11844  /* if the column has a lazy lower bound, mark its lower bounds as changed */
11845  if( !SCIPsetIsInfinity(set, -col->lazylb) )
11846  {
11847  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
11848  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
11849  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11850 
11851  /* insert column in the chgcols list (if not already there) */
11852  SCIP_CALL( insertColChgcols(col, set, lp) );
11853 
11854  /* mark bound change in the column */
11855  col->lbchanged = TRUE;
11856  }
11857 
11858  /* if the column has a lazy upper bound, mark its upper bounds as changed */
11859  if( !SCIPsetIsInfinity(set, col->lazyub) )
11860  {
11861  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
11862  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
11863  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11864 
11865  /* insert column in the chgcols list (if not already there) */
11866  SCIP_CALL( insertColChgcols(col, set, lp) );
11867 
11868  /* mark bound change in the column */
11869  col->ubchanged = TRUE;
11870  }
11871  }
11872 
11873  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
11874  * if not, we just removed them
11875  */
11876  lp->divinglazyapplied = lp->diving;
11877 
11878  return SCIP_OKAY;
11879 }
11880 
11881 /** returns the iteration limit for an LP resolving call */
11882 static
11884  SCIP_SET* set, /**< global SCIP settings */
11885  SCIP_STAT* stat, /**< dynamic problem statistics */
11886  int itlim /**< hard iteration limit */
11887  )
11888 {
11889  /* no limit set or average not yet reliable */
11890  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
11891  return itlim;
11892  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
11893  if( itlim == -1 )
11894  itlim = INT_MAX;
11895  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
11896  return (int) MIN(itlim, MAX(set->lp_resolveitermin,
11897  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
11898 }
11899 
11900 
11901 
11902 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
11904  SCIP_LP* lp, /**< LP data */
11905  SCIP_SET* set, /**< global SCIP settings */
11906  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11907  BMS_BLKMEM* blkmem, /**< block memory buffers */
11908  SCIP_STAT* stat, /**< problem statistics */
11909  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11910  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
11911  SCIP_PROB* prob, /**< problem data */
11912  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
11913  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
11914  * (limit is computed within the method w.r.t. the average LP iterations) */
11915  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
11916  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11917  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11918  )
11919 {
11920  SCIP_RETCODE retcode;
11921  SCIP_Bool needprimalray;
11922  SCIP_Bool needdualray;
11923  int harditlim;
11924  int resolveitlim;
11925 
11926  assert(lp != NULL);
11927  assert(prob != NULL);
11928  assert(prob->nvars >= lp->ncols);
11929  assert(lperror != NULL);
11930 
11931  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
11932  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
11933 
11934  retcode = SCIP_OKAY;
11935  *lperror = FALSE;
11936 
11937  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
11938  needprimalray = TRUE;
11939  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
11940  || (set->conf_enable && set->conf_useinflp != 'o'));
11941 
11942  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
11943  harditlim = (int) MIN(itlim, INT_MAX);
11944  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
11945  assert(harditlim == -1 || (resolveitlim <= harditlim));
11946 
11947  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
11948  * or removed from the LP (diving was ended)
11949  */
11950  if( lp->nlazycols > 0 )
11951  {
11952  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
11953  * first resolve LP?
11954  */
11955  SCIP_CALL( updateLazyBounds(lp, set) );
11956  assert(lp->diving == lp->divinglazyapplied);
11957  }
11958 
11959  /* flush changes to the LP solver */
11960  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
11961  assert(lp->flushed);
11962 
11963  /* 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
11964  * to run again anyway, since there seems to be some time left / the time limit was increased
11965  */
11966  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
11967  {
11968  SCIP_Bool* primalfeaspointer;
11969  SCIP_Bool* dualfeaspointer;
11970  SCIP_Bool primalfeasible;
11971  SCIP_Bool dualfeasible;
11972  SCIP_Bool rayfeasible;
11973  SCIP_Bool tightprimfeastol;
11974  SCIP_Bool tightdualfeastol;
11975  SCIP_Bool fromscratch;
11976  SCIP_Bool wasfromscratch;
11977  SCIP_Longint oldnlps;
11978  int fastmip;
11979 
11980  /* set initial LP solver settings */
11981  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
11982  tightprimfeastol = FALSE;
11983  tightdualfeastol = FALSE;
11984  fromscratch = FALSE;
11985  primalfeasible = FALSE;
11986  dualfeasible = FALSE;
11987  wasfromscratch = (stat->nlps == 0);
11988 
11989  SOLVEAGAIN:
11990  /* solve the LP */
11991  oldnlps = stat->nlps;
11992  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
11993  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11994  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
11995  assert(!(*lperror) || !lp->solved);
11996 
11997  /* check for error */
11998  if( *lperror )
11999  {
12000  retcode = SCIP_OKAY;
12001  goto TERMINATE;
12002  }
12003 
12004  /* evaluate solution status */
12005  switch( SCIPlpGetSolstat(lp) )
12006  {
12008  /* get LP solution and possibly check the solution's feasibility again */
12009  if( set->lp_checkprimfeas )
12010  primalfeaspointer = &primalfeasible;
12011  else
12012  {
12013  /* believe in the primal feasibility of the LP solution */
12014  primalfeasible = TRUE;
12015  primalfeaspointer = NULL;
12016  }
12017  if( set->lp_checkdualfeas )
12018  dualfeaspointer = &dualfeasible;
12019  else
12020  {
12021  /* believe in the dual feasibility of the LP solution */
12022  dualfeasible = TRUE;
12023  dualfeaspointer = NULL;
12024  }
12025 
12026  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12027 
12028  /* in debug mode, check that lazy bounds (if present) are not violated */
12029  checkLazyBounds(lp, set);
12030 
12031  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12032  {
12033  /* update ages and remove obsolete columns and rows from LP */
12034  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12035  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12036  {
12037  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12038  }
12039 
12040  if( !lp->solved )
12041  {
12042  /* resolve LP after removing obsolete columns and rows */
12043  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12044  aging = FALSE; /* to prevent infinite loops */
12045  goto SOLVEAGAIN;
12046  }
12047  }
12048  if( !primalfeasible || !dualfeasible )
12049  {
12051 
12052  if( (fastmip > 0) && simplex )
12053  {
12054  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12055  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12056  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12057  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12058  fastmip = 0;
12059  goto SOLVEAGAIN;
12060  }
12061  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12062  {
12063  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12064  * tolerance
12065  */
12066  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12067  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12068  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12069  tightprimfeastol = tightprimfeastol || !primalfeasible;
12070  tightdualfeastol = tightdualfeastol || !dualfeasible;
12071  goto SOLVEAGAIN;
12072  }
12073  else if( !fromscratch && !wasfromscratch && simplex )
12074  {
12075  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12076  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12077  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12078  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12079  fromscratch = TRUE;
12080  goto SOLVEAGAIN;
12081  }
12082  else
12083  {
12084  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12085  "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
12086  lp->solved = FALSE;
12088  *lperror = TRUE;
12089  }
12090  }
12091  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12092  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12093  lp->lpsolstat, lp->cutoffbound);
12094  break;
12095 
12097  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12098  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12099  {
12100  if( SCIPlpiHasDualRay(lp->lpi) )
12101  {
12102  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12103  }
12104  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12105  * with the primal simplex due to numerical problems) - treat this case like an LP error
12106  */
12107  else
12108  {
12109  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12110  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12111  lp->solved = FALSE;
12113  *lperror = TRUE;
12114  }
12115  }
12116  break;
12117 
12119  if( set->lp_checkprimfeas )
12120  {
12121  /* get unbounded LP solution and check the solution's feasibility again */
12122  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12123  }
12124  else
12125  {
12126  /* get unbounded LP solution believing in the feasibility of the LP solution */
12127  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12128 
12129  primalfeasible = TRUE;
12130  rayfeasible = TRUE;
12131  }
12132 
12133  /* in debug mode, check that lazy bounds (if present) are not violated */
12134  checkLazyBounds(lp, set);
12135 
12136  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12137  primalfeasible, rayfeasible);
12138 
12139  if( !primalfeasible || !rayfeasible )
12140  {
12142 
12143  if( (fastmip > 0) && simplex )
12144  {
12145  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12146  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12147  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12148  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12149  fastmip = 0;
12150  goto SOLVEAGAIN;
12151  }
12152  else if( !tightprimfeastol )
12153  {
12154  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12155  * tolerance
12156  */
12157  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12158  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again with tighter primal feasibility tolerance\n",
12159  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12160  tightprimfeastol = TRUE;
12161  goto SOLVEAGAIN;
12162  }
12163  else if( !fromscratch && simplex )
12164  {
12165  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12166  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12167  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12168  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12169  fromscratch = TRUE;
12170  goto SOLVEAGAIN;
12171  }
12172  else
12173  {
12174  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12175  * forget about the LP at this node and mark it to be unsolved
12176  */
12177  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12178  "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in unbounded LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
12179  lp->solved = FALSE;
12181  *lperror = TRUE;
12182  }
12183  }
12184 
12185  break;
12186 
12188  assert(!lpCutoffDisabled(set));
12189  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12190  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12191  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12192  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12193  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12194  * FASTMIP and solve again.
12195  */
12196  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12197  {
12198  SCIP_LPI* lpi;
12199  SCIP_Real objval;
12200 
12201  lpi = SCIPlpGetLPI(lp);
12202 
12203  assert(lpi != NULL);
12204  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12205  * the assert by using !SCIPsetIsFeasNegative()
12206  */
12207  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiuobjlim));
12208 
12209  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12210 
12211  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12212  if( SCIPsetIsLT(set, objval, lp->lpiuobjlim) )
12213  {
12214  SCIP_Real tmpcutoff;
12215  char tmppricingchar;
12216  SCIP_LPSOLSTAT solstat;
12217 
12218  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiuobjlim, but status objlimit\n", objval, lp->lpiuobjlim);
12219 
12220  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12221  fromscratch = FALSE;
12222 
12223  /* temporarily disable cutoffbound, which also disables the objective limit */
12224  tmpcutoff = lp->cutoffbound;
12225  lp->cutoffbound = SCIPlpiInfinity(lpi);
12226 
12227  /* set lp pricing strategy to steepest edge */
12228  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12229  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12230 
12231  /* resolve LP with an iteration limit of 1 */
12232  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12233  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12234 
12235  /* reinstall old cutoff bound and lp pricing strategy */
12236  lp->cutoffbound = tmpcutoff;
12237  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12238 
12239  /* get objective value */
12240  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12241 
12242  /* get solution status for the lp */
12243  solstat = SCIPlpGetSolstat(lp);
12244  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12245 
12246  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12247  {
12248  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12249  }
12250 
12251  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12252  fastmip = 0;
12253 
12254  /* the solution is still not exceeding the objective limit and the solving process
12255  * was stopped due to time or iteration limit, solve again with fastmip turned off
12256  */
12257  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12258  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12259  {
12260  assert(!(*lperror));
12261 
12262  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12263  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12264 
12265  /* get objective value */
12266  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12267 
12268  /* get solution status for the lp */
12269  solstat = SCIPlpGetSolstat(lp);
12270 
12271  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12272  }
12273 
12274  /* check for lp errors */
12275  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12276  {
12277  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12278  lp->solved = FALSE;
12280 
12281  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12282  goto TERMINATE;
12283  }
12284 
12285  lp->solved = TRUE;
12286 
12287  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12288  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12289  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12290  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12291  {
12292  /* get LP solution and possibly check the solution's feasibility again */
12293  if( set->lp_checkprimfeas )
12294  primalfeaspointer = &primalfeasible;
12295  else
12296  {
12297  /* believe in the primal feasibility of the LP solution */
12298  primalfeasible = TRUE;
12299  primalfeaspointer = NULL;
12300  }
12301  if( set->lp_checkdualfeas )
12302  dualfeaspointer = &dualfeasible;
12303  else
12304  {
12305  /* believe in the dual feasibility of the LP solution */
12306  dualfeasible = TRUE;
12307  dualfeaspointer = NULL;
12308  }
12309 
12310  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12311 
12312  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12313  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12314  {
12315  checkLazyBounds(lp, set);
12316  }
12317 
12318  /* if objective value is larger than the cutoff bound, set solution status to objective
12319  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12320  * this was already done in the lpSolve() method
12321  */
12322  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12323  {
12325  lp->lpobjval = SCIPsetInfinity(set);
12326  }
12327 
12328  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12329  * the cutoffbound; mark the LP to be unsolved
12330  */
12331  if( !primalfeasible || !dualfeasible
12332  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12333  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12334  {
12335  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
12336  "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
12337  lp->solved = FALSE;
12339  *lperror = TRUE;
12340  }
12341 
12342  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12343  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12344  lp->lpsolstat, lp->cutoffbound);
12345  }
12346  /* infeasible solution */
12347  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12348  {
12349  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12350  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12351  }
12352  /* unbounded solution */
12353  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12354  {
12355  if( set->lp_checkprimfeas )
12356  {
12357  /* get unbounded LP solution and check the solution's feasibility again */
12358  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12359  }
12360  else
12361  {
12362  /* get unbounded LP solution believing in its feasibility */
12363  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12364 
12365  primalfeasible = TRUE;
12366  rayfeasible = TRUE;
12367  }
12368 
12369  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12370 
12371  /* in debug mode, check that lazy bounds (if present) are not violated */
12372  checkLazyBounds(lp, set);
12373 
12374  if( !primalfeasible || !rayfeasible )
12375  {
12376  /* unbounded solution is infeasible (this can happen due to numerical problems):
12377  * forget about the LP at this node and mark it to be unsolved
12378 
12379  * @todo: like in the default LP solving evaluation, solve without fastmip,
12380  * with tighter feasibility tolerance and from scratch
12381  */
12382  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12383  "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in unbounded LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
12384  lp->solved = FALSE;
12386  *lperror = TRUE;
12387  }
12388 
12389  }
12390 
12391  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12392  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12394  }
12395  else
12396  {
12397  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12398  }
12399  }
12400  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12401  {
12402  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12403  }
12404  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12405  break;
12406 
12408  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12409  break;
12410 
12412  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12413 
12414  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12415  stat->nclockskipsleft = 0;
12416  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12417  {
12418  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12419  "you might consider switching the clock type of SCIP\n");
12420  stat->status = SCIP_STATUS_TIMELIMIT;
12421  }
12422  break;
12423 
12424  case SCIP_LPSOLSTAT_ERROR:
12426  SCIPerrorMessage("error in LP solver\n");
12427  retcode = SCIP_LPERROR;
12428  goto TERMINATE;
12429 
12430  default:
12431  SCIPerrorMessage("unknown LP solution status\n");
12432  retcode = SCIP_ERROR;
12433  goto TERMINATE;
12434  }
12435  }
12436  assert(!(*lperror) || !lp->solved);
12437 
12438  TERMINATE:
12439  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12440  * may happen that we continue to solve from scratch during strong branching */
12441  if( lp->lpifromscratch )
12442  {
12443  SCIP_Bool success;
12444  (void) lpSetFromscratch(lp, FALSE, &success);
12445  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12446  }
12447 
12448  return retcode;
12449 }
12450 
12451 /** gets solution status of current LP */
12453  SCIP_LP* lp /**< current LP data */
12454  )
12455 {
12456  assert(lp != NULL);
12457  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12458 
12459  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12460 }
12461 
12462 /** gets objective value of current LP
12463  *
12464  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12465  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12466  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12467  */
12469  SCIP_LP* lp, /**< current LP data */
12470  SCIP_SET* set, /**< global SCIP settings */
12471  SCIP_PROB* prob /**< problem data */
12472  )
12473 {
12474  assert(lp != NULL);
12475  assert(lp->solved);
12476  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12477  assert(set != NULL);
12478 
12479  if( !lp->flushed )
12480  return SCIP_INVALID;
12481  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12482  return lp->lpobjval;
12483  else if( lp->looseobjvalinf > 0 )
12484  return -SCIPsetInfinity(set);
12485  else
12486  {
12487  /* recalculate the loose objective value, if needed */
12488  if( !lp->looseobjvalid )
12489  recomputeLooseObjectiveValue(lp, set, prob);
12490 
12491  return lp->lpobjval + lp->looseobjval;
12492  }
12493 }
12494 
12495 /** gets part of objective value of current LP that results from COLUMN variables only */
12497  SCIP_LP* lp /**< current LP data */
12498  )
12499 {
12500  assert(lp != NULL);
12501  assert(lp->solved);
12502 
12503  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12504 }
12505 
12506 /** gets part of objective value of current LP that results from LOOSE variables only */
12508  SCIP_LP* lp, /**< current LP data */
12509  SCIP_SET* set, /**< global SCIP settings */
12510  SCIP_PROB* prob /**< problem data */
12511  )
12512 {
12513  assert(lp != NULL);
12514  assert(lp->solved);
12515  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12516  assert(set != NULL);
12517 
12518  if( !lp->flushed )
12519  return SCIP_INVALID;
12520  else if( lp->looseobjvalinf > 0 )
12521  return -SCIPsetInfinity(set);
12522  else
12523  return getFiniteLooseObjval(lp, set, prob);
12524 }
12525 
12526 /** remembers the current LP objective value as root solution value */
12528  SCIP_LP* lp, /**< current LP data */
12529  SCIP_SET* set, /**< global SCIP settings */
12530  SCIP_PROB* prob /**< problem data */
12531  )
12532 {
12533  assert(lp != NULL);
12534 
12536  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12537 }
12538 
12539 /** invalidates the root LP solution value */
12541  SCIP_LP* lp /**< current LP data */
12542  )
12543 {
12544  assert(lp != NULL);
12545 
12546  lp->rootlpobjval = SCIP_INVALID;
12548 }
12549 
12550 /** recomputes local and global pseudo objective values */
12552  SCIP_LP* lp, /**< current LP data */
12553  SCIP_SET* set, /**< global SCIP settings */
12554  SCIP_PROB* prob /**< problem data */
12555  )
12556 {
12557  SCIP_VAR** vars;
12558  int nvars;
12559  int v;
12560 
12561  assert(lp != NULL);
12562  assert(set != NULL);
12563  assert(prob != NULL);
12564 
12565  vars = prob->vars;
12566  nvars = prob->nvars;
12567 
12568  lp->glbpseudoobjvalinf = 0;
12569  lp->glbpseudoobjval = 0.0;
12570 
12571  lp->pseudoobjvalinf = 0;
12572  lp->pseudoobjval = 0.0;
12573 
12574  for( v = 0; v < nvars; ++v )
12575  {
12576  SCIP_Real obj = SCIPvarGetObj(vars[v]);
12577 
12578  if( SCIPsetIsPositive(set, obj) )
12579  {
12580  /* update the global pseudo objective value */
12581  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
12582  ++(lp->glbpseudoobjvalinf);
12583  else
12584  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
12585 
12586  /* update the local pseudo objective value */
12587  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
12588  ++(lp->pseudoobjvalinf);
12589  else
12590  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
12591  }
12592 
12593  if( SCIPsetIsNegative(set, obj) )
12594  {
12595  /* update the global pseudo objective value */
12596  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
12597  ++(lp->glbpseudoobjvalinf);
12598  else
12599  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
12600 
12601  /* update the local pseudo objective value */
12602  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
12603  ++(lp->pseudoobjvalinf);
12604  else
12605  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
12606  }
12607  }
12608 
12609  /* the recomputed values are reliable */
12611  lp->glbpseudoobjvalid = TRUE;
12612  lp->relpseudoobjval = lp->pseudoobjval;
12613  lp->pseudoobjvalid = TRUE;
12614 }
12615 
12616 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
12617  * global bound
12618  */
12620  SCIP_LP* lp, /**< current LP data */
12621  SCIP_SET* set, /**< global SCIP settings */
12622  SCIP_PROB* prob /**< problem data */
12623  )
12624 {
12625  assert(lp != NULL);
12626  assert(lp->glbpseudoobjvalinf >= 0);
12627  assert(set != NULL);
12628 
12629  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
12630  return -SCIPsetInfinity(set);
12631  else
12632  {
12633  /* recalculate the global pseudo solution value, if needed */
12634  if( !lp->glbpseudoobjvalid )
12635  recomputeGlbPseudoObjectiveValue(lp, set, prob);
12636 
12637  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
12638  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
12639  return -SCIPsetInfinity(set);
12640 
12641  return lp->glbpseudoobjval;
12642  }
12643 }
12644 
12645 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
12646  * objective function) local bound
12647  */
12649  SCIP_LP* lp, /**< current LP data */
12650  SCIP_SET* set, /**< global SCIP settings */
12651  SCIP_PROB* prob /**< problem data */
12652  )
12653 {
12654  assert(lp != NULL);
12655  assert(lp->pseudoobjvalinf >= 0);
12656  assert(set != NULL);
12657 
12658  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12659  return -SCIPsetInfinity(set);
12660  else
12661  {
12662  /* recalculate the pseudo solution value, if needed */
12663  if( !lp->pseudoobjvalid )
12664  recomputePseudoObjectiveValue(lp, set, prob);
12665 
12666  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
12667  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
12668  return -SCIPsetInfinity(set);
12669 
12670  return lp->pseudoobjval;
12671  }
12672 }
12673 
12674 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
12676  SCIP_LP* lp, /**< current LP data */
12677  SCIP_SET* set, /**< global SCIP settings */
12678  SCIP_PROB* prob, /**< problem data */
12679  SCIP_VAR* var, /**< problem variable */
12680  SCIP_Real oldbound, /**< old value for bound */
12681  SCIP_Real newbound, /**< new value for bound */
12682  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12683  )
12684 {
12685  SCIP_Real pseudoobjval;
12686  int pseudoobjvalinf;
12687  SCIP_Real obj;
12688 
12689  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
12690  pseudoobjvalinf = lp->pseudoobjvalinf;
12691  obj = SCIPvarGetObj(var);
12692  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12693  {
12694  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12695  pseudoobjvalinf--;
12696  else
12697  pseudoobjval -= oldbound * obj;
12698  assert(pseudoobjvalinf >= 0);
12699  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12700  pseudoobjvalinf++;
12701  else
12702  pseudoobjval += newbound * obj;
12703  }
12704  assert(pseudoobjvalinf >= 0);
12705 
12706  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12707  return -SCIPsetInfinity(set);
12708  else
12709  return pseudoobjval;
12710 }
12711 
12712 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
12713  * perform calculations with interval arithmetic to get an exact lower bound
12714  */
12716  SCIP_LP* lp, /**< current LP data */
12717  SCIP_SET* set, /**< global SCIP settings */
12718  SCIP_VAR* var, /**< problem variable */
12719  SCIP_Real oldbound, /**< old value for bound */
12720  SCIP_Real newbound, /**< new value for bound */
12721  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12722  )
12723 {
12724  SCIP_Real pseudoobjval;
12725  int pseudoobjvalinf;
12726  SCIP_Real obj;
12727 
12728  assert(lp->pseudoobjvalid);
12729 
12730  pseudoobjval = lp->pseudoobjval;
12731  pseudoobjvalinf = lp->pseudoobjvalinf;
12732  obj = SCIPvarGetObj(var);
12733  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12734  {
12735  SCIP_INTERVAL objint;
12736  SCIP_INTERVAL bd;
12737  SCIP_INTERVAL prod;
12738  SCIP_INTERVAL psval;
12739 
12740  SCIPintervalSet(&psval, pseudoobjval);
12741  SCIPintervalSet(&objint, SCIPvarGetObj(var));
12742 
12743  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12744  pseudoobjvalinf--;
12745  else
12746  {
12747  SCIPintervalSet(&bd, oldbound);
12748  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12749  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
12750  }
12751  assert(pseudoobjvalinf >= 0);
12752  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12753  pseudoobjvalinf++;
12754  else
12755  {
12756  SCIPintervalSet(&bd, newbound);
12757  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12758  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
12759  }
12760 
12761  pseudoobjval = SCIPintervalGetInf(psval);
12762  }
12763  assert(pseudoobjvalinf >= 0);
12764 
12765  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12766  return -SCIPsetInfinity(set);
12767  else
12768  return pseudoobjval;
12769 }
12770 
12771 /** compute the objective delta due the new objective coefficient */
12772 static
12774  SCIP_SET* set, /**< global SCIP settings */
12775  SCIP_Real oldobj, /**< old objective value of variable */
12776  SCIP_Real newobj, /**< new objective value of variable */
12777  SCIP_Real lb, /**< lower bound of variable */
12778  SCIP_Real ub, /**< upper bound of variable */
12779  SCIP_Real* deltaval, /**< pointer to store the delta value */
12780  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12781  )
12782 {
12783  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
12784  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
12785  assert(!SCIPsetIsInfinity(set, lb));
12786  assert(!SCIPsetIsInfinity(set, -ub));
12787  assert(!SCIPsetIsEQ(set, oldobj, newobj));
12788 
12789  (*deltaval) = 0.0;
12790  (*deltainf) = 0;
12791 
12792  if( SCIPsetIsPositive(set, oldobj) )
12793  {
12794  /* sign of objective did not change */
12795  if( SCIPsetIsPositive(set, newobj) )
12796  {
12797  /* if the bound is finite, calculate the deltaval */
12798  if( !SCIPsetIsInfinity(set, -lb) )
12799  (*deltaval) = lb * (newobj - oldobj);
12800  }
12801  /* sign of objective did change, so the best bound does change */
12802  else if( SCIPsetIsNegative(set, newobj) )
12803  {
12804  if( SCIPsetIsInfinity(set, -lb) )
12805  {
12806  /* old best bound was infinite while new one is not */
12807  if( !SCIPsetIsInfinity(set, ub) )
12808  {
12809  (*deltainf) = -1;
12810  (*deltaval) = ub * newobj;
12811  }
12812  }
12813  else
12814  {
12815  /* new best bound is infinite while old one was not */
12816  if( SCIPsetIsInfinity(set, ub) )
12817  {
12818  (*deltainf) = 1;
12819  (*deltaval) = -lb * oldobj;
12820  }
12821  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12822  else
12823  {
12824  (*deltaval) = (ub * newobj) - (lb * oldobj);
12825  }
12826  }
12827  }
12828  /* new objective is 0.0 */
12829  else
12830  {
12831  if( SCIPsetIsInfinity(set, -lb) )
12832  (*deltainf) = -1;
12833  else
12834  (*deltaval) = -lb * oldobj;
12835  }
12836 
12837  }
12838  else if( SCIPsetIsNegative(set, oldobj) )
12839  {
12840  /* sign of objective did not change */
12841  if( SCIPsetIsNegative(set, newobj) )
12842  {
12843  /* if the bound is finite, calculate the deltaval */
12844  if( !SCIPsetIsInfinity(set, ub) )
12845  (*deltaval) = ub * (newobj - oldobj);
12846  }
12847  /* sign of objective did change, so the best bound does change */
12848  else if( SCIPsetIsPositive(set, newobj) )
12849  {
12850  if( SCIPsetIsInfinity(set, ub) )
12851  {
12852  /* old best bound was infinite while new one is not */
12853  if( !SCIPsetIsInfinity(set, -lb) )
12854  {
12855  (*deltainf) = -1;
12856  (*deltaval) = lb * newobj;
12857  }
12858  }
12859  else
12860  {
12861  /* new best bound is infinite while old one was not */
12862  if( SCIPsetIsInfinity(set, -lb) )
12863  {
12864  (*deltainf) = 1;
12865  (*deltaval) = -ub * oldobj;
12866  }
12867  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12868  else
12869  {
12870  (*deltaval) = (lb * newobj) - (ub * oldobj);
12871  }
12872  }
12873  }
12874  /* new objective is 0.0 */
12875  else
12876  {
12877  if( SCIPsetIsInfinity(set, ub) )
12878  (*deltainf) = -1;
12879  else
12880  (*deltaval) = -ub * oldobj;
12881  }
12882  }
12883  /* old objective was 0.0 */
12884  else
12885  {
12886  if( SCIPsetIsNegative(set, newobj) )
12887  {
12888  if( SCIPsetIsInfinity(set, ub) )
12889  (*deltainf) = 1;
12890  else
12891  (*deltaval) = ub * newobj;
12892  }
12893  else if( SCIPsetIsPositive(set, newobj) )
12894  {
12895  if( SCIPsetIsInfinity(set, -lb) )
12896  (*deltainf) = 1;
12897  else
12898  (*deltaval) = lb * newobj;
12899  }
12900  }
12901 }
12902 
12903 /** compute the objective delta due the new lower bound */
12904 static
12906  SCIP_SET* set, /**< global SCIP settings */
12907  SCIP_Real obj, /**< objective value of variable */
12908  SCIP_Real oldlb, /**< old lower bound of variable */
12909  SCIP_Real newlb, /**< new lower bound of variable */
12910  SCIP_Real* deltaval, /**< pointer to store the delta value */
12911  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12912  )
12913 {
12914  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
12915  assert(!SCIPsetIsInfinity(set, oldlb));
12916  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
12917  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
12918 
12919  if( SCIPsetIsInfinity(set, -oldlb) )
12920  {
12921  if( !SCIPsetIsInfinity(set, newlb) )
12922  {
12923  (*deltainf) = -1;
12924  (*deltaval) = newlb * obj;
12925  }
12926  else
12927  {
12928  (*deltainf) = 0;
12929  (*deltaval) = 0.0;
12930  }
12931  }
12932  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
12933  {
12934  (*deltainf) = 1;
12935  (*deltaval) = -oldlb * obj;
12936  }
12937  else
12938  {
12939  (*deltainf) = 0;
12940  (*deltaval) = obj * (newlb - oldlb);
12941  }
12942 }
12943 
12944 /** compute the objective delta due the new upper bound */
12945 static
12947  SCIP_SET* set, /**< global SCIP settings */
12948  SCIP_Real obj, /**< objective value of variable */
12949  SCIP_Real oldub, /**< old upper bound of variable */
12950  SCIP_Real newub, /**< new upper bound of variable */
12951  SCIP_Real* deltaval, /**< pointer to store the delta value */
12952  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12953  )
12954 {
12955  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
12956  assert(!SCIPsetIsInfinity(set, -oldub));
12957  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
12958  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
12959 
12960  if( SCIPsetIsInfinity(set, oldub) )
12961  {
12962  if( !SCIPsetIsInfinity(set, -newub) )
12963  {
12964  (*deltainf) = -1;
12965  (*deltaval) = newub * obj;
12966  }
12967  else
12968  {
12969  (*deltainf) = 0;
12970  (*deltaval) = 0.0;
12971  }
12972  }
12973  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
12974  {
12975  (*deltainf) = 1;
12976  (*deltaval) = -oldub * obj;
12977  }
12978  else
12979  {
12980  (*deltainf) = 0;
12981  (*deltaval) = obj * (newub - oldub);
12982  }
12983 }
12984 
12985 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
12986 static
12988  SCIP_LP* lp, /**< current LP data */
12989  SCIP_SET* set, /**< global SCIP settings */
12990  SCIP_VAR* var, /**< problem variable that changed */
12991  SCIP_Real deltaval, /**< delta value in the objective function */
12992  int deltainf, /**< delta value for the number of variables with infinite best bound */
12993  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
12994  SCIP_Bool loose, /**< should the loose objective value be updated? */
12995  SCIP_Bool global /**< should the global pseudo objective value be updated? */
12996  )
12997 {
12998  assert(lp != NULL);
12999  assert(lp->looseobjvalinf >= 0);
13000  assert(lp->pseudoobjvalinf >= 0);
13001  assert(lp->glbpseudoobjvalinf >= 0);
13002 
13003  /* update the pseudo objective value */
13004  if( local )
13005  {
13006  lp->pseudoobjvalinf += deltainf;
13007  if( lp->pseudoobjvalid )
13008  {
13009  lp->pseudoobjval += deltaval;
13010 
13011  /* if the absolute value was increased, this is regarded as reliable,
13012  * otherwise, we check whether we can still trust the updated value
13013  */
13014  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13015  lp->relpseudoobjval = lp->pseudoobjval;
13016  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13017  lp->pseudoobjvalid = FALSE;
13018  }
13019 
13020  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13022  loose = TRUE;
13023  }
13024  /* update the loose objective value */
13025  if( loose )
13026  {
13027  lp->looseobjvalinf += deltainf;
13028 
13029  if( deltaval != 0.0 && lp->looseobjvalid )
13030  {
13031  lp->looseobjval += deltaval;
13032 
13033  /* if the absolute value was increased, this is regarded as reliable,
13034  * otherwise, we check whether we can still trust the updated value
13035  */
13036  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13037  lp->rellooseobjval = lp->looseobjval;
13038  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13039  lp->looseobjvalid = FALSE;
13040  }
13041  }
13042  /* update the root pseudo objective values */
13043  if( global )
13044  {
13045  lp->glbpseudoobjvalinf += deltainf;
13046  if( lp->glbpseudoobjvalid )
13047  {
13048  lp->glbpseudoobjval += deltaval;
13049 
13050  /* if the absolute value was increased, this is regarded as reliable,
13051  * otherwise, we check whether we can still trust the updated value
13052  */
13056  lp->glbpseudoobjvalid = FALSE;
13057  }
13058  }
13059 
13060  assert(lp->looseobjvalinf >= 0);
13061  assert(lp->pseudoobjvalinf >= 0);
13062  assert(lp->glbpseudoobjvalinf >= 0);
13063 }
13064 
13065 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13066  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13067  */
13068 static
13070  SCIP_LP* lp, /**< current LP data */
13071  SCIP_SET* set, /**< global SCIP settings */
13072  SCIP_VAR* var, /**< problem variable that changed */
13073  SCIP_Real oldobj, /**< old objective value of variable */
13074  SCIP_Real oldlb, /**< old objective value of variable */
13075  SCIP_Real oldub, /**< old objective value of variable */
13076  SCIP_Real newobj, /**< new objective value of variable */
13077  SCIP_Real newlb, /**< new objective value of variable */
13078  SCIP_Real newub /**< new objective value of variable */
13079  )
13080 {
13081  SCIP_INTERVAL deltaval;
13082  SCIP_INTERVAL bd;
13083  SCIP_INTERVAL obj;
13084  SCIP_INTERVAL prod;
13085  SCIP_INTERVAL psval;
13086  int deltainf;
13087 
13088  assert(lp != NULL);
13089  assert(lp->pseudoobjvalinf >= 0);
13090  assert(lp->looseobjvalinf >= 0);
13091  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13092  assert(!SCIPsetIsInfinity(set, oldlb));
13093  assert(!SCIPsetIsInfinity(set, -oldub));
13094  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13095  assert(!SCIPsetIsInfinity(set, newlb));
13096  assert(!SCIPsetIsInfinity(set, -newub));
13097  assert(var != NULL);
13098 
13100  {
13101  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13102  return SCIP_INVALIDDATA;
13103  }
13104 
13105  assert(SCIPvarGetProbindex(var) >= 0);
13106 
13107  SCIPintervalSet(&deltaval, 0.0);
13108  deltainf = 0;
13109 
13110  /* subtract old pseudo objective value */
13111  if( oldobj > 0.0 )
13112  {
13113  if( SCIPsetIsInfinity(set, -oldlb) )
13114  deltainf--;
13115  else
13116  {
13117  SCIPintervalSet(&bd, oldlb);
13118  SCIPintervalSet(&obj, oldobj);
13119  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13120  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13121  }
13122  }
13123  else if( oldobj < 0.0 )
13124  {
13125  if( SCIPsetIsInfinity(set, oldub) )
13126  deltainf--;
13127  else
13128  {
13129  SCIPintervalSet(&bd, oldub);
13130  SCIPintervalSet(&obj, oldobj);
13131  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13132  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13133  }
13134  }
13135 
13136  /* add new pseudo objective value */
13137  if( newobj > 0.0 )
13138  {
13139  if( SCIPsetIsInfinity(set, -newlb) )
13140  deltainf++;
13141  else
13142  {
13143  SCIPintervalSet(&bd, newlb);
13144  SCIPintervalSet(&obj, newobj);
13145  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13146  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13147  }
13148  }
13149  else if( newobj < 0.0 )
13150  {
13151  if( SCIPsetIsInfinity(set, newub) )
13152  deltainf++;
13153  else
13154  {
13155  SCIPintervalSet(&bd, newub);
13156  SCIPintervalSet(&obj, newobj);
13157  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13158  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13159  }
13160  }
13161 
13162  /* update the pseudo and loose objective values */
13163  SCIPintervalSet(&psval, lp->pseudoobjval);
13164  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13165  lp->pseudoobjval = SCIPintervalGetInf(psval);
13166  lp->pseudoobjvalinf += deltainf;
13168  {
13169  SCIPintervalSet(&psval, lp->looseobjval);
13170  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13171  lp->looseobjval = SCIPintervalGetInf(psval);
13172  lp->looseobjvalinf += deltainf;
13173  }
13174 
13175  assert(lp->pseudoobjvalinf >= 0);
13176  assert(lp->looseobjvalinf >= 0);
13177 
13178  return SCIP_OKAY;
13179 }
13180 
13181 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13183  SCIP_LP* lp, /**< current LP data */
13184  SCIP_SET* set, /**< global SCIP settings */
13185  SCIP_VAR* var, /**< problem variable that changed */
13186  SCIP_Real oldobj, /**< old objective value of variable */
13187  SCIP_Real newobj /**< new objective value of variable */
13188  )
13189 {
13190  assert(set != NULL);
13191  assert(var != NULL);
13192 
13193  if( set->misc_exactsolve )
13194  {
13195  if( oldobj != newobj ) /*lint !e777*/
13196  {
13197  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13198  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13199  }
13200  }
13201  else
13202  {
13203  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13204  {
13205  SCIP_Real deltaval;
13206  int deltainf;
13207 
13209  assert(SCIPvarGetProbindex(var) >= 0);
13210 
13211  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13212  * domain of the variable are the same
13213  */
13214  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13215  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13216 
13217  /* compute the pseudo objective delta due the new objective coefficient */
13218  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13219 
13220  /* update the local pseudo objective value */
13221  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13222 
13223  /* compute the pseudo objective delta due the new objective coefficient */
13224  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13225 
13226  /* update the global pseudo objective value */
13227  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13228  }
13229  }
13230 
13231  return SCIP_OKAY;
13232 }
13233 
13234 
13235 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13237  SCIP_LP* lp, /**< current LP data */
13238  SCIP_SET* set, /**< global SCIP settings */
13239  SCIP_VAR* var, /**< problem variable that changed */
13240  SCIP_Real oldlb, /**< old lower bound of variable */
13241  SCIP_Real newlb /**< new lower bound of variable */
13242  )
13243 {
13244  assert(set != NULL);
13245  assert(var != NULL);
13246 
13247  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13248  {
13249  SCIP_Real deltaval;
13250  int deltainf;
13251 
13252  /* compute the pseudo objective delta due the new lower bound */
13253  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13254 
13255  /* update the root pseudo objective values */
13256  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13257 
13258  }
13259 
13260  return SCIP_OKAY;
13261 }
13262 
13263 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13265  SCIP_LP* lp, /**< current LP data */
13266  SCIP_SET* set, /**< global SCIP settings */
13267  SCIP_VAR* var, /**< problem variable that changed */
13268  SCIP_Real oldlb, /**< old lower bound of variable */
13269  SCIP_Real newlb /**< new lower bound of variable */
13270  )
13271 {
13272  assert(set != NULL);
13273  assert(var != NULL);
13274 
13275  if( set->misc_exactsolve )
13276  {
13277  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13278  {
13279  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13280  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13281  }
13282  }
13283  else
13284  {
13285  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13286  {
13287  SCIP_Real deltaval;
13288  int deltainf;
13289 
13291  assert(SCIPvarGetProbindex(var) >= 0);
13292 
13293  /* compute the pseudo objective delta due the new lower bound */
13294  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13295 
13296  /* update the pseudo and loose objective values */
13297  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13298  }
13299  }
13300 
13301  return SCIP_OKAY;
13302 }
13303 
13304 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13306  SCIP_LP* lp, /**< current LP data */
13307  SCIP_SET* set, /**< global SCIP settings */
13308  SCIP_VAR* var, /**< problem variable that changed */
13309  SCIP_Real oldub, /**< old upper bound of variable */
13310  SCIP_Real newub /**< new upper bound of variable */
13311  )
13312 {
13313  assert(set != NULL);
13314  assert(var != NULL);
13315 
13316  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13317  {
13318  SCIP_Real deltaval;
13319  int deltainf;
13320 
13321  /* compute the pseudo objective delta due the new upper bound */
13322  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13323 
13324  /* update the root pseudo objective values */
13325  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13326  }
13327 
13328  return SCIP_OKAY;
13329 }
13330 
13331 /** updates current pseudo objective value for a change in a variable's upper bound */
13333  SCIP_LP* lp, /**< current LP data */
13334  SCIP_SET* set, /**< global SCIP settings */
13335  SCIP_VAR* var, /**< problem variable that changed */
13336  SCIP_Real oldub, /**< old upper bound of variable */
13337  SCIP_Real newub /**< new upper bound of variable */
13338  )
13339 {
13340  assert(set != NULL);
13341  assert(var != NULL);
13342 
13343  if( set->misc_exactsolve )
13344  {
13345  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13346  {
13347  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13348  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13349  }
13350  }
13351  else
13352  {
13353  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13354  {
13355  SCIP_Real deltaval;
13356  int deltainf;
13357 
13359  assert(SCIPvarGetProbindex(var) >= 0);
13360 
13361  /* compute the pseudo objective delta due the new upper bound */
13362  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13363 
13364  /* update the pseudo and loose objective values */
13365  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13366  }
13367  }
13368 
13369  return SCIP_OKAY;
13370 }
13371 
13372 /** informs LP, that given variable was added to the problem */
13374  SCIP_LP* lp, /**< current LP data */
13375  SCIP_SET* set, /**< global SCIP settings */
13376  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13377  )
13378 {
13379  assert(lp != NULL);
13381  assert(SCIPvarGetProbindex(var) >= 0);
13382 
13383  /* add the variable to the loose objective value sum */
13384  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13385 
13386  /* update the loose variables counter */
13388  lp->nloosevars++;
13389 
13390  return SCIP_OKAY;
13391 }
13392 
13393 /** informs LP, that given variable is to be deleted from the problem */
13395  SCIP_LP* lp, /**< current LP data */
13396  SCIP_SET* set, /**< global SCIP settings */
13397  SCIP_VAR* var /**< variable that will be deleted from the problem */
13398  )
13399 {
13400  assert(lp != NULL);
13402  assert(SCIPvarGetProbindex(var) >= 0);
13403 
13404  /* subtract the variable from the loose objective value sum */
13405  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13406 
13407  /* update the loose variables counter */
13409  {
13410  SCIPlpDecNLoosevars(lp);
13411  }
13412 
13413  return SCIP_OKAY;
13414 }
13415 
13416 /** informs LP, that given formerly loose problem variable is now a column variable */
13417 static
13419  SCIP_LP* lp, /**< current LP data */
13420  SCIP_SET* set, /**< global SCIP settings */
13421  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13422  )
13423 {
13424  SCIP_Real obj;
13425  SCIP_Real lb;
13426  SCIP_Real ub;
13427 
13428  assert(lp != NULL);
13429  assert(lp->nloosevars > 0);
13430  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13431  assert(SCIPvarGetProbindex(var) >= 0);
13432  assert(lp->looseobjvalinf >= 0);
13433 
13434  obj = SCIPvarGetObj(var);
13435 
13436  /* update loose objective value */
13437  if( SCIPsetIsPositive(set, obj) )
13438  {
13439  lb = SCIPvarGetLbLocal(var);
13440  if( SCIPsetIsInfinity(set, -lb) )
13441  lp->looseobjvalinf--;
13442  else
13443  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13444  }
13445  else if( SCIPsetIsNegative(set, obj) )
13446  {
13447  ub = SCIPvarGetUbLocal(var);
13448  if( SCIPsetIsInfinity(set, ub) )
13449  lp->looseobjvalinf--;
13450  else
13451  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13452  }
13453 
13454  SCIPlpDecNLoosevars(lp);
13455 
13456  assert(lp->looseobjvalinf >= 0);
13457 
13458  return SCIP_OKAY;
13459 }
13460 
13461 /** informs LP, that given formerly loose problem variable is now a column variable
13462  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13463  */
13464 static
13466  SCIP_LP* lp, /**< current LP data */
13467  SCIP_SET* set, /**< global SCIP settings */
13468  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13469  )
13470 {
13471  SCIP_INTERVAL bd;
13472  SCIP_INTERVAL ob;
13473  SCIP_INTERVAL prod;
13474  SCIP_INTERVAL loose;
13475  SCIP_Real obj;
13476  SCIP_Real lb;
13477  SCIP_Real ub;
13478 
13479  assert(lp != NULL);
13480  assert(lp->nloosevars > 0);
13481  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13482  assert(SCIPvarGetProbindex(var) >= 0);
13483 
13484  obj = SCIPvarGetObj(var);
13485 
13486  SCIPintervalSet(&loose, lp->looseobjval);
13487 
13488  /* update loose objective value corresponding to the deletion of variable */
13489  if( obj > 0.0 )
13490  {
13491  lb = SCIPvarGetLbLocal(var);
13492  if( SCIPsetIsInfinity(set, -lb) )
13493  lp->looseobjvalinf--;
13494  else
13495  {
13496  SCIPintervalSet(&bd, lb);
13497  SCIPintervalSet(&ob, obj);
13498  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13499  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13500  }
13501  }
13502  else if( SCIPsetIsNegative(set, obj) )
13503  {
13504  ub = SCIPvarGetUbLocal(var);
13505  if( SCIPsetIsInfinity(set, ub) )
13506  lp->looseobjvalinf--;
13507  else
13508  {
13509  SCIPintervalSet(&bd, ub);
13510  SCIPintervalSet(&ob, obj);
13511  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13512  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13513  }
13514  }
13515  lp->nloosevars--;
13516 
13517  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13518  if( lp->nloosevars == 0 )
13519  {
13520  assert(lp->looseobjvalinf == 0);
13521  lp->looseobjval = 0.0;
13522  }
13523  else
13524  lp->looseobjval = SCIPintervalGetInf(loose);
13525 
13526  return SCIP_OKAY;
13527 }
13528 
13529 /** informs LP, that given formerly loose problem variable is now a column variable */
13531  SCIP_LP* lp, /**< current LP data */
13532  SCIP_SET* set, /**< global SCIP settings */
13533  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13534  )
13535 {
13536  assert(set != NULL);
13537 
13538  if( set->misc_exactsolve )
13539  {
13540  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13541  }
13542  else
13543  {
13544  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13545  }
13546 
13547  return SCIP_OKAY;
13548 }
13549 
13550 /** informs LP, that given formerly column problem variable is now again a loose variable */
13551 static
13553  SCIP_LP* lp, /**< current LP data */
13554  SCIP_SET* set, /**< global SCIP settings */
13555  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13556  )
13557 {
13558  SCIP_Real obj;
13559  SCIP_Real lb;
13560  SCIP_Real ub;
13561 
13562  assert(lp != NULL);
13563  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13564  assert(SCIPvarGetProbindex(var) >= 0);
13565  assert(lp->looseobjvalinf >= 0);
13566 
13567  obj = SCIPvarGetObj(var);
13568 
13569  /* update loose objective value corresponding to the addition of variable */
13570  if( SCIPsetIsPositive(set, obj) )
13571  {
13572  lb = SCIPvarGetLbLocal(var);
13573  if( SCIPsetIsInfinity(set, -lb) )
13574  lp->looseobjvalinf++;
13575  else
13576  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
13577  }
13578  else if( SCIPsetIsNegative(set, obj) )
13579  {
13580  ub = SCIPvarGetUbLocal(var);
13581  if( SCIPsetIsInfinity(set, ub) )
13582  lp->looseobjvalinf++;
13583  else
13584  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
13585  }
13586  lp->nloosevars++;
13587 
13588  assert(lp->looseobjvalinf >= 0);
13589 
13590  return SCIP_OKAY;
13591 }
13592 
13593 /** informs LP, that given formerly column problem variable is now again a loose variable
13594  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13595  */
13596 static
13598  SCIP_LP* lp, /**< current LP data */
13599  SCIP_SET* set, /**< global SCIP settings */
13600  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13601  )
13602 {
13603  SCIP_INTERVAL bd;
13604  SCIP_INTERVAL ob;
13605  SCIP_INTERVAL prod;
13606  SCIP_INTERVAL loose;
13607  SCIP_Real obj;
13608  SCIP_Real lb;
13609  SCIP_Real ub;
13610 
13611  assert(lp != NULL);
13612  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13613  assert(SCIPvarGetProbindex(var) >= 0);
13614 
13615  obj = SCIPvarGetObj(var);
13616 
13617  SCIPintervalSet(&loose, lp->looseobjval);
13618 
13619  /* update loose objective value corresponding to the deletion of variable */
13620  if( obj > 0.0 )
13621  {
13622  lb = SCIPvarGetLbLocal(var);
13623  if( SCIPsetIsInfinity(set, -lb) )
13624  lp->looseobjvalinf++;
13625  else
13626  {
13627  SCIPintervalSet(&bd, lb);
13628  SCIPintervalSet(&ob, obj);
13629  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13630  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
13631  }
13632  }
13633  else if( SCIPsetIsNegative(set, obj) )
13634  {
13635  ub = SCIPvarGetUbLocal(var);
13636  if( SCIPsetIsInfinity(set, ub) )
13637  lp->looseobjvalinf++;
13638  else
13639  {
13640  SCIPintervalSet(&bd, ub);
13641  SCIPintervalSet(&ob, obj);
13642  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13643  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
13644  }
13645  }
13646  lp->nloosevars++;
13647 
13648  lp->looseobjval = SCIPintervalGetInf(loose);
13649 
13650  return SCIP_OKAY;
13651 }
13652 
13653 /** informs LP, that given formerly column problem variable is now again a loose variable */
13655  SCIP_LP* lp, /**< current LP data */
13656  SCIP_SET* set, /**< global SCIP settings */
13657  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13658  )
13659 {
13660  assert(set != NULL);
13661 
13662  if( set->misc_exactsolve )
13663  {
13664  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
13665  }
13666  else
13667  {
13668  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
13669  }
13670 
13671  return SCIP_OKAY;
13672 }
13673 
13674 /** decrease the number of loose variables by one */
13676  SCIP_LP* lp /**< current LP data */
13677  )
13678 {
13679  assert(lp != NULL);
13680  assert(lp->nloosevars > 0);
13681 
13682  lp->nloosevars--;
13683 
13684  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13685  if( lp->nloosevars == 0 )
13686  {
13687  assert(lp->looseobjvalinf == 0);
13688  lp->looseobjval = 0.0;
13689  }
13690 }
13691 
13692 /** stores the LP solution in the columns and rows */
13694  SCIP_LP* lp, /**< current LP data */
13695  SCIP_SET* set, /**< global SCIP settings */
13696  SCIP_STAT* stat, /**< problem statistics */
13697  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
13698  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
13699  )
13700 {
13701  SCIP_COL** lpicols;
13702  SCIP_ROW** lpirows;
13703  SCIP_Real* primsol;
13704  SCIP_Real* dualsol;
13705  SCIP_Real* activity;
13706  SCIP_Real* redcost;
13707  SCIP_Real primalbound;
13708  SCIP_Real dualbound;
13709  SCIP_Bool stillprimalfeasible;
13710  SCIP_Bool stilldualfeasible;
13711  int* cstat;
13712  int* rstat;
13713  SCIP_Longint lpcount;
13714  int nlpicols;
13715  int nlpirows;
13716  int c;
13717  int r;
13718 
13719  assert(lp != NULL);
13720  assert(lp->flushed);
13721  assert(lp->solved);
13722  assert(set != NULL);
13723  assert(stat != NULL);
13724  assert(lp->validsollp <= stat->lpcount);
13725 
13726  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
13727  * corresponding flag immediately to FALSE to skip all checks
13728  */
13729  if( primalfeasible == NULL )
13730  stillprimalfeasible = FALSE;
13731  else
13732  {
13733  *primalfeasible = TRUE;
13734  stillprimalfeasible = TRUE;
13735  }
13736  if( dualfeasible == NULL )
13737  stilldualfeasible = FALSE;
13738  else
13739  {
13740  *dualfeasible = TRUE;
13741  stilldualfeasible = TRUE;
13742  }
13743 
13744  /* check if the values are already calculated */
13745  if( lp->validsollp == stat->lpcount )
13746  return SCIP_OKAY;
13747  lp->validsollp = stat->lpcount;
13748 
13749  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
13750  stat->lpcount, SCIPlpGetSolstat(lp));
13751 
13752  lpicols = lp->lpicols;
13753  lpirows = lp->lpirows;
13754  nlpicols = lp->nlpicols;
13755  nlpirows = lp->nlpirows;
13756  lpcount = stat->lpcount;
13757 
13758  /* get temporary memory */
13759  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
13760  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
13761  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
13762  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
13763  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
13764  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
13765 
13766  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
13767  if( lp->solisbasic )
13768  {
13769  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
13770  }
13771  else
13772  {
13773  BMSclearMemoryArray(cstat, nlpicols);
13774  BMSclearMemoryArray(rstat, nlpirows);
13775  }
13776 
13777  primalbound = 0.0;
13778  dualbound = 0.0;
13779 
13780  /* copy primal solution and reduced costs into columns */
13781  for( c = 0; c < nlpicols; ++c )
13782  {
13783  assert( 0 <= cstat[c] && cstat[c] < 4 );
13784  lpicols[c]->primsol = primsol[c];
13785  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
13786  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
13787  lpicols[c]->redcost = redcost[c];
13788  lpicols[c]->basisstatus = (unsigned int) cstat[c];
13789  lpicols[c]->validredcostlp = lpcount;
13790  if( stillprimalfeasible )
13791  {
13792  stillprimalfeasible =
13793  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
13794  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
13795  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
13796  }
13797  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13798  {
13799  double compslack;
13800 
13801  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13802  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
13803  * variables, which would magnify even the tiniest violation in the dual multiplier
13804  */
13805  if( stilldualfeasible )
13806  {
13807  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
13808  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13809  }
13810  if( stilldualfeasible )
13811  {
13812  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
13813  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13814  }
13815 
13816  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13817  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13818  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13819  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13820  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13821  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
13822  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
13823  dualfeasible != NULL ? stilldualfeasible : TRUE);
13824  }
13825  else
13826  {
13827  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
13828  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
13829  {
13830  lpicols[c]->redcost = 0.0;
13831  }
13832 
13833  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
13834  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
13835  * bounds, its reduced cost must be zero
13836  */
13837  if( stilldualfeasible
13838  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
13839  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
13840  if( stilldualfeasible
13841  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
13842  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
13843 
13844  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13845  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13846  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13847  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13848  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13849  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
13850  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
13851  dualfeasible != NULL ? stilldualfeasible : TRUE);
13852  }
13853 
13854  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
13855  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
13856  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
13857  */
13858  if( stilldualfeasible )
13859  {
13860  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
13861  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
13862  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
13863  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
13864  }
13865  }
13866 
13867  /* copy dual solution and activities into rows */
13868  for( r = 0; r < nlpirows; ++r )
13869  {
13870  assert( 0 <= rstat[r] && rstat[r] < 4 );
13871  lpirows[r]->dualsol = dualsol[r];
13872  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
13873  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
13874  lpirows[r]->validactivitylp = lpcount;
13875  if( stillprimalfeasible )
13876  {
13877  stillprimalfeasible =
13878  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
13879  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
13880  }
13881  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13882  {
13883  double compslack;
13884 
13885  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13886  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
13887  * variables, which would magnify even the tiniest violation in the dual multiplier
13888  */
13889  if( stilldualfeasible )
13890  {
13891  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
13892  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13893  }
13894  if( stilldualfeasible )
13895  {
13896  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
13897  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13898  }
13899 
13900  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13901  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
13902  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
13903  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
13904  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13905  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
13906  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
13907  dualfeasible != NULL ? stilldualfeasible : TRUE);
13908  }
13909  else
13910  {
13911  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
13912  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
13913  * strictly within left-hand and right-hand side, its dual multiplier must be zero
13914  */
13915  if( stilldualfeasible &&
13916  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
13917  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
13918  if( stilldualfeasible &&
13919  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
13920  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
13921 
13922  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13923  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
13924  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
13925  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
13926  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13927  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
13928  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
13929  dualfeasible != NULL ? stilldualfeasible : TRUE);
13930  }
13931 
13932  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
13933  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
13934  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
13935  */
13936  if( stilldualfeasible )
13937  {
13938  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
13939  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
13940  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
13941  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
13942  }
13943  }
13944 
13945  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
13946  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
13947  * infinity
13948  */
13949  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
13950  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
13951  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
13952  {
13953  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
13954  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
13955  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
13956  }
13957 
13958  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
13959  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
13960  */
13961  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
13962  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
13963  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
13964  {
13965  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
13966  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
13967  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
13968  }
13969 
13970  if( primalfeasible != NULL )
13971  *primalfeasible = stillprimalfeasible;
13972  if( dualfeasible != NULL )
13973  *dualfeasible = stilldualfeasible;
13974 
13975  /* free temporary memory */
13976  SCIPsetFreeBufferArray(set, &rstat);
13977  SCIPsetFreeBufferArray(set, &cstat);
13978  SCIPsetFreeBufferArray(set, &redcost);
13979  SCIPsetFreeBufferArray(set, &activity);
13980  SCIPsetFreeBufferArray(set, &dualsol);
13981  SCIPsetFreeBufferArray(set, &primsol);
13982 
13983  return SCIP_OKAY;
13984 }
13985 
13986 /** stores LP solution with infinite objective value in the columns and rows */
13988  SCIP_LP* lp, /**< current LP data */
13989  SCIP_SET* set, /**< global SCIP settings */
13990  SCIP_STAT* stat, /**< problem statistics */
13991  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
13992  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
13993  )
13994 {
13995  SCIP_COL** lpicols;
13996  SCIP_ROW** lpirows;
13997  SCIP_Real* primsol;
13998  SCIP_Real* activity;
13999  SCIP_Real* ray;
14000  SCIP_Real rayobjval;
14001  SCIP_Real rayscale;
14002  SCIP_Longint lpcount;
14003  int nlpicols;
14004  int nlpirows;
14005  int c;
14006  int r;
14007 
14008  assert(lp != NULL);
14009  assert(lp->flushed);
14010  assert(lp->solved);
14011  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14012  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14013  assert(set != NULL);
14014  assert(stat != NULL);
14015  assert(lp->validsollp <= stat->lpcount);
14016 
14017  if( primalfeasible != NULL )
14018  *primalfeasible = TRUE;
14019  if( rayfeasible != NULL )
14020  *rayfeasible = TRUE;
14021 
14022  /* check if the values are already calculated */
14023  if( lp->validsollp == stat->lpcount )
14024  return SCIP_OKAY;
14025 
14026  /* check if the LP solver is able to provide a primal unbounded ray */
14027  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14028  {
14029  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14030  return SCIP_LPERROR;
14031  }
14032 
14033  lp->validsollp = stat->lpcount;
14034 
14035  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14036 
14037  /* get temporary memory */
14038  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14039  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14040  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14041 
14042  /* get primal feasible point */
14043  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14044 
14045  /* get primal unbounded ray */
14046  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14047 
14048  lpicols = lp->lpicols;
14049  lpirows = lp->lpirows;
14050  nlpicols = lp->nlpicols;
14051  nlpirows = lp->nlpirows;
14052  lpcount = stat->lpcount;
14053 
14054  /* calculate the objective value decrease of the ray */
14055  rayobjval = 0.0;
14056  for( c = 0; c < nlpicols; ++c )
14057  {
14058  assert(lpicols[c] != NULL);
14059  assert(lpicols[c]->var != NULL);
14060 
14061  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14062  if( rayfeasible != NULL )
14063  *rayfeasible = *rayfeasible
14064  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -lpicols[c]->lb))
14065  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, lpicols[c]->ub));
14066 
14067  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14068  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14069  */
14070  if( primalfeasible != NULL )
14071  *primalfeasible = *primalfeasible
14072  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14073  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14074 
14075  if( !SCIPsetIsZero(set, ray[c]) )
14076  rayobjval += ray[c] * lpicols[c]->obj;
14077  }
14078 
14079  /* if the finite point is already infeasible, we do not have to add the ray */
14080  if( primalfeasible != NULL && !(*primalfeasible) )
14081  {
14082  rayscale = 0.0;
14083  }
14084  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14085  else if( rayfeasible != NULL && !(*rayfeasible) )
14086  {
14087  rayscale = 0.0;
14088  }
14089  /* due to numerical problems, the objective of the ray might be nonnegative,
14090  *
14091  * @todo How to check for negative objective value here?
14092  */
14093  else if( !SCIPsetIsNegative(set, rayobjval) )
14094  {
14095  if( rayfeasible != NULL )
14096  {
14097  *rayfeasible = FALSE;
14098  }
14099 
14100  rayscale = 0.0;
14101  }
14102  else
14103  {
14104  assert(rayobjval != 0.0);
14105 
14106  /* scale the ray, such that the resulting point has infinite objective value */
14107  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14108  assert(SCIPsetIsFeasPositive(set, rayscale));
14109 
14110  /* ensure that unbounded point does not violate the bounds of the variables */
14111  for( c = 0; c < nlpicols; ++c )
14112  {
14113  if( SCIPsetIsPositive(set, ray[c]) )
14114  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14115  else if( SCIPsetIsNegative(set, ray[c]) )
14116  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14117 
14118  assert(SCIPsetIsFeasPositive(set, rayscale));
14119  }
14120  }
14121 
14122  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14123 
14124  /* calculate the unbounded point: x' = x + rayscale * ray */
14125  for( c = 0; c < nlpicols; ++c )
14126  {
14127  if( SCIPsetIsZero(set, ray[c]) )
14128  lpicols[c]->primsol = primsol[c];
14129  else
14130  {
14131  SCIP_Real primsolval = primsol[c] + rayscale * ray[c];
14132  lpicols[c]->primsol = SCIPsetIsInfinity(set, primsolval) ? SCIPsetInfinity(set) : primsolval;
14133  }
14134  lpicols[c]->redcost = SCIP_INVALID;
14135  lpicols[c]->validredcostlp = -1;
14136  }
14137 
14138  for( r = 0; r < nlpirows; ++r )
14139  {
14140  lpirows[r]->dualsol = SCIP_INVALID;
14141  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14142  lpirows[r]->validactivitylp = lpcount;
14143 
14144  /* check for feasibility of the rows */
14145  if( primalfeasible != NULL )
14146  *primalfeasible = *primalfeasible
14147  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14148  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14149  }
14150 
14151  /* free temporary memory */
14152  SCIPsetFreeBufferArray(set, &ray);
14153  SCIPsetFreeBufferArray(set, &activity);
14154  SCIPsetFreeBufferArray(set, &primsol);
14155 
14156  return SCIP_OKAY;
14157 }
14158 
14159 /** returns primal ray proving the unboundedness of the current LP */
14161  SCIP_LP* lp, /**< current LP data */
14162  SCIP_SET* set, /**< global SCIP settings */
14163  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14164  * so the size of this array should be at least number of active variables
14165  * (all entries have to be initialized to 0 before) */
14166  )
14167 {
14168  SCIP_COL** lpicols;
14169  SCIP_Real* lpiray;
14170  SCIP_VAR* var;
14171  int nlpicols;
14172  int c;
14173 
14174  assert(lp != NULL);
14175  assert(set != NULL);
14176  assert(ray != NULL);
14177  assert(lp->flushed);
14178  assert(lp->solved);
14179  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14180  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14181 
14182  /* check if the LP solver is able to provide a primal unbounded ray */
14183  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14184  {
14185  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14186  return SCIP_LPERROR;
14187  }
14188 
14189  /* get temporary memory */
14190  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14191 
14192  SCIPsetDebugMsg(set, "getting primal ray values\n");
14193 
14194  /* get primal unbounded ray */
14195  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14196 
14197  lpicols = lp->lpicols;
14198  nlpicols = lp->nlpicols;
14199 
14200  /* store the ray values of active problem variables */
14201  for( c = 0; c < nlpicols; c++ )
14202  {
14203  assert(lpicols[c] != NULL);
14204 
14205  var = lpicols[c]->var;
14206  assert(var != NULL);
14207  assert(SCIPvarGetProbindex(var) != -1);
14208  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14209  }
14210 
14211  SCIPsetFreeBufferArray(set, &lpiray);
14212 
14213  return SCIP_OKAY;
14214 }
14215 
14216 /** stores the dual Farkas multipliers for infeasibility proof in rows */
14218  SCIP_LP* lp, /**< current LP data */
14219  SCIP_SET* set, /**< global SCIP settings */
14220  SCIP_STAT* stat /**< problem statistics */
14221  )
14222 {
14223  SCIP_COL** lpicols;
14224  SCIP_ROW** lpirows;
14225  SCIP_Real* dualfarkas;
14226  int nlpicols;
14227  int nlpirows;
14228  int c;
14229  int r;
14230 
14231  assert(lp != NULL);
14232  assert(lp->flushed);
14233  assert(lp->solved);
14234  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14235  assert(set != NULL);
14236  assert(stat != NULL);
14237  assert(lp->validfarkaslp <= stat->lpcount);
14238 
14239  /* check if the values are already calculated */
14240  if( lp->validfarkaslp == stat->lpcount )
14241  return SCIP_OKAY;
14242  lp->validfarkaslp = stat->lpcount;
14243 
14244  /* get temporary memory */
14245  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14246 
14247  /* get dual Farkas infeasibility proof */
14248  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14249 
14250  lpicols = lp->lpicols;
14251  lpirows = lp->lpirows;
14252  nlpicols = lp->nlpicols;
14253  nlpirows = lp->nlpirows;
14254 
14255  /* store infeasibility proof in rows */
14256  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14257  for( r = 0; r < nlpirows; ++r )
14258  {
14259  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14260  lpirows[r]->dualfarkas = dualfarkas[r];
14261  lpirows[r]->dualsol = SCIP_INVALID;
14262  lpirows[r]->activity = 0.0;
14263  lpirows[r]->validactivitylp = -1L;
14264  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14265  }
14266 
14267  /* set columns as invalid */
14268  for( c = 0; c < nlpicols; ++c )
14269  {
14270  lpicols[c]->primsol = SCIP_INVALID;
14271  lpicols[c]->redcost = SCIP_INVALID;
14272  lpicols[c]->validredcostlp = -1L;
14273  lpicols[c]->validfarkaslp = -1L;
14274  }
14275 
14276  /* free temporary memory */
14277  SCIPsetFreeBufferArray(set, &dualfarkas);
14278 
14279  return SCIP_OKAY;
14280 }
14281 
14282 /** get number of iterations used in last LP solve */
14284  SCIP_LP* lp, /**< current LP data */
14285  int* iterations /**< pointer to store the iteration count */
14286  )
14287 {
14288  assert(lp != NULL);
14289 
14290  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14291 
14292  return SCIP_OKAY;
14293 }
14294 
14295 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14296  * resets age of non-zero columns and sharp rows
14297  */
14299  SCIP_LP* lp, /**< current LP data */
14300  SCIP_STAT* stat /**< problem statistics */
14301  )
14302 {
14303  SCIP_COL** lpicols;
14304  SCIP_ROW** lpirows;
14305  int nlpicols;
14306  int nlpirows;
14307  int c;
14308  int r;
14309 
14310  assert(lp != NULL);
14311  assert(lp->flushed);
14312  assert(lp->solved);
14313  assert(lp->nlpicols == lp->ncols);
14314  assert(lp->nlpirows == lp->nrows);
14315  assert(stat != NULL);
14316  assert(lp->validsollp == stat->lpcount);
14317 
14318  SCIPdebugMessage("updating LP ages\n");
14319 
14320  lpicols = lp->lpicols;
14321  lpirows = lp->lpirows;
14322  nlpicols = lp->nlpicols;
14323  nlpirows = lp->nlpirows;
14324 
14325  for( c = 0; c < nlpicols; ++c )
14326  {
14327  assert(lpicols[c] == lp->cols[c]);
14328  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14329  lpicols[c]->age++;
14330  else
14331  lpicols[c]->age = 0;
14332  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14333  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14334  }
14335 
14336  for( r = 0; r < nlpirows; ++r )
14337  {
14338  lpirows[r]->nlpsaftercreation++;
14339  assert(lpirows[r] == lp->rows[r]);
14340 
14341  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14342  {
14343  lpirows[r]->age++;
14344  }
14345  else
14346  {
14347  lpirows[r]->activeinlpcounter++;
14348  lpirows[r]->age = 0;
14349  }
14350  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14351  }
14352 
14353  return SCIP_OKAY;
14354 }
14355 
14356 /* deletes the marked columns from the LP and the LP interface */
14357 static
14359  SCIP_LP* lp, /**< current LP data */
14360  SCIP_SET* set, /**< global SCIP settings */
14361  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
14362  )
14363 {
14364  SCIP_COL* col;
14365  int ncols;
14366  int c;
14367 
14368  assert(lp != NULL);
14369  assert(lp->flushed);
14370  assert(lp->ncols == lp->nlpicols);
14371  assert(!lp->diving);
14372  assert(coldstat != NULL);
14373  assert(lp->nlazycols <= lp->ncols);
14374 
14375  ncols = lp->ncols;
14376 
14377  /* delete columns in LP solver */
14378  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
14379 
14380  /* update LP data respectively */
14381  for( c = 0; c < ncols; ++c )
14382  {
14383  col = lp->cols[c];
14384  assert(col != NULL);
14385  assert(col == lp->lpicols[c]);
14386  assert(coldstat[c] <= c);
14387  col->lppos = coldstat[c];
14388  if( coldstat[c] == -1 )
14389  {
14390  assert(col->removable);
14391 
14392  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
14393  * function vector norms
14394  */
14395  markColDeleted(col);
14396  colUpdateDelLP(col, set);
14397  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
14398  col->lpdepth = -1;
14399 
14400  lp->cols[c] = NULL;
14401  lp->lpicols[c] = NULL;
14402  lp->ncols--;
14403  lp->nremovablecols--;
14404  lp->nlpicols--;
14405  }
14406  else if( coldstat[c] < c )
14407  {
14408  assert(lp->cols[coldstat[c]] == NULL);
14409  assert(lp->lpicols[coldstat[c]] == NULL);
14410  lp->cols[coldstat[c]] = col;
14411  lp->lpicols[coldstat[c]] = col;
14412  lp->cols[coldstat[c]]->lppos = coldstat[c];
14413  lp->cols[coldstat[c]]->lpipos = coldstat[c];
14414  lp->cols[c] = NULL;
14415  lp->lpicols[c] = NULL;
14416  }
14417  }
14418 
14419  /* remove columns which are deleted from the lazy column array */
14420  c = 0;
14421  while( c < lp->nlazycols )
14422  {
14423  if( lp->lazycols[c]->lpipos < 0 )
14424  {
14425  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
14426  lp->nlazycols--;
14427  }
14428  else
14429  c++;
14430  }
14431 
14432  /* mark LP to be unsolved */
14433  if( lp->ncols < ncols )
14434  {
14435  assert(lp->ncols == lp->nlpicols);
14436  assert(lp->nchgcols == 0);
14437  assert(lp->flushed);
14438 
14439  lp->lpifirstchgcol = lp->nlpicols;
14440 
14441  /* mark the current solution invalid */
14442  lp->solved = FALSE;
14443  lp->primalfeasible = FALSE;
14444  lp->lpobjval = SCIP_INVALID;
14446  }
14447 
14448  checkLazyColArray(lp, set);
14449  checkLinks(lp);
14450 
14451  return SCIP_OKAY;
14452 }
14453 
14454 /* deletes the marked rows from the LP and the LP interface */
14455 static
14457  SCIP_LP* lp, /**< current LP data */
14458  BMS_BLKMEM* blkmem, /**< block memory buffers */
14459  SCIP_SET* set, /**< global SCIP settings */
14460  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14461  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14462  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
14463  )
14464 {
14465  SCIP_ROW* row;
14466  int nrows;
14467  int r;
14468 
14469  assert(lp != NULL);
14470  assert(lp->flushed);
14471  assert(lp->nrows == lp->nlpirows);
14472  assert(!lp->diving);
14473  assert(rowdstat != NULL);
14474 
14475  nrows = lp->nrows;
14476 
14477  /* delete rows in LP solver */
14478  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
14479 
14480  /* update LP data respectively */
14481  for( r = 0; r < nrows; ++r )
14482  {
14483  row = lp->rows[r];
14484  assert(row == lp->lpirows[r]);
14485  assert(rowdstat[r] <= r);
14486  assert(row != NULL);
14487  row->lppos = rowdstat[r];
14488  if( rowdstat[r] == -1 )
14489  {
14490  if( row->removable )
14491  lp->nremovablerows--;
14492 
14493  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
14494  markRowDeleted(row);
14495  rowUpdateDelLP(row);
14496  row->lpdepth = -1;
14497 
14498  /* check, if row deletion events are tracked
14499  * if so, issue ROWDELETEDLP event
14500  */
14501  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
14502  {
14503  SCIP_EVENT* event;
14504 
14505  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
14506  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
14507  }
14508 
14509  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
14510  SCIProwUnlock(lp->rows[r]);
14511  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
14512  assert(lp->lpirows[r] == NULL);
14513  assert(lp->rows[r] == NULL);
14514  lp->nrows--;
14515  lp->nlpirows--;
14516  }
14517  else if( rowdstat[r] < r )
14518  {
14519  assert(lp->rows[rowdstat[r]] == NULL);
14520  assert(lp->lpirows[rowdstat[r]] == NULL);
14521  lp->rows[rowdstat[r]] = row;
14522  lp->lpirows[rowdstat[r]] = row;
14523  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
14524  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
14525  lp->rows[r] = NULL;
14526  lp->lpirows[r] = NULL;
14527  }
14528  }
14529 
14530  /* mark LP to be unsolved */
14531  if( lp->nrows < nrows )
14532  {
14533  assert(lp->nrows == lp->nlpirows);
14534  assert(lp->nchgrows == 0);
14535  assert(lp->flushed);
14536 
14537  lp->lpifirstchgrow = lp->nlpirows;
14538 
14539  /* mark the current solution invalid */
14540  lp->solved = FALSE;
14541  lp->dualfeasible = FALSE;
14542  lp->lpobjval = SCIP_INVALID;
14544  }
14545 
14546  checkLinks(lp);
14547 
14548  return SCIP_OKAY;
14549 }
14550 
14551 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
14552 static
14554  SCIP_LP* lp, /**< current LP data */
14555  SCIP_SET* set, /**< global SCIP settings */
14556  SCIP_STAT* stat, /**< problem statistics */
14557  int firstcol /**< first column to check for clean up */
14558  )
14559 {
14560  SCIP_COL** cols;
14561 #ifndef NDEBUG
14562  SCIP_COL** lpicols;
14563 #endif
14564  int* coldstat;
14565  int ncols;
14566  int ndelcols;
14567  int c;
14568 
14569  assert(lp != NULL);
14570  assert(lp->flushed);
14571  assert(lp->ncols == lp->nlpicols);
14572  assert(lp->nremovablecols <= lp->ncols);
14573  assert(!lp->diving);
14574  assert(set != NULL);
14575  assert(stat != NULL);
14576 
14577  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
14578  return SCIP_OKAY;
14579 
14580  ncols = lp->ncols;
14581  cols = lp->cols;
14582 #ifndef NDEBUG
14583  lpicols = lp->lpicols;
14584 #endif
14585 
14586  /* get temporary memory */
14587  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14588 
14589  /* mark obsolete columns to be deleted */
14590  ndelcols = 0;
14591  BMSclearMemoryArray(coldstat, ncols);
14592  for( c = firstcol; c < ncols; ++c )
14593  {
14594  assert(cols[c] == lpicols[c]);
14595  assert(cols[c]->lppos == c);
14596  assert(cols[c]->lpipos == c);
14597  if( cols[c]->removable
14598  && 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 */
14599  && cols[c]->age > set->lp_colagelimit
14601  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14602  {
14603  assert(cols[c]->primsol == 0.0);
14604  coldstat[c] = 1;
14605  ndelcols++;
14606  cols[c]->obsoletenode = stat->nnodes;
14607  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
14608  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
14609  }
14610  }
14611 
14612  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
14613 
14614  /* delete the marked columns in the LP solver interface, update the LP respectively */
14615  if( ndelcols > 0 )
14616  {
14617  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14618  }
14619  assert(lp->ncols == ncols - ndelcols);
14620 
14621  /* release temporary memory */
14622  SCIPsetFreeBufferArray(set, &coldstat);
14623 
14624  return SCIP_OKAY;
14625 }
14626 
14627 /** removes all basic rows, that are too old, beginning with the given firstrow */
14628 static
14630  SCIP_LP* lp, /**< current LP data */
14631  BMS_BLKMEM* blkmem, /**< block memory buffers */
14632  SCIP_SET* set, /**< global SCIP settings */
14633  SCIP_STAT* stat, /**< problem statistics */
14634  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14635  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14636  int firstrow /**< first row to check for clean up */
14637  )
14638 {
14639  SCIP_ROW** rows;
14640 #ifndef NDEBUG
14641  SCIP_ROW** lpirows;
14642 #endif
14643  int* rowdstat;
14644  int nrows;
14645  int ndelrows;
14646  int r;
14647 
14648  assert(lp != NULL);
14649  assert(lp->flushed);
14650  assert(lp->nrows == lp->nlpirows);
14651  assert(lp->nremovablerows <= lp->nrows);
14652  assert(!lp->diving);
14653  assert(set != NULL);
14654  assert(stat != NULL);
14655 
14656  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
14657  return SCIP_OKAY;
14658 
14659  nrows = lp->nrows;
14660  rows = lp->rows;
14661 #ifndef NDEBUG
14662  lpirows = lp->lpirows;
14663 #endif
14664 
14665  /* get temporary memory */
14666  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14667 
14668  /* mark obsolete rows to be deleted */
14669  ndelrows = 0;
14670  BMSclearMemoryArray(rowdstat, nrows);
14671  for( r = firstrow; r < nrows; ++r )
14672  {
14673  assert(rows[r] == lpirows[r]);
14674  assert(rows[r]->lppos == r);
14675  assert(rows[r]->lpipos == r);
14676  if( rows[r]->removable
14677  && 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 */
14678  && rows[r]->age > set->lp_rowagelimit
14680  {
14681  rowdstat[r] = 1;
14682  ndelrows++;
14683  rows[r]->obsoletenode = stat->nnodes;
14684  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
14685  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
14686  }
14687  }
14688 
14689  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
14690 
14691  /* delete the marked rows in the LP solver interface, update the LP respectively */
14692  if( ndelrows > 0 )
14693  {
14694  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14695  }
14696  assert(lp->nrows == nrows - ndelrows);
14697 
14698  /* release temporary memory */
14699  SCIPsetFreeBufferArray(set, &rowdstat);
14700 
14701  return SCIP_OKAY;
14702 }
14703 
14704 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
14706  SCIP_LP* lp, /**< current LP data */
14707  BMS_BLKMEM* blkmem, /**< block memory buffers */
14708  SCIP_SET* set, /**< global SCIP settings */
14709  SCIP_STAT* stat, /**< problem statistics */
14710  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14711  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14712  )
14713 {
14714  assert(lp != NULL);
14715  assert(lp->solved);
14716  assert(!lp->diving);
14718  assert(set != NULL);
14719 
14720  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
14721  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
14722 
14723  if( lp->firstnewcol < lp->ncols )
14724  {
14725  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
14726  }
14727  if( lp->firstnewrow < lp->nrows )
14728  {
14729  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
14730  }
14731 
14732  return SCIP_OKAY;
14733 }
14734 
14735 /** removes all non-basic columns and basic rows in whole LP, that are too old */
14737  SCIP_LP* lp, /**< current LP data */
14738  BMS_BLKMEM* blkmem, /**< block memory buffers */
14739  SCIP_SET* set, /**< global SCIP settings */
14740  SCIP_STAT* stat, /**< problem statistics */
14741  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14742  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14743  )
14744 {
14745  assert(lp != NULL);
14746  assert(lp->solved);
14747  assert(!lp->diving);
14749  assert(set != NULL);
14750 
14751  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
14752 
14753  if( 0 < lp->ncols )
14754  {
14755  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
14756  }
14757  if( 0 < lp->nrows )
14758  {
14759  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
14760  }
14761 
14762  return SCIP_OKAY;
14763 }
14764 
14765 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
14766 static
14768  SCIP_LP* lp, /**< current LP data */
14769  SCIP_SET* set, /**< global SCIP settings */
14770  SCIP_STAT* stat, /**< problem statistics */
14771  int firstcol /**< first column to check for clean up */
14772  )
14773 {
14774  SCIP_COL** cols;
14775  SCIP_COL** lpicols;
14776  int* coldstat;
14777  int ncols;
14778  int ndelcols;
14779  int c;
14780 
14781  assert(lp != NULL);
14782  assert(lp->flushed);
14783  assert(lp->ncols == lp->nlpicols);
14784  assert(!lp->diving);
14785  assert(stat != NULL);
14786  assert(lp->validsollp == stat->lpcount);
14787  assert(0 <= firstcol && firstcol < lp->ncols);
14788 
14789  if( lp->nremovablecols == 0 || !lp->solisbasic )
14790  return SCIP_OKAY;
14791 
14792  ncols = lp->ncols;
14793  cols = lp->cols;
14794  lpicols = lp->lpicols;
14795 
14796  /* get temporary memory */
14797  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14798 
14799  /* mark unused columns to be deleted */
14800  ndelcols = 0;
14801  BMSclearMemoryArray(coldstat, ncols);
14802  for( c = firstcol; c < ncols; ++c )
14803  {
14804  assert(cols[c] == lpicols[c]);
14805  assert(cols[c]->lppos == c);
14806  assert(cols[c]->lpipos == c);
14807  if( lpicols[c]->removable
14808  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
14809  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
14810  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14811  {
14812  coldstat[c] = 1;
14813  ndelcols++;
14814  }
14815  }
14816 
14817  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
14818 
14819  /* delete the marked columns in the LP solver interface, update the LP respectively */
14820  if( ndelcols > 0 )
14821  {
14822  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14823  }
14824  assert(lp->ncols == ncols - ndelcols);
14825 
14826  /* release temporary memory */
14827  SCIPsetFreeBufferArray(set, &coldstat);
14828 
14829  return SCIP_OKAY;
14830 }
14831 
14832 /** removes all basic rows beginning with the given firstrow */
14833 static
14835  SCIP_LP* lp, /**< current LP data */
14836  BMS_BLKMEM* blkmem, /**< block memory buffers */
14837  SCIP_SET* set, /**< global SCIP settings */
14838  SCIP_STAT* stat, /**< problem statistics */
14839  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14840  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14841  int firstrow /**< first row to check for clean up */
14842  )
14843 {
14844 #ifndef NDEBUG
14845  SCIP_ROW** rows;
14846 #endif
14847  SCIP_ROW** lpirows;
14848  int* rowdstat;
14849  int nrows;
14850  int ndelrows;
14851  int r;
14852 
14853  assert(lp != NULL);
14854  assert(lp->flushed);
14855  assert(lp->ncols == lp->nlpicols);
14856  assert(lp->nrows == lp->nlpirows);
14857  assert(!lp->diving);
14858  assert(stat != NULL);
14859  assert(lp->validsollp == stat->lpcount);
14860  assert(0 <= firstrow && firstrow < lp->nrows);
14861 
14862  if( lp->nremovablerows == 0 || !lp->solisbasic )
14863  return SCIP_OKAY;
14864 
14865 #ifndef NDEBUG
14866  rows = lp->rows;
14867 #endif
14868  nrows = lp->nrows;
14869  lpirows = lp->lpirows;
14870 
14871  /* get temporary memory */
14872  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14873 
14874  /* mark unused rows to be deleted */
14875  ndelrows = 0;
14876  BMSclearMemoryArray(rowdstat, nrows);
14877  for( r = firstrow; r < nrows; ++r )
14878  {
14879  assert(rows[r] == lpirows[r]);
14880  assert(rows[r]->lppos == r);
14881  assert(rows[r]->lpipos == r);
14882  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
14883  {
14884  rowdstat[r] = 1;
14885  ndelrows++;
14886  }
14887  }
14888 
14889  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
14890 
14891  /* delete the marked rows in the LP solver interface, update the LP respectively */
14892  if( ndelrows > 0 )
14893  {
14894  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14895  }
14896  assert(lp->nrows == nrows - ndelrows);
14897 
14898  /* release temporary memory */
14899  SCIPsetFreeBufferArray(set, &rowdstat);
14900 
14901  return SCIP_OKAY;
14902 }
14903 
14904 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
14906  SCIP_LP* lp, /**< current LP data */
14907  BMS_BLKMEM* blkmem, /**< block memory buffers */
14908  SCIP_SET* set, /**< global SCIP settings */
14909  SCIP_STAT* stat, /**< problem statistics */
14910  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14911  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14912  SCIP_Bool root /**< are we at the root node? */
14913  )
14914 {
14915  SCIP_Bool cleanupcols;
14916  SCIP_Bool cleanuprows;
14917 
14918  assert(lp != NULL);
14919  assert(lp->solved);
14920  assert(!lp->diving);
14922  assert(set != NULL);
14923 
14924  /* check, if we want to clean up the columns and rows */
14925  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
14926  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
14927 
14928  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
14929  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
14930 
14931  if( cleanupcols && lp->firstnewcol < lp->ncols )
14932  {
14933  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
14934  }
14935  if( cleanuprows && lp->firstnewrow < lp->nrows )
14936  {
14937  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
14938  }
14939 
14940  return SCIP_OKAY;
14941 }
14942 
14943 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
14945  SCIP_LP* lp, /**< current LP data */
14946  BMS_BLKMEM* blkmem, /**< block memory buffers */
14947  SCIP_SET* set, /**< global SCIP settings */
14948  SCIP_STAT* stat, /**< problem statistics */
14949  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14950  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14951  SCIP_Bool root /**< are we at the root node? */
14952  )
14953 {
14954  SCIP_Bool cleanupcols;
14955  SCIP_Bool cleanuprows;
14956 
14957  assert(lp != NULL);
14958  assert(lp->solved);
14959  assert(!lp->diving);
14961  assert(set != NULL);
14962 
14963  /* check, if we want to clean up the columns and rows */
14964  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
14965  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
14966 
14967  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
14968  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
14969 
14970  if( cleanupcols && 0 < lp->ncols )
14971  {
14972  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
14973  }
14974  if( cleanuprows && 0 < lp->nrows )
14975  {
14976  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
14977  }
14978 
14979  return SCIP_OKAY;
14980 }
14981 
14982 /** removes all redundant rows that were added at the current node */
14984  SCIP_LP* lp, /**< current LP data */
14985  BMS_BLKMEM* blkmem, /**< block memory buffers */
14986  SCIP_SET* set, /**< global SCIP settings */
14987  SCIP_STAT* stat, /**< problem statistics */
14988  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14989  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14990  )
14991 {
14992 #ifndef NDEBUG
14993  SCIP_ROW** rows;
14994 #endif
14995  SCIP_ROW** lpirows;
14996  int* rowdstat;
14997  int nrows;
14998  int ndelrows;
14999  int r;
15000 
15001  assert(lp != NULL);
15002  assert(lp->flushed);
15003  assert(lp->ncols == lp->nlpicols);
15004  assert(lp->nrows == lp->nlpirows);
15005  assert(!lp->diving);
15006  assert(stat != NULL);
15007  assert(lp->validsollp == stat->lpcount);
15008  assert(lp->firstnewrow <= lp->nrows);
15009 
15010  if( lp->firstnewrow == lp->nrows )
15011  return SCIP_OKAY;
15012 
15013 #ifndef NDEBUG
15014  rows = lp->rows;
15015 #endif
15016  nrows = lp->nrows;
15017  lpirows = lp->lpirows;
15018 
15019  /* get temporary memory */
15020  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15021 
15022  /* mark redundant rows to be deleted (only delete basic rows!) */
15023  ndelrows = 0;
15024  BMSclearMemoryArray(rowdstat, nrows);
15025  for( r = lp->firstnewrow; r < nrows; ++r )
15026  {
15027  assert(rows[r] == lpirows[r]);
15028  assert(rows[r]->lppos == r);
15029  assert(rows[r]->lpipos == r);
15030  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15031  && SCIProwIsRedundant(lpirows[r], set, stat) )
15032  {
15033  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15034  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15035  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15036  rowdstat[r] = 1;
15037  ndelrows++;
15038  }
15039  }
15040 
15041  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15042 
15043  /* delete the marked rows in the LP solver interface, update the LP respectively */
15044  if( ndelrows > 0 )
15045  {
15046  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15047  }
15048  assert(lp->nrows == nrows - ndelrows);
15049 
15050  /* release temporary memory */
15051  SCIPsetFreeBufferArray(set, &rowdstat);
15052 
15053  return SCIP_OKAY;
15054 }
15055 
15056 /** initiates LP diving */
15058  SCIP_LP* lp, /**< current LP data */
15059  BMS_BLKMEM* blkmem, /**< block memory */
15060  SCIP_SET* set, /**< global SCIP settings */
15061  SCIP_STAT* stat /**< problem statistics */
15062  )
15063 {
15064  int c;
15065  int r;
15066 
15067  assert(lp != NULL);
15068  assert(lp->flushed || !lp->solved);
15069  assert(!lp->diving);
15070  assert(!lp->probing);
15071  assert(lp->divelpistate == NULL);
15072  assert(lp->divelpwasprimfeas);
15073  assert(lp->divelpwasdualfeas);
15074  assert(lp->validsollp <= stat->lpcount);
15075  assert(blkmem != NULL);
15076  assert(set != NULL);
15077  assert(lp->ndivechgsides == 0);
15078 
15079  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15080  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15081 
15082 #ifndef NDEBUG
15083  for( c = 0; c < lp->ncols; ++c )
15084  {
15085  assert(lp->cols[c] != NULL);
15086  assert(lp->cols[c]->var != NULL);
15087  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15088  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15089  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15090  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15091  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15092  }
15093 #endif
15094 
15095  /* save current LPI state (basis information) */
15096  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15098  lp->divelpwasdualfeas = lp->dualfeasible;
15099 
15100  /* save current LP values dependent on the solution */
15101  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15102  assert(lp->storedsolvals != NULL);
15103  if( !set->lp_resolverestore && lp->solved )
15104  {
15105  SCIP_Bool store = TRUE;
15106 
15107  switch ( lp->lpsolstat )
15108  {
15110  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15111  assert(lp->validsollp == stat->lpcount);
15112  break;
15114  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15115  assert(lp->validsollp == stat->lpcount);
15116  break;
15120  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15121  assert(lp->validsollp == stat->lpcount);
15122  break;
15124  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
15125  break;
15127  case SCIP_LPSOLSTAT_ERROR:
15128  default:
15129  store = FALSE;
15130  }
15131 
15132  if ( store )
15133  {
15134  for( c = 0; c < lp->ncols; ++c )
15135  {
15136  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15137  }
15138  for( r = 0; r < lp->nrows; ++r )
15139  {
15141  }
15142  }
15143  }
15144 
15145  /* store LPI iteration limit */
15147 
15148  /* store current number of rows */
15149  lp->ndivingrows = lp->nrows;
15150 
15151  /* switch to diving mode */
15152  lp->diving = TRUE;
15153 
15154  return SCIP_OKAY;
15155 }
15156 
15157 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15159  SCIP_LP* lp, /**< current LP data */
15160  BMS_BLKMEM* blkmem, /**< block memory */
15161  SCIP_SET* set, /**< global SCIP settings */
15162  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15163  SCIP_STAT* stat, /**< problem statistics */
15164  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15165  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15166  SCIP_PROB* prob, /**< problem data */
15167  SCIP_VAR** vars, /**< array with all active variables */
15168  int nvars /**< number of active variables */
15169  )
15170 {
15171  SCIP_VAR* var;
15172  int v;
15173 
15174  assert(lp != NULL);
15175  assert(lp->diving);
15176  assert(blkmem != NULL);
15177  assert(nvars == 0 || vars != NULL);
15178 
15179  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15180 
15181  /* reset all columns' objective values and bounds to its original values */
15182  for( v = 0; v < nvars; ++v )
15183  {
15184  var = vars[v];
15185  assert(var != NULL);
15187  {
15188  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15189  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15190  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15191  }
15192  }
15193 
15194  /* remove rows which were added in diving mode */
15195  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15196 
15197  /* undo changes to left hand sides and right hand sides */
15198  while( lp->ndivechgsides > 0 )
15199  {
15200  SCIP_Real oldside;
15201  SCIP_SIDETYPE sidetype;
15202  SCIP_ROW* row;
15203 
15204  lp->ndivechgsides--;
15205  oldside = lp->divechgsides[lp->ndivechgsides];
15206  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15207  row = lp->divechgrows[lp->ndivechgsides];
15208 
15209  if( sidetype == SCIP_SIDETYPE_LEFT )
15210  {
15211  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15212  }
15213  else
15214  {
15215  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15216  }
15217  }
15218 
15219  /* restore LPI iteration limit */
15221 
15222  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15223  * happens
15224  */
15225  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15227  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15228  lp->divelpwasprimfeas = TRUE;
15229  lp->divelpwasdualfeas = TRUE;
15230  assert(lp->divelpistate == NULL);
15231 
15232  /* switch to standard (non-diving) mode */
15233  lp->diving = FALSE;
15234  lp->divingobjchg = FALSE;
15235 
15236  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15237  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15238  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15239  * the parameter resolverestore to TRUE
15240  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15241  */
15242  assert(lp->storedsolvals != NULL);
15243  if( lp->storedsolvals->lpissolved
15244  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL) )
15245  {
15246  SCIP_Bool lperror;
15247 
15248  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15249  if( lperror )
15250  {
15251  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15252  "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles while resolving LP %" SCIP_LONGINT_FORMAT " after diving\n", stat->nnodes, stat->nlps);
15253  lp->resolvelperror = TRUE;
15254  }
15259  {
15260  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15261  "LP was not resolved to a sufficient status after diving\n");
15262  lp->resolvelperror = TRUE;
15263  }
15264  }
15265  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15266  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15267  * re-solve as above can lead to a different LP status
15268  */
15269  else
15270  {
15271  int c;
15272  int r;
15273 
15274  /* if there are lazy bounds, remove them from the LP */
15275  if( lp->nlazycols > 0 )
15276  {
15277  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15278  * first resolve LP?
15279  */
15280  SCIP_CALL( updateLazyBounds(lp, set) );
15281  assert(lp->diving == lp->divinglazyapplied);
15282 
15283  /* flush changes to the LP solver */
15284  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15285  }
15286 
15287  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15288  SCIPstatIncrement(stat, set, lpcount);
15289 
15290  /* restore LP solution values in lp data, columns and rows */
15291  if( lp->storedsolvals->lpissolved &&
15298  )
15299  {
15300  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15301 
15302  for( c = 0; c < lp->ncols; ++c )
15303  {
15304  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15305  }
15306  for( r = 0; r < lp->nrows; ++r )
15307  {
15308  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15309  }
15310  }
15311  else
15312  {
15313  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15314  }
15315  }
15316 
15317 #ifndef NDEBUG
15318  {
15319  int c;
15320  for( c = 0; c < lp->ncols; ++c )
15321  {
15322  assert(lp->cols[c] != NULL);
15323  assert(lp->cols[c]->var != NULL);
15324  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15325  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15326  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15327  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15328  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15329  }
15330  }
15331 #endif
15332 
15333  return SCIP_OKAY;
15334 }
15335 
15336 #define DIVESTACKGROWFACT 1.5
15337 
15338 /** records a current row side such that any change will be undone after diving */
15340  SCIP_LP* lp, /**< LP data object */
15341  SCIP_ROW* row, /**< row affected by the change */
15342  SCIP_SIDETYPE sidetype /**< side type */
15343  )
15344 {
15345  assert(lp != NULL);
15346  assert(row != NULL);
15347 
15348  if( lp->ndivechgsides == lp->divechgsidessize )
15349  {
15351  }
15352  assert(lp->ndivechgsides < lp->divechgsidessize);
15353 
15354  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
15355  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
15356  lp->divechgrows[lp->ndivechgsides] = row;
15357  lp->ndivechgsides++;
15358 
15359  return SCIP_OKAY;
15360 }
15361 
15362 /** informs the LP that probing mode was initiated */
15364  SCIP_LP* lp /**< current LP data */
15365  )
15366 {
15367  assert(lp != NULL);
15368  assert(!lp->probing);
15369  assert(!lp->strongbranching);
15370  assert(!lp->strongbranchprobing);
15371 
15372  lp->probing = TRUE;
15373 
15374  return SCIP_OKAY;
15375 }
15376 
15377 /** informs the LP that probing mode was finished */
15379  SCIP_LP* lp /**< current LP data */
15380  )
15381 {
15382  assert(lp != NULL);
15383  assert(lp->probing);
15384  assert(!lp->strongbranching);
15385  assert(!lp->strongbranchprobing);
15386 
15387  lp->probing = FALSE;
15388 
15389  return SCIP_OKAY;
15390 }
15391 
15392 /** informs the LP that the probing mode is now used for strongbranching */
15394  SCIP_LP* lp /**< current LP data */
15395  )
15396 {
15397  assert(lp != NULL);
15398  assert(lp->probing);
15399  assert(!lp->strongbranching);
15400  assert(!lp->strongbranchprobing);
15401 
15402  lp->strongbranchprobing = TRUE;
15403 }
15404 
15405 /** informs the LP that the probing mode is not used for strongbranching anymore */
15407  SCIP_LP* lp /**< current LP data */
15408  )
15409 {
15410  assert(lp != NULL);
15411  assert(lp->probing);
15412  assert(!lp->strongbranching);
15413  assert(lp->strongbranchprobing);
15414 
15415  lp->strongbranchprobing = FALSE;
15416 }
15417 
15418 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
15419  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
15420  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
15421  * we have only left hand sides):
15422  * min{cx | b <= Ax, lb <= x <= ub}
15423  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
15424  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
15425  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
15426  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
15427  */
15428 static
15430  SCIP_LP* lp, /**< current LP data */
15431  SCIP_SET* set, /**< global SCIP settings */
15432  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
15433  SCIP_Real* bound /**< result of interval arithmetic minimization */
15434  )
15435 {
15436  SCIP_INTERVAL* yinter;
15437  SCIP_INTERVAL b;
15438  SCIP_INTERVAL ytb;
15439  SCIP_INTERVAL prod;
15440  SCIP_INTERVAL diff;
15441  SCIP_INTERVAL x;
15442  SCIP_INTERVAL minprod;
15443  SCIP_INTERVAL a;
15444  SCIP_ROW* row;
15445  SCIP_COL* col;
15446  SCIP_Real y;
15447  SCIP_Real c;
15448  int i;
15449  int j;
15450 
15451  assert(lp != NULL);
15452  assert(lp->solved);
15453  assert(set != NULL);
15454  assert(bound != NULL);
15455 
15456  /* allocate buffer for storing y in interval arithmetic */
15457  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
15458 
15459  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
15460  SCIPintervalSet(&ytb, 0.0);
15461  for( j = 0; j < lp->nrows; ++j )
15462  {
15463  row = lp->rows[j];
15464  assert(row != NULL);
15465 
15466  y = (usefarkas ? row->dualfarkas : row->dualsol);
15467 
15468  if( SCIPsetIsFeasPositive(set, y) )
15469  {
15470  SCIPintervalSet(&yinter[j], y);
15471  SCIPintervalSet(&b, row->lhs - row->constant);
15472  }
15473  else if( SCIPsetIsFeasNegative(set, y) )
15474  {
15475  SCIPintervalSet(&yinter[j], y);
15476  SCIPintervalSet(&b, row->rhs - row->constant);
15477  }
15478  else
15479  {
15480  SCIPintervalSet(&yinter[j], 0.0);
15481  SCIPintervalSet(&b, 0.0);
15482  }
15483 
15484  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
15485  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
15486  }
15487 
15488  /* calculate min{(c^T - y^TA)x} */
15489  SCIPintervalSet(&minprod, 0.0);
15490  for( j = 0; j < lp->ncols; ++j )
15491  {
15492  col = lp->cols[j];
15493  assert(col != NULL);
15494  assert(col->nunlinked == 0);
15495 
15497 
15498  c = usefarkas ? 0.0 : col->obj;
15499  SCIPintervalSet(&diff, c);
15500 
15501  for( i = 0; i < col->nlprows; ++i )
15502  {
15503  assert(col->rows[i] != NULL);
15504  assert(col->rows[i]->lppos >= 0);
15505  assert(col->linkpos[i] >= 0);
15506  SCIPintervalSet(&a, col->vals[i]);
15507  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
15508  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
15509  }
15510 
15511 #ifndef NDEBUG
15512  for( i = col->nlprows; i < col->len; ++i )
15513  {
15514  assert(col->rows[i] != NULL);
15515  assert(col->rows[i]->lppos == -1);
15516  assert(col->rows[i]->dualsol == 0.0);
15517  assert(col->rows[i]->dualfarkas == 0.0);
15518  assert(col->linkpos[i] >= 0);
15519  }
15520 #endif
15521 
15522  SCIPintervalSetBounds(&x, col->lb, col->ub);
15523  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
15524  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
15525  }
15526 
15527  /* add y^Tb */
15528  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
15529 
15530  /* free buffer for storing y in interval arithmetic */
15531  SCIPsetFreeBufferArray(set, &yinter);
15532 
15533  *bound = SCIPintervalGetInf(minprod);
15534 
15535  return SCIP_OKAY;
15536 }
15537 
15538 /** gets proven lower (dual) bound of last LP solution */
15540  SCIP_LP* lp, /**< current LP data */
15541  SCIP_SET* set, /**< global SCIP settings */
15542  SCIP_Real* bound /**< pointer to store proven dual bound */
15543  )
15544 {
15545  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
15546 
15547  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
15548 
15549  return SCIP_OKAY;
15550 }
15551 
15552 /** gets proven dual bound of last LP solution */
15554  SCIP_LP* lp, /**< current LP data */
15555  SCIP_SET* set, /**< global SCIP settings */
15556  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
15557  )
15558 {
15559  SCIP_Real bound;
15560 
15561  assert(proved != NULL);
15562 
15563  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
15564 
15565  *proved = (bound > 0.0);
15566 
15567  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
15568 
15569  return SCIP_OKAY;
15570 }
15571 
15572 
15573 
15574 /** writes LP to a file */
15576  SCIP_LP* lp, /**< current LP data */
15577  const char* fname /**< file name */
15578  )
15579 {
15580  assert(lp != NULL);
15581  assert(lp->flushed);
15582  assert(fname != NULL);
15583 
15584  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
15585 
15586  return SCIP_OKAY;
15587 }
15588 
15589 /** writes MIP relaxation of the current B&B node to a file */
15591  SCIP_LP* lp, /**< current LP data */
15592  SCIP_SET* set, /**< global SCIP settings */
15593  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15594  const char* fname, /**< file name */
15595  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
15596  * troubles with reserved symbols? */
15597  SCIP_Bool origobj, /**< should the original objective function be used? */
15598  SCIP_OBJSENSE objsense, /**< objective sense */
15599  SCIP_Real objscale, /**< objective scaling factor */
15600  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
15601  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
15602  )
15603 {
15604  FILE* file;
15605  int i;
15606  int j;
15607  char rowname[SCIP_MAXSTRLEN];
15608  SCIP_Real coeff;
15609 
15610  assert(lp != NULL);
15611  assert(lp->flushed);
15612  assert(fname != NULL);
15613 
15614  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
15615  file = fopen(fname, "w");
15616  if( file == NULL )
15617  {
15618  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
15619  SCIPprintSysError(fname);
15620  return SCIP_FILECREATEERROR;
15621  }
15622 
15623  /* print comments */
15624  if( genericnames )
15625  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
15626  else
15627  {
15628  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
15629  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
15630  }
15631 
15632  if( origobj && objoffset != 0.0 )
15633  {
15634  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
15635  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
15636  }
15637 
15638  /* print objective function */
15639  /**@note the transformed problem in SCIP is always a minimization problem */
15640  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
15641  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
15642  else
15643  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
15644 
15645  /* print objective */
15646  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
15647  j = 0;
15648  for( i = 0; i < lp->ncols; ++i )
15649  {
15650  if( lp->cols[i]->obj != 0.0 )
15651  {
15652  coeff = lp->cols[i]->obj;
15653  if( origobj )
15654  {
15655  coeff *= (SCIP_Real) objsense;
15656  coeff *= objscale;
15657  }
15658 
15659  if( genericnames )
15660  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
15661  else
15662  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
15663 
15664  ++j;
15665  if( j % 10 == 0 )
15666  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15667  }
15668  }
15669  /* add artificial variable 'objoffset' to transfer objective offset */
15670  if( origobj && objoffset != 0.0 )
15671  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
15672 
15673  /* print constraint section */
15674  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
15675  for( i = 0; i < lp->nrows; i++ )
15676  {
15677  char type = 'i';
15678 
15679  /* skip removable rows if we want to write them as lazy constraints */
15680  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
15681  continue;
15682 
15683  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15684  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15685  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15686  * type 'i' means: lhs and rhs are both infinite */
15687  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15688  type = 'r';
15689  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15690  type = 'l';
15691  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15692  type = 'e';
15693  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15694  type = 'b';
15695 
15696  /* print name of row */
15697  if( genericnames )
15698  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15699  else
15700  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15701 
15702  WRITEROW:
15703  switch( type )
15704  {
15705  case 'r':
15706  case 'l':
15707  case 'e':
15708  if( strlen(rowname) > 0 )
15709  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15710  break;
15711  case 'i':
15712  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15713  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15714  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
15715  type = 'b';
15716  /*lint -fallthrough*/
15717  case 'b':
15718  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15719  break;
15720  case 'B':
15721  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15722  break;
15723  default:
15724  SCIPerrorMessage("Undefined row type!\n");
15725  return SCIP_ERROR;
15726  }
15727 
15728  /* print coefficients and variables */
15729  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15730  {
15731  if( genericnames )
15732  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15733  else
15734  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15735 
15736  if( (j+1) % 10 == 0 )
15737  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15738  }
15739 
15740  /* print right hand side */
15741  switch( type )
15742  {
15743  case 'b':
15744  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15745  type = 'B';
15746  goto WRITEROW;
15747  case 'l':
15748  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15749  break;
15750  case 'B':
15751  case 'r':
15752  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15753  break;
15754  case 'e':
15755  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15756  break;
15757  default:
15758  SCIPerrorMessage("Undefined row type!\n");
15759  return SCIP_ERROR;
15760  }
15761  }
15762 
15763  if ( lazyconss )
15764  {
15765  /* print lazy constraint section */
15766  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
15767  for( i = 0; i < lp->nrows; i++ )
15768  {
15769  char type = 'i';
15770 
15771  /* skip non-removable rows if we want to write lazy constraints */
15772  if ( ! SCIProwIsRemovable(lp->rows[i]) )
15773  continue;
15774 
15775  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15776  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15777  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15778  * type 'i' means: lhs and rhs are both infinite */
15779  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15780  type = 'r';
15781  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15782  type = 'l';
15783  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15784  type = 'e';
15785  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15786  type = 'b';
15787 
15788  /* print name of row */
15789  if( genericnames )
15790  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15791  else
15792  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15793 
15794  WRITELAZYROW:
15795  switch( type )
15796  {
15797  case 'r':
15798  case 'l':
15799  case 'e':
15800  if( strlen(rowname) > 0 )
15801  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15802  break;
15803  case 'i':
15804  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15805  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15806  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
15807  type = 'b';
15808  /*lint -fallthrough*/
15809  case 'b':
15810  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15811  break;
15812  case 'B':
15813  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15814  break;
15815  default:
15816  SCIPerrorMessage("Undefined row type!\n");
15817  return SCIP_ERROR;
15818  }
15819 
15820  /* print coefficients and variables */
15821  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15822  {
15823  if( genericnames )
15824  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15825  else
15826  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15827 
15828  if( (j+1) % 10 == 0 )
15829  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15830  }
15831 
15832  /* print right hand side */
15833  switch( type )
15834  {
15835  case 'b':
15836  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15837  type = 'B';
15838  goto WRITELAZYROW;
15839  case 'l':
15840  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15841  break;
15842  case 'B':
15843  case 'r':
15844  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15845  break;
15846  case 'e':
15847  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15848  break;
15849  default:
15850  SCIPerrorMessage("Undefined row type!\n");
15851  return SCIP_ERROR;
15852  }
15853  }
15854  }
15855 
15856  /* print variable bounds */
15857  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
15858  for( i = 0; i < lp->ncols; ++i )
15859  {
15860  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
15861  {
15862  /* print lower bound as far this one is not infinity */
15863  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
15864  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
15865 
15866  /* print variable name */
15867  if( genericnames )
15868  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
15869  else
15870  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
15871 
15872  /* print upper bound as far this one is not infinity */
15873  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
15874  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
15875  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
15876  }
15877  }
15878  if( origobj && objoffset != 0.0 )
15879  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
15880 
15881  /* print integer variables */
15882  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
15883  j = 0;
15884  for( i = 0; i < lp->ncols; ++i )
15885  {
15886  if( SCIPvarIsIntegral(lp->cols[i]->var) )
15887  {
15888  /* print variable name */
15889  if( genericnames )
15890  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
15891  else
15892  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
15893 
15894  j++;
15895  if( j % 10 == 0 )
15896  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
15897  }
15898  }
15899 
15900  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
15901  fclose(file);
15902 
15903  return SCIP_OKAY;
15904 }
15905 
15906 /*
15907  * simple functions implemented as defines
15908  */
15909 
15910 /* In debug mode, the following methods are implemented as function calls to ensure
15911  * type validity.
15912  * In optimized mode, the methods are implemented as defines to improve performance.
15913  * However, we want to have them in the library anyways, so we have to undef the defines.
15914  */
15915 
15916 #undef SCIPcolGetObj
15917 #undef SCIPcolGetLb
15918 #undef SCIPcolGetUb
15919 #undef SCIPcolGetBestBound
15920 #undef SCIPcolGetPrimsol
15921 #undef SCIPcolGetMinPrimsol
15922 #undef SCIPcolGetMaxPrimsol
15923 #undef SCIPcolGetBasisStatus
15924 #undef SCIPcolGetVar
15925 #undef SCIPcolGetIndex
15926 #undef SCIPcolIsIntegral
15927 #undef SCIPcolIsRemovable
15928 #undef SCIPcolGetLPPos
15929 #undef SCIPcolGetLPDepth
15930 #undef SCIPcolIsInLP
15931 #undef SCIPcolGetNNonz
15932 #undef SCIPcolGetNLPNonz
15933 #undef SCIPcolGetRows
15934 #undef SCIPcolGetVals
15935 #undef SCIPcolGetStrongbranchNode
15936 #undef SCIPcolGetNStrongbranchs
15937 #undef SCIPboundtypeOpposite
15938 #undef SCIProwGetNNonz
15939 #undef SCIProwGetNLPNonz
15940 #undef SCIProwGetCols
15941 #undef SCIProwGetVals
15942 #undef SCIProwGetConstant
15943 #undef SCIProwGetNorm
15944 #undef SCIProwGetSumNorm
15945 #undef SCIProwGetLhs
15946 #undef SCIProwGetRhs
15947 #undef SCIProwGetDualsol
15948 #undef SCIProwGetDualfarkas
15949 #undef SCIProwGetBasisStatus
15950 #undef SCIProwGetName
15951 #undef SCIProwGetIndex
15952 #undef SCIProwGetAge
15953 #undef SCIProwGetRank
15954 #undef SCIProwIsIntegral
15955 #undef SCIProwIsLocal
15956 #undef SCIProwIsModifiable
15957 #undef SCIProwIsRemovable
15958 #undef SCIProwGetOrigintype
15959 #undef SCIProwGetOriginCons
15960 #undef SCIProwGetOriginSepa
15961 #undef SCIProwIsInGlobalCutpool
15962 #undef SCIProwGetLPPos
15963 #undef SCIProwGetLPDepth
15964 #undef SCIProwIsInLP
15965 #undef SCIProwGetActiveLPCount
15966 #undef SCIProwGetNLPsAfterCreation
15967 #undef SCIProwChgRank
15968 #undef SCIPlpGetCols
15969 #undef SCIPlpGetNCols
15970 #undef SCIPlpGetRows
15971 #undef SCIPlpGetNRows
15972 #undef SCIPlpGetNewcols
15973 #undef SCIPlpGetNNewcols
15974 #undef SCIPlpGetNewrows
15975 #undef SCIPlpGetNNewrows
15976 #undef SCIPlpGetObjNorm
15977 #undef SCIPlpGetRootObjval
15978 #undef SCIPlpGetRootColumnObjval
15979 #undef SCIPlpGetRootLooseObjval
15980 #undef SCIPlpGetLPI
15981 #undef SCIPlpSetIsRelax
15982 #undef SCIPlpIsRelax
15983 #undef SCIPlpIsSolved
15984 #undef SCIPlpIsSolBasic
15985 #undef SCIPlpDiving
15986 #undef SCIPlpDivingObjChanged
15987 #undef SCIPlpMarkDivingObjChanged
15988 #undef SCIPlpUnmarkDivingObjChanged
15989 #undef SCIPlpDivingRowsChanged
15990 
15991 /** gets objective value of column */
15993  SCIP_COL* col /**< LP column */
15994  )
15995 {
15996  assert(col != NULL);
15997 
15998  return col->obj;
15999 }
16000 
16001 /** gets lower bound of column */
16003  SCIP_COL* col /**< LP column */
16004  )
16005 {
16006  assert(col != NULL);
16007 
16008  return col->lb;
16009 }
16010 
16011 /** gets upper bound of column */
16013  SCIP_COL* col /**< LP column */
16014  )
16015 {
16016  assert(col != NULL);
16017 
16018  return col->ub;
16019 }
16020 
16021 /** gets best bound of column with respect to the objective function */
16023  SCIP_COL* col /**< LP column */
16024  )
16025 {
16026  assert(col != NULL);
16027 
16028  if( col->obj >= 0.0 )
16029  return col->lb;
16030  else
16031  return col->ub;
16032 }
16033 
16034 /** gets the primal LP solution of a column */
16036  SCIP_COL* col /**< LP column */
16037  )
16038 {
16039  assert(col != NULL);
16040 
16041  if( col->lppos >= 0 )
16042  return col->primsol;
16043  else
16044  return 0.0;
16045 }
16046 
16047 /** gets the minimal LP solution value, this column ever assumed */
16049  SCIP_COL* col /**< LP column */
16050  )
16051 {
16052  assert(col != NULL);
16053 
16054  return col->minprimsol;
16055 }
16056 
16057 /** gets the maximal LP solution value, this column ever assumed */
16059  SCIP_COL* col /**< LP column */
16060  )
16061 {
16062  assert(col != NULL);
16063 
16064  return col->maxprimsol;
16065 }
16066 
16067 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16068  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16069  */
16071  SCIP_COL* col /**< LP column */
16072  )
16073 {
16074  assert(col != NULL);
16075  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16076 
16077  return (SCIP_BASESTAT)col->basisstatus;
16078 }
16079 
16080 /** gets variable this column represents */
16082  SCIP_COL* col /**< LP column */
16083  )
16084 {
16085  assert(col != NULL);
16086 
16087  return col->var;
16088 }
16089 
16090 /** gets unique index of col */
16092  SCIP_COL* col /**< LP col */
16093  )
16094 {
16095  assert(col != NULL);
16096 
16097  return col->index;
16098 }
16099 
16100 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16102  SCIP_COL* col /**< LP column */
16103  )
16104 {
16105  assert(col != NULL);
16106  assert(SCIPvarIsIntegral(col->var) == col->integral);
16107 
16108  return col->integral;
16109 }
16110 
16111 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16113  SCIP_COL* col /**< LP column */
16114  )
16115 {
16116  assert(col != NULL);
16117 
16118  return col->removable;
16119 }
16120 
16121 /** gets position of column in current LP, or -1 if it is not in LP */
16123  SCIP_COL* col /**< LP column */
16124  )
16125 {
16126  assert(col != NULL);
16127  assert((col->lppos == -1) == (col->lpdepth == -1));
16128 
16129  return col->lppos;
16130 }
16131 
16132 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16134  SCIP_COL* col /**< LP column */
16135  )
16136 {
16137  assert(col != NULL);
16138  assert((col->lppos == -1) == (col->lpdepth == -1));
16139 
16140  return col->lpdepth;
16141 }
16142 
16143 /** returns TRUE iff column is member of current LP */
16145  SCIP_COL* col /**< LP column */
16146  )
16147 {
16148  assert(col != NULL);
16149  assert((col->lppos == -1) == (col->lpdepth == -1));
16150 
16151  return (col->lppos >= 0);
16152 }
16153 
16154 /** get number of nonzero entries in column vector */
16156  SCIP_COL* col /**< LP column */
16157  )
16158 {
16159  assert(col != NULL);
16160 
16161  return col->len;
16162 }
16163 
16164 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16165  *
16166  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16167  * 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
16168  */
16170  SCIP_COL* col /**< LP column */
16171  )
16172 {
16173  assert(col != NULL);
16174  assert(col->nunlinked == 0);
16175 
16176  return col->nlprows;
16177 }
16178 
16179 /** gets array with rows of nonzero entries */
16181  SCIP_COL* col /**< LP column */
16182  )
16183 {
16184  assert(col != NULL);
16185 
16186  return col->rows;
16187 }
16188 
16189 /** gets array with coefficients of nonzero entries */
16191  SCIP_COL* col /**< LP column */
16192  )
16193 {
16194  assert(col != NULL);
16195 
16196  return col->vals;
16197 }
16198 
16199 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16200  * given column, or -1 if strong branching was never applied to the column in current run
16201  */
16203  SCIP_COL* col /**< LP column */
16204  )
16205 {
16206  assert(col != NULL);
16207 
16208  return col->sbnode;
16209 }
16210 
16211 /** gets number of times, strong branching was applied in current run on the given column */
16213  SCIP_COL* col /**< LP column */
16214  )
16215 {
16216  assert(col != NULL);
16217 
16218  return col->nsbcalls;
16219 }
16220 
16221 /** gets opposite bound type of given bound type */
16223  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16224  )
16225 {
16226  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16227 
16229 }
16230 
16231 /** get number of nonzero entries in row vector */
16233  SCIP_ROW* row /**< LP row */
16234  )
16235 {
16236  assert(row != NULL);
16237 
16238  return row->len;
16239 }
16240 
16241 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16242  *
16243  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16244  * 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
16245  */
16247  SCIP_ROW* row /**< LP row */
16248  )
16249 {
16250  assert(row != NULL);
16251  assert(row->nunlinked == 0);
16252 
16253  return row->nlpcols;
16254 }
16255 
16256 /** gets array with columns of nonzero entries */
16258  SCIP_ROW* row /**< LP row */
16259  )
16260 {
16261  assert(row != NULL);
16262 
16263  return row->cols;
16264 }
16265 
16266 /** gets array with coefficients of nonzero entries */
16268  SCIP_ROW* row /**< LP row */
16269  )
16270 {
16271  assert(row != NULL);
16272 
16273  return row->vals;
16274 }
16275 
16276 /** gets constant shift of row */
16278  SCIP_ROW* row /**< LP row */
16279  )
16280 {
16281  assert(row != NULL);
16282 
16283  return row->constant;
16284 }
16285 
16286 /** gets Euclidean norm of row vector */
16288  SCIP_ROW* row /**< LP row */
16289  )
16290 {
16291  assert(row != NULL);
16292 
16293  checkRowSqrnorm(row);
16294 
16295  return sqrt(row->sqrnorm);
16296 }
16297 
16298 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16300  SCIP_ROW* row /**< LP row */
16301  )
16302 {
16303  assert(row != NULL);
16304 
16305  checkRowSumnorm(row);
16306 
16307  return row->sumnorm;
16308 }
16309 
16310 /** returns the left hand side of the row */
16312  SCIP_ROW* row /**< LP row */
16313  )
16314 {
16315  assert(row != NULL);
16316 
16317  return row->lhs;
16318 }
16319 
16320 /** returns the right hand side of the row */
16322  SCIP_ROW* row /**< LP row */
16323  )
16324 {
16325  assert(row != NULL);
16326 
16327  return row->rhs;
16328 }
16329 
16330 /** gets the dual LP solution of a row */
16332  SCIP_ROW* row /**< LP row */
16333  )
16334 {
16335  assert(row != NULL);
16336 
16337  if( row->lppos >= 0 )
16338  return row->dualsol;
16339  else
16340  return 0.0;
16341 }
16342 
16343 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16345  SCIP_ROW* row /**< LP row */
16346  )
16347 {
16348  assert(row != NULL);
16349 
16350  if( row->lppos >= 0 )
16351  return row->dualfarkas;
16352  else
16353  return 0.0;
16354 }
16355 
16356 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16357  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
16358  */
16360  SCIP_ROW* row /**< LP row */
16361  )
16362 {
16363  assert(row != NULL);
16364  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
16365 
16366  return (SCIP_BASESTAT)row->basisstatus;
16367 }
16368 
16369 /** returns the name of the row */
16370 const char* SCIProwGetName(
16371  SCIP_ROW* row /**< LP row */
16372  )
16373 {
16374  assert(row != NULL);
16375 
16376  return row->name;
16377 }
16378 
16379 /** gets unique index of row */
16381  SCIP_ROW* row /**< LP row */
16382  )
16383 {
16384  assert(row != NULL);
16385 
16386  return row->index;
16387 }
16388 
16389 /** gets age of row */
16391  SCIP_ROW* row /**< LP row */
16392  )
16393 {
16394  assert(row != NULL);
16395 
16396  return row->age;
16397 }
16398 
16399 /** gets rank of row */
16401  SCIP_ROW* row /**< LP row */
16402  )
16403 {
16404  assert(row != NULL);
16405 
16406  return row->rank;
16407 }
16408 
16409 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
16411  SCIP_ROW* row /**< LP row */
16412  )
16413 {
16414  assert(row != NULL);
16415 
16416  return row->integral;
16417 }
16418 
16419 /** returns TRUE iff row is only valid locally */
16421  SCIP_ROW* row /**< LP row */
16422  )
16423 {
16424  assert(row != NULL);
16425 
16426  return row->local;
16427 }
16428 
16429 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
16431  SCIP_ROW* row /**< LP row */
16432  )
16433 {
16434  assert(row != NULL);
16435 
16436  return row->modifiable;
16437 }
16438 
16439 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
16441  SCIP_ROW* row /**< LP row */
16442  )
16443 {
16444  assert(row != NULL);
16445 
16446  return row->removable;
16447 }
16448 
16449 /** returns type of origin that created the row */
16451  SCIP_ROW* row /**< LP row */
16452  )
16453 {
16454  assert( row != NULL );
16455 
16456  return (SCIP_ROWORIGINTYPE) row->origintype;
16457 }
16458 
16459 /** returns origin constraint handler that created the row (NULL if not available) */
16461  SCIP_ROW* row /**< LP row */
16462  )
16463 {
16464  assert( row != NULL );
16465 
16467  {
16468  assert( row->origin != NULL );
16469  return (SCIP_CONSHDLR*) row->origin;
16470  }
16471  return NULL;
16472 }
16473 
16474 /** returns origin separator that created the row (NULL if not available) */
16476  SCIP_ROW* row /**< LP row */
16477  )
16478 {
16479  assert( row != NULL );
16480 
16482  {
16483  assert( row->origin != NULL );
16484  return (SCIP_SEPA*) row->origin;
16485  }
16486  return NULL;
16487 }
16488 
16489 /** returns TRUE iff row is member of the global cut pool */
16491  SCIP_ROW* row /**< LP row */
16492  )
16493 {
16494  assert(row != NULL);
16495 
16496  return row->inglobalcutpool;
16497 }
16498 
16499 /** gets position of row in current LP, or -1 if it is not in LP */
16501  SCIP_ROW* row /**< LP row */
16502  )
16503 {
16504  assert(row != NULL);
16505  assert((row->lppos == -1) == (row->lpdepth == -1));
16506 
16507  return row->lppos;
16508 }
16509 
16510 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
16512  SCIP_ROW* row /**< LP row */
16513  )
16514 {
16515  assert(row != NULL);
16516  assert((row->lppos == -1) == (row->lpdepth == -1));
16517 
16518  return row->lpdepth;
16519 }
16520 
16521 /** returns TRUE iff row is member of current LP */
16523  SCIP_ROW* row /**< LP row */
16524  )
16525 {
16526  assert(row != NULL);
16527  assert((row->lppos == -1) == (row->lpdepth == -1));
16528 
16529  return (row->lppos >= 0);
16530 }
16531 
16532 /** changes the rank of LP row */
16534  SCIP_ROW* row, /**< LP row */
16535  int rank /**< new value for rank */
16536  )
16537 {
16538  assert(row != NULL);
16539 
16540  row->rank = rank;
16541 }
16542 
16543 /** returns the number of times that this row has been sharp in an optimal LP solution */
16545  SCIP_ROW* row /**< row */
16546  )
16547 {
16548  assert(row != NULL);
16549 
16550  return row->activeinlpcounter;
16551 }
16552 
16553 /** returns the number of LPs since this row has been created */
16555  SCIP_ROW* row /**< row */
16556  )
16557 {
16558  assert(row != NULL);
16559 
16560  return row->nlpsaftercreation;
16561 }
16562 
16563 /** gets array with columns of the LP */
16565  SCIP_LP* lp /**< current LP data */
16566  )
16567 {
16568  assert(lp != NULL);
16569 
16570  return lp->cols;
16571 }
16572 
16573 /** gets current number of columns in LP */
16575  SCIP_LP* lp /**< current LP data */
16576  )
16577 {
16578  assert(lp != NULL);
16579 
16580  return lp->ncols;
16581 }
16582 
16583 /** gets array with rows of the LP */
16585  SCIP_LP* lp /**< current LP data */
16586  )
16587 {
16588  assert(lp != NULL);
16589 
16590  return lp->rows;
16591 }
16592 
16593 /** gets current number of rows in LP */
16595  SCIP_LP* lp /**< current LP data */
16596  )
16597 {
16598  assert(lp != NULL);
16599 
16600  return lp->nrows;
16601 }
16602 
16603 /** gets array with newly added columns after the last mark */
16605  SCIP_LP* lp /**< current LP data */
16606  )
16607 {
16608  assert(lp != NULL);
16609  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16610 
16611  return &(lp->cols[lp->firstnewcol]);
16612 }
16613 
16614 /** gets number of newly added columns after the last mark */
16616  SCIP_LP* lp /**< current LP data */
16617  )
16618 {
16619  assert(lp != NULL);
16620  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16621 
16622  return lp->ncols - lp->firstnewcol;
16623 }
16624 
16625 /** gets array with newly added rows after the last mark */
16627  SCIP_LP* lp /**< current LP data */
16628  )
16629 {
16630  assert(lp != NULL);
16631  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16632 
16633  return &(lp->rows[lp->firstnewrow]);
16634 }
16635 
16636 /** gets number of newly added rows after the last mark */
16638  SCIP_LP* lp /**< current LP data */
16639  )
16640 {
16641  assert(lp != NULL);
16642  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16643 
16644  return lp->nrows - lp->firstnewrow;
16645 }
16646 
16647 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
16649  SCIP_SET* set, /**< global SCIP settings */
16650  SCIP_LP* lp /**< LP data */
16651  )
16652 {
16653  if( lp->objsqrnormunreliable )
16654  {
16655  SCIP_COL** cols;
16656  int c;
16657 
16658  cols = lp->cols;
16659  assert(cols != NULL || lp->ncols == 0);
16660 
16661  lp->objsqrnorm = 0.0;
16662 
16663  for( c = lp->ncols - 1; c >= 0; --c )
16664  {
16665  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
16666  }
16667  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
16668 
16669  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
16670  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
16671 
16673  }
16674  return;
16675 }
16676 
16677 /** gets Euclidean norm of objective function vector of column variables, only use this method if
16678  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
16680  SCIP_LP* lp /**< LP data */
16681  )
16682 {
16683  assert(lp != NULL);
16684  assert(!lp->objsqrnormunreliable);
16685  assert(lp->objsqrnorm >= 0.0);
16686 
16687  return SQRT(lp->objsqrnorm);
16688 }
16689 
16690 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16692  SCIP_LP* lp, /**< LP data */
16693  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
16694  )
16695 {
16696  assert(lp != NULL);
16697 
16698  lp->rootlpisrelax = isrelax;
16699 }
16700 
16701 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16703  SCIP_LP* lp /**< LP data */
16704  )
16705 {
16706  assert(lp != NULL);
16707 
16708  return lp->rootlpisrelax;
16709 }
16710 
16711 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
16713  SCIP_LP* lp /**< LP data */
16714  )
16715 {
16716  assert(lp != NULL);
16717 
16718  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
16719 }
16720 
16721 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
16722  * returns SCIP_INVALID if the root node LP was not (yet) solved
16723  */
16725  SCIP_LP* lp /**< LP data */
16726  )
16727 {
16728  assert(lp != NULL);
16729 
16730  return lp->rootlpobjval;
16731 }
16732 
16733 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
16734  * returns SCIP_INVALID if the root node LP was not (yet) solved
16735  */
16737  SCIP_LP* lp /**< LP data */
16738  )
16739 {
16740  assert(lp != NULL);
16741 
16742  return lp->rootlooseobjval;
16743 }
16744 
16745 /** gets the LP solver interface */
16747  SCIP_LP* lp /**< current LP data */
16748  )
16749 {
16750  assert(lp != NULL);
16751 
16752  return lp->lpi;
16753 }
16754 
16755 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
16757  SCIP_LP* lp, /**< LP data */
16758  SCIP_Bool relax /**< is the current lp a relaxation? */
16759  )
16760 {
16761  assert(lp != NULL);
16762 
16763  lp->isrelax = relax;
16764 }
16765 
16766 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
16767  * solution value a valid local lower bound?
16768  */
16770  SCIP_LP* lp /**< LP data */
16771  )
16772 {
16773  assert(lp != NULL);
16774 
16775  return lp->isrelax;
16776 }
16777 
16778 /** returns whether the current LP is flushed and solved */
16780  SCIP_LP* lp /**< current LP data */
16781  )
16782 {
16783  assert(lp != NULL);
16784 
16785  return lp->flushed && lp->solved;
16786 }
16787 
16788 /** returns whether the current LP solution is a basic solution */
16790  SCIP_LP* lp /**< current LP data */
16791  )
16792 {
16793  assert(lp != NULL);
16794 
16795  return lp->solisbasic;
16796 }
16797 
16798 /** returns whether the LP is in diving mode */
16800  SCIP_LP* lp /**< current LP data */
16801  )
16802 {
16803  assert(lp != NULL);
16804 
16805  return lp->diving;
16806 }
16807 
16808 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
16810  SCIP_LP* lp /**< current LP data */
16811  )
16812 {
16813  assert(lp != NULL);
16814 
16815  return lp->divingobjchg;
16816 }
16817 
16818 /** marks the diving LP to have a changed objective function */
16820  SCIP_LP* lp /**< current LP data */
16821  )
16822 {
16823  assert(lp != NULL);
16824  assert(lp->diving || lp->probing);
16825 
16826  lp->divingobjchg = TRUE;
16827 }
16828 
16829 /** marks the diving LP to not have a changed objective function anymore */
16831  SCIP_LP* lp /**< current LP data */
16832  )
16833 {
16834  assert(lp != NULL);
16835  assert(lp->diving || lp->probing);
16836 
16837  lp->divingobjchg = FALSE;
16838 }
16839 
16840 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
16842  SCIP_LP* lp /**< current LP data */
16843  )
16844 {
16845  assert(lp != NULL);
16846  assert(lp->diving || lp->ndivechgsides == 0);
16847 
16848  return (lp->ndivechgsides > 0);
16849 }
16850 
16851 /** compute relative interior point
16852  *
16853  * We use the approach of@par
16854  * R. Freund, R. Roundy, M. J. Todd@par
16855  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
16856  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
16857  *
16858  * to compute a relative interior point for the current LP.
16859  *
16860  * Assume the original LP looks as follows:
16861  * \f[
16862  * \begin{array}{rrl}
16863  * \min & c^T x &\\
16864  * & A x & \geq a\\
16865  * & B x & \leq b\\
16866  * & D x & = d.
16867  * \end{array}
16868  * \f]
16869  * Note that bounds should be included in the system.
16870  *
16871  * To find an interior point the following LP does the job:
16872  * \f[
16873  * \begin{array}{rrl}
16874  * \max & 1^T y &\\
16875  * & A x - y - \alpha a & \geq 0\\
16876  * & B x + y - \alpha b & \leq 0\\
16877  * & D x - \alpha d & = 0\\
16878  * & 0 \leq y & \leq 1\\
16879  * & \alpha & \geq 1.
16880  * \end{array}
16881  * \f]
16882  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
16883  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
16884  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
16885  */
16887  SCIP_SET* set, /**< global SCIP settings */
16888  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16889  SCIP_LP* lp, /**< LP data */
16890  SCIP_PROB* prob, /**< problem data */
16891  SCIP_Bool relaxrows, /**< should the rows be relaxed */
16892  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
16893  SCIP_Real timelimit, /**< time limit for LP solver */
16894  int iterlimit, /**< iteration limit for LP solver */
16895  SCIP_Real* point, /**< array to store relative interior point on exit */
16896  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
16897  )
16898 {
16899  SCIP_LPI* lpi;
16900  SCIP_Real* obj;
16901  SCIP_Real* lb;
16902  SCIP_Real* ub;
16903  SCIP_Real* primal;
16904  SCIP_Real* colvals;
16905  SCIP_Real zero;
16906  SCIP_Real minusinf;
16907  SCIP_Real plusinf;
16908  SCIP_Real objval;
16909  SCIP_Real alpha;
16910  SCIP_RETCODE retcode;
16911  int* colinds;
16912  int nnewcols;
16913 #ifndef NDEBUG
16914  int nslacks;
16915 #endif
16916  int beg;
16917  int cnt;
16918  int i;
16919  int j;
16920 
16921  assert(set != NULL);
16922  assert(lp != NULL);
16923  assert(point != NULL);
16924  assert(success != NULL);
16925 
16926  *success = FALSE;
16927 
16928  /* check time and iteration limits */
16929  if ( timelimit <= 0.0 || iterlimit <= 0 )
16930  return SCIP_OKAY;
16931 
16932  /* exit if there are no columns */
16933  assert(lp->nrows >= 0);
16934  assert(lp->ncols >= 0);
16935  if( lp->ncols == 0 )
16936  return SCIP_OKAY;
16937 
16938  /* disable objective cutoff if we have none */
16939  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
16940  inclobjcutoff = FALSE;
16941 
16942  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
16943 
16944  /* if there are no rows, we return the zero point */
16945  if( lp->nrows == 0 && !inclobjcutoff )
16946  {
16947  /* create zero point */
16948  BMSclearMemoryArray(point, lp->ncols);
16949  *success = TRUE;
16950 
16951  return SCIP_OKAY;
16952  }
16953 
16954  /* create auxiliary LP */
16955  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
16956 
16958  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
16959  {
16960  SCIP_CALL( retcode );
16961  }
16962 
16964  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
16965  {
16966  SCIP_CALL( retcode );
16967  }
16968 
16969  /* get storage */
16970  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
16971  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
16972  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
16973  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
16974 
16975  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
16976  for( j = 0; j < lp->ncols; ++j )
16977  {
16978  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
16979  obj[j] = 0.0;
16980  lb[j] = -SCIPlpiInfinity(lpi);
16981  ub[j] = SCIPlpiInfinity(lpi);
16982  /* note: we could also use the original bounds - free variables seem to be faster. */
16983  }
16984 
16985  /* add artificial alpha variable */
16986  nnewcols = lp->ncols;
16987  obj[nnewcols] = 0.0;
16988  lb[nnewcols] = 1.0;
16989  ub[nnewcols] = SCIPlpiInfinity(lpi);
16990  ++nnewcols;
16991 
16992  /* create slacks for rows */
16993  for( i = 0; i < lp->nrows; ++i )
16994  {
16995  SCIP_ROW* row;
16996 
16997  row = lp->rows[i];
16998  assert( row != NULL );
16999 
17000  if( SCIProwIsModifiable(row) )
17001  continue;
17002 
17003  /* make sure row is sorted */
17004  rowSortLP(row);
17005  assert( row->lpcolssorted );
17006 
17007  /* check whether we have an equation */
17008  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17009  {
17010  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17011  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17012  }
17013  else if( relaxrows )
17014  {
17015  /* otherwise add slacks for each side if necessary */
17016  if( !SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17017  {
17018  obj[nnewcols] = 1.0;
17019  lb[nnewcols] = 0.0;
17020  ub[nnewcols] = 1.0;
17021  ++nnewcols;
17022  }
17023  if( !SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17024  {
17025  obj[nnewcols] = 1.0;
17026  lb[nnewcols] = 0.0;
17027  ub[nnewcols] = 1.0;
17028  ++nnewcols;
17029  }
17030  }
17031  }
17032 
17033  /* create slacks for objective cutoff row */
17034  if( inclobjcutoff && relaxrows )
17035  {
17036  /* add slacks for right hand side */
17037  obj[nnewcols] = 1.0;
17038  lb[nnewcols] = 0.0;
17039  ub[nnewcols] = 1.0;
17040  ++nnewcols;
17041  }
17042 
17043  /* create slacks for bounds */
17044  for( j = 0; j < lp->ncols; ++j )
17045  {
17046  SCIP_COL* col;
17047 
17048  col = lp->cols[j];
17049  assert( col != NULL );
17050 
17051  /* no slacks for fixed variables */
17052  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17053  continue;
17054 
17055  /* add slacks for each bound if necessary */
17056  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17057  {
17058  obj[nnewcols] = 1.0;
17059  lb[nnewcols] = 0.0;
17060  ub[nnewcols] = 1.0;
17061  ++nnewcols;
17062  }
17063  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17064  {
17065  obj[nnewcols] = 1.0;
17066  lb[nnewcols] = 0.0;
17067  ub[nnewcols] = 1.0;
17068  ++nnewcols;
17069  }
17070  }
17071 #ifndef NDEBUG
17072  nslacks = nnewcols - lp->ncols - 1;
17073  assert( nslacks >= 0 );
17074  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17075 #endif
17076 
17077  /* add columns */
17078  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17079 
17080  /* free storage */
17081  SCIPsetFreeBufferArray(set, &obj);
17082  SCIPsetFreeBufferArray(set, &ub);
17083  SCIPsetFreeBufferArray(set, &lb);
17084 
17085  /* prepare storage for rows */
17086  SCIP_CALL( SCIPsetAllocBufferArray(set, &colinds, lp->ncols+2) );
17087  SCIP_CALL( SCIPsetAllocBufferArray(set, &colvals, lp->ncols+2) );
17088 
17089  /* create rows arising from original rows */
17090  cnt = 0;
17091  beg = 0;
17092  zero = 0.0;
17093  minusinf = -SCIPlpiInfinity(lpi);
17094  plusinf = SCIPlpiInfinity(lpi);
17095  for( i = 0; i < lp->nrows; ++i )
17096  {
17097  SCIP_ROW* row;
17098  SCIP_COL** rowcols;
17099  SCIP_Real* rowvals;
17100  SCIP_Real lhs;
17101  SCIP_Real rhs;
17102  int nnonz;
17103 
17104  row = lp->rows[i];
17105  assert( row != NULL );
17106 
17107  if( SCIProwIsModifiable(row) )
17108  continue;
17109  assert( row->lpcolssorted );
17110 
17111  /* get row data */
17112  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17113  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17114  nnonz = row->nlpcols;
17115  assert( nnonz <= lp->ncols );
17116  rowcols = row->cols;
17117  rowvals = row->vals;
17118 
17119  /* set up indices */
17120  for( j = 0; j < nnonz; ++j )
17121  {
17122  assert( rowcols[j] != NULL );
17123  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17124  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17125  colinds[j] = rowcols[j]->lppos;
17126  colvals[j] = rowvals[j];
17127  }
17128 
17129  /* if we have an equation */
17130  if( SCIPsetIsEQ(set, lhs, rhs) )
17131  {
17132  /* add artificial variable */
17133  colinds[nnonz] = lp->ncols;
17134  colvals[nnonz] = -rhs;
17135 
17136  /* add row */
17137  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &zero, NULL, nnonz+1, &beg, colinds, colvals) );
17138  }
17139  else
17140  {
17141  SCIP_Real abslhs = REALABS(lhs);
17142  SCIP_Real absrhs = REALABS(rhs);
17143 
17144  /* treat lhs */
17145  if( !SCIPsetIsInfinity(set, abslhs) )
17146  {
17147  assert(!SCIPsetIsEQ(set, lhs, rhs));
17148 
17149  /* add artificial variable */
17150  colinds[nnonz] = lp->ncols;
17151  colvals[nnonz] = -lhs;
17152 
17153  if( relaxrows )
17154  {
17155  /* add slack variable */
17156  colinds[nnonz+1] = lp->ncols + 1 + cnt; /*lint !e679*/
17157  colvals[nnonz+1] = -MAX(1.0, lhs); /*lint !e679*/
17158  ++cnt;
17159  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, nnonz+2, &beg, colinds, colvals) );
17160  }
17161  else
17162  {
17163  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, nnonz+1, &beg, colinds, colvals) );
17164  }
17165  }
17166 
17167  /* treat rhs */
17168  if( !SCIPsetIsInfinity(set, absrhs) )
17169  {
17170  assert(!SCIPsetIsEQ(set, lhs, rhs));
17171 
17172  /* add artificial variable */
17173  colinds[nnonz] = lp->ncols;
17174  colvals[nnonz] = -rhs;
17175 
17176  if( relaxrows )
17177  {
17178  /* add slack variable */
17179  colinds[nnonz+1] = lp->ncols + 1 + cnt; /*lint !e679*/
17180  colvals[nnonz+1] = MAX(1.0, absrhs); /*lint !e679*/
17181  ++cnt;
17182  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz+2, &beg, colinds, colvals) );
17183  }
17184  else
17185  {
17186  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz+1, &beg, colinds, colvals) );
17187  }
17188  }
17189  }
17190  }
17191 
17192  /* create row arising from objective cutoff */
17193  if( inclobjcutoff )
17194  {
17195  SCIP_Real rhs;
17196  int nnonz;
17197 
17198  /* get row data */
17199  assert(lp->looseobjvalinf == 0);
17200  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17201 
17202  /* set up indices and coefficients */
17203  nnonz = 0;
17204  for( j = 0; j < lp->ncols; ++j )
17205  {
17206  assert( lp->cols[j] != NULL );
17207  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17208  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17209  if( lp->cols[j]->obj == 0.0 )
17210  continue;
17211  colinds[nnonz] = lp->cols[j]->lppos;
17212  colvals[nnonz] = lp->cols[j]->obj;
17213  ++nnonz;
17214  }
17215 
17216  /* treat rhs */
17217  /* add artificial variable */
17218  colinds[nnonz] = lp->ncols;
17219  colvals[nnonz] = -rhs;
17220  ++nnonz;
17221 
17222  if( relaxrows )
17223  {
17224  SCIP_Real absrhs = REALABS(rhs);
17225 
17226  /* add slack variable */
17227  colinds[nnonz] = lp->ncols + 1 + cnt;
17228  colvals[nnonz] = MAX(1.0, absrhs);
17229  ++cnt;
17230  ++nnonz;
17231  }
17232  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz, &beg, colinds, colvals) );
17233  }
17234 
17235  /* create rows arising from bounds */
17236  for( j = 0; j < lp->ncols; ++j )
17237  {
17238  SCIP_COL* col;
17239  SCIP_Real abscollb;
17240  SCIP_Real abscolub;
17241 
17242  col = lp->cols[j];
17243  assert( col != NULL );
17244  assert( col->lppos == j );
17245 
17246  /* set up index of column */
17247  colinds[0] = j;
17248  colvals[0] = 1.0;
17249 
17250  /* fixed variable */
17251  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17252  {
17253  /* add artificial variable */
17254  colinds[1] = lp->ncols;
17255  colvals[1] = -col->lb;
17256 
17257  /* add row */
17258  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &zero, NULL, 2, &beg, colinds, colvals) );
17259 
17260  continue;
17261  }
17262 
17263  abscollb = REALABS(col->lb);
17264  abscolub = REALABS(col->ub);
17265 
17266  /* lower bound */
17267  if( !SCIPsetIsInfinity(set, abscollb) )
17268  {
17269  /* add artificial variable */
17270  colinds[1] = lp->ncols;
17271  colvals[1] = -col->lb;
17272 
17273  /* add slack variable */
17274  colinds[2] = lp->ncols + 1 + cnt;
17275  colvals[2] = -MAX(1.0, abscollb);
17276  ++cnt;
17277  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, 3, &beg, colinds, colvals) );
17278  }
17279 
17280  /* upper bound */
17281  if( !SCIPsetIsInfinity(set, abscolub) )
17282  {
17283  /* add artificial variable */
17284  colinds[1] = lp->ncols;
17285  colvals[1] = -col->ub;
17286 
17287  /* add slack variable */
17288  colinds[2] = lp->ncols + 1 + cnt;
17289  colvals[2] = MAX(1.0, abscolub);
17290  ++cnt;
17291  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, 3, &beg, colinds, colvals) );
17292  }
17293  }
17294  assert( cnt == nslacks );
17295 
17296  SCIPsetFreeBufferArray(set, &colvals);
17297  SCIPsetFreeBufferArray(set, &colinds);
17298 
17299 #ifdef SCIP_OUTPUT
17300  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
17301 #endif
17302 
17303 #ifndef NDEBUG
17304  {
17305  int ncols;
17306  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
17307  assert( ncols == nnewcols );
17308  }
17309 #endif
17310 
17311  /* set time limit */
17312  if( SCIPsetIsInfinity(set, timelimit) )
17313  timelimit = SCIPlpiInfinity(lpi);
17314  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
17315 
17316  /* check, if parameter is unknown */
17317  if ( retcode == SCIP_PARAMETERUNKNOWN )
17318  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
17319 
17320  /* set iteration limit */
17321  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
17322 
17323  /* check, if parameter is unknown */
17324  if ( retcode == SCIP_PARAMETERUNKNOWN )
17325  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
17326 
17327  /* solve and store point */
17328  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
17329  retcode = SCIPlpiSolveDual(lpi); /* dual is usually faster */
17330 
17331  /* detect possible error in LP solver */
17332  if ( retcode != SCIP_OKAY )
17333  {
17334  SCIP_CALL( SCIPlpiFree(&lpi) );
17335  return SCIP_OKAY;
17336  }
17337 
17338 #ifndef NDEBUG
17339  if ( SCIPlpiIsIterlimExc(lpi) )
17340  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
17341  if ( SCIPlpiIsTimelimExc(lpi) )
17342  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
17343 #endif
17344 
17345  if( SCIPlpiIsOptimal(lpi) )
17346  {
17347  /* get primal solution */
17348  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
17349  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
17350  alpha = primal[lp->ncols];
17351  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
17352 
17353  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
17354 
17355  /* construct relative interior point */
17356  for( j = 0; j < lp->ncols; ++j )
17357  point[j] = primal[j]/alpha;
17358 
17359 #ifdef SCIP_DEBUG
17360  /* check whether the point is a relative interior point */
17361  cnt = 0;
17362  if( relaxrows )
17363  {
17364  for( i = 0; i < lp->nrows; ++i )
17365  {
17366  SCIP_ROW* row;
17367  SCIP_COL** rowcols;
17368  SCIP_Real* rowvals;
17369  SCIP_Real lhs;
17370  SCIP_Real rhs;
17371  SCIP_Real sum;
17372  int nnonz;
17373 
17374  row = lp->rows[i];
17375  assert( row != NULL );
17376 
17377  /* get row data */
17378  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17379  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17380  nnonz = row->nlpcols;
17381  assert( nnonz <= lp->ncols );
17382  rowcols = row->cols;
17383  rowvals = row->vals;
17384 
17385  sum = 0.0;
17386  for( j = 0; j < nnonz; ++j )
17387  sum += rowvals[j] * primal[rowcols[j]->lppos];
17388  sum /= alpha;
17389 
17390  /* if we have an equation */
17391  if( SCIPsetIsEQ(set, lhs, rhs) )
17392  {
17393  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
17394  }
17395  else
17396  {
17397  /* treat lhs */
17398  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
17399  {
17400  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
17401  ++cnt;
17402  }
17403  /* treat rhs */
17404  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
17405  {
17406  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17407  ++cnt;
17408  }
17409  }
17410  }
17411  if( inclobjcutoff )
17412  {
17413  SCIP_Real sum;
17414 #ifndef NDEBUG
17415  SCIP_Real rhs;
17416 
17417  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17418 #endif
17419  sum = 0.0;
17420  for( j = 0; j < lp->ncols; ++j )
17421  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
17422  sum /= alpha;
17423 
17424  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17425  ++cnt;
17426  }
17427  }
17428  /* check bounds */
17429  for( j = 0; j < lp->ncols; ++j )
17430  {
17431  SCIP_COL* col;
17432 #ifndef NDEBUG
17433  SCIP_Real val;
17434 #endif
17435 
17436  col = lp->cols[j];
17437  assert( col != NULL );
17438 #ifndef NDEBUG
17439  val = primal[col->lppos] / alpha;
17440 #endif
17441  /* if the variable is not fixed */
17442  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
17443  {
17444  /* treat lb */
17445  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17446  {
17447  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
17448  ++cnt;
17449  }
17450  /* treat rhs */
17451  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17452  {
17453  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
17454  ++cnt;
17455  }
17456  }
17457  }
17458 #endif
17459 
17460  /* free */
17461  SCIPsetFreeBufferArray(set, &primal);
17462 
17463  *success = TRUE;
17464  }
17465  SCIP_CALL( SCIPlpiFree(&lpi) );
17466 
17467  return SCIP_OKAY;
17468 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:367
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:6637
SCIP_Longint nprimallps
Definition: struct_stat.h:172
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:16440
SCIP_Bool solisbasic
Definition: struct_lp.h:346
SCIP_Real lazyub
Definition: struct_lp.h:132
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1693
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:61
SCIP_Bool lpissolved
Definition: struct_lp.h:114
int nunlinked
Definition: struct_lp.h:226
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4597
int firstnewrow
Definition: struct_lp.h:313
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:15539
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6328
SCIP_Real sbup
Definition: struct_lp.h:143
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:12540
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:4553
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:71
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:186
int nsbcalls
Definition: struct_lp.h:165
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lp.c:335
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5522
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5825
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2488
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2773
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6511
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:422
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2675
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:13069
SCIP_Real maxactivity
Definition: struct_lp.h:207
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8654
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:823
internal methods for managing events
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:9829
SCIP_Real obj
Definition: struct_lp.h:126
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:16841
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2748
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7100
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5580
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2507
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:16637
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6030
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2874
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:6743
void * origin
Definition: struct_lp.h:214
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:220
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:4776
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1726
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13373
SCIP_STATUS status
Definition: struct_stat.h:164
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:16799
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3441
SCIP_Real farkascoef
Definition: struct_lp.h:139
unsigned int ubchanged
Definition: struct_lp.h:173
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3261
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1815
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:103
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9378
int nummaxval
Definition: struct_lp.h:233
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:16756
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2740
SCIP_Longint validactivitylp
Definition: struct_lp.h:221
int lpifirstchgrow
Definition: struct_lp.h:299
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2340
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3503
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:16390
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1352
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:16475
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:93
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6495
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:78
int * cols_index
Definition: struct_lp.h:217
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15406
int nremovablecols
Definition: struct_lp.h:308
char * name
Definition: struct_var.h:228
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:14767
SCIP_Bool primalfeasible
Definition: struct_lp.h:344
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:16886
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:856
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3023
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:842
int nchgrows
Definition: struct_lp.h:303
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:216
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8397
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9545
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3146
char * name
Definition: struct_lp.h:215
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:17314
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6094
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:3372
int nlpicols
Definition: struct_lp.h:295
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5920
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:495
enum SCIP_BaseStat SCIP_BASESTAT
Definition: type_lpi.h:86
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:14736
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6242
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:16691
SCIP_Longint nlps
Definition: struct_stat.h:170
SCIP_Longint activeinlpcounter
Definition: struct_lp.h:211
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:2112
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17166
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6448
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:330
#define SCIP_MAXSTRLEN
Definition: def.h:215
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7739
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3349
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16070
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:5992
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3612
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:16648
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:68
internal methods for clocks and timing issues
unsigned int origintype
Definition: struct_lp.h:252
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:12946
int lpdepth
Definition: struct_lp.h:230
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16190
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3108
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16202
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5645
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:105
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16232
SCIP_Real objsumnorm
Definition: struct_lp.h:278
SCIP_Longint ndivinglps
Definition: struct_stat.h:184
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:1851
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17222
SCIP_ROW ** chgrows
Definition: struct_lp.h:283
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5159
SCIP_COL ** chgcols
Definition: struct_lp.h:282
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:5405
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:14358
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14283
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11503
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16370
int rank
Definition: struct_lp.h:236
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:2257
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:984
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16732
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5384
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1219
int rowssize
Definition: struct_lp.h:310
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8619
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2639
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3557
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7632
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:16544
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12619
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13264
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1496
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13552
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:580
unsigned int nonlprowssorted
Definition: struct_lp.h:170
int nclockskipsleft
Definition: struct_stat.h:250
SCIP_COL ** cols
Definition: struct_lp.h:284
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9768
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1255
int nlpirows
Definition: struct_lp.h:298
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3181
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:649
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:97
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:131
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:16246
#define debugColPrint(x, y)
Definition: lp.c:138
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:3138
static const int nscalars
Definition: lp.c:5564
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:8996
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1534
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:13236
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16311
SCIP_ROW ** rows
Definition: struct_lp.h:150
#define FALSE
Definition: def.h:64
int lppos
Definition: struct_lp.h:161
SCIP_Real lazylb
Definition: struct_lp.h:130
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1851
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:15575
#define EPSEQ(x, y, eps)
Definition: def.h:160
#define EPSISINT(x, eps)
Definition: def.h:172
int pseudoobjvalinf
Definition: struct_lp.h:317
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:16789
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:262
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13305
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6063
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:730
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:16101
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3478
int divinglpiitlim
Definition: struct_lp.h:321
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16012
SCIP_Bool solved
Definition: struct_lp.h:343
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:1649
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:9618
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Longint nrootlps
Definition: struct_stat.h:171
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:16359
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:15992
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2539
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5634
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:15553
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7960
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool lpifromscratch
Definition: struct_lp.h:359
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:549
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1099
unsigned int basisstatus
Definition: struct_lp.h:237
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2711
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6543
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9706
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:16724
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15393
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:138
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1834
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:420
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2528
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:5296
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16859
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3466
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:336
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasdualfeas)
Definition: lp.c:9730
unsigned int sbdownvalid
Definition: struct_lp.h:177
unsigned int objchanged
Definition: struct_lp.h:171
#define DIVESTACKGROWFACT
Definition: lp.c:15336
unsigned int delaysort
Definition: struct_lp.h:240
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5096
unsigned int basisstatus
Definition: struct_lp.h:168
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:16133
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Real lpidualfeastol
Definition: struct_lp.h:274
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:63
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:14705
SCIP_Real sbsolval
Definition: struct_lp.h:144
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1588
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5731
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3000
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:8775
SCIP_Real sumnorm
Definition: struct_lp.h:198
int lpifastmip
Definition: struct_lp.h:323
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:78
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6699
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1859
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:15158
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:5801
int index
Definition: struct_lp.h:156
SCIP_Real relpseudoobjval
Definition: struct_lp.h:268
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2849
SCIP_Real dualfarkas
Definition: struct_lp.h:204
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:11903
SCIP_Real minprimsol
Definition: struct_lp.h:140
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:146
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11821
SCIP_Real pseudoobjval
Definition: struct_lp.h:266
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:16584
SCIP_Bool diving
Definition: struct_lp.h:354
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7654
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:12987
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12648
SCIP_Real rootlooseobjval
Definition: struct_lp.h:270
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:3423
int firstnewcol
Definition: struct_lp.h:309
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:14944
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3327
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:9843
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: lp.c:4947
unsigned int coefchanged
Definition: struct_lp.h:174
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:14298
unsigned int integral
Definition: struct_lp.h:245
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:421
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:9809
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1088
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:94
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5656
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:16450
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:2935
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1017
#define SCIP_LONGINT_MAX
Definition: def.h:121
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:147
int lpifirstchgcol
Definition: struct_lp.h:296
int index
Definition: struct_lp.h:222
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1841
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:15378
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2500
#define checkRow(row)
Definition: lp.c:646
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5876
int maxdepth
Definition: struct_stat.h:211
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:8749
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:76
int looseobjvalinf
Definition: struct_lp.h:314
SCIP_Real obj
Definition: struct_var.h:202
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:337
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2577
unsigned int rhschanged
Definition: struct_lp.h:243
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:5348
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1294
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:16331
int nlpcols
Definition: struct_lp.h:225
SCIP_COL ** lpicols
Definition: struct_lp.h:280
static SCIP_RETCODE lpAlgorithm(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:10972
unsigned int lprowssorted
Definition: struct_lp.h:169
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12452
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:242
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4585
internal methods for LP management
int lazycolssize
Definition: struct_lp.h:306
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13465
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:814
SCIP_Real objprod
Definition: struct_lp.h:199
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:16702
int colssize
Definition: struct_lp.h:304
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:331
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:15339
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:365
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:373
SCIP_Bool lpipresolving
Definition: struct_lp.h:360
int nremovablerows
Definition: struct_lp.h:312
SCIP_Real lpiuobjlim
Definition: struct_lp.h:272
SCIP_Bool strongbranching
Definition: struct_lp.h:351
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1286
SCIP_Bool dualfeasible
Definition: struct_lp.h:112
#define checkLinks(lp)
Definition: lp.c:1575
int lpithreads
Definition: struct_lp.h:324
int ndivechgsides
Definition: struct_lp.h:319
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:16574
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11794
int * linkpos
Definition: struct_lp.h:219
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2623
#define FEASTOLTIGHTFAC
Definition: lp.c:11051
#define SCIP_DEFAULT_EPSILON
Definition: def.h:141
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:11054
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5616
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:16522
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:6392
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2296
SCIP_Real * vals
Definition: struct_lp.h:218
unsigned int integral
Definition: struct_lp.h:175
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:8077
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:3517
int nloosevars
Definition: struct_lp.h:315
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:1928
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:16712
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3706
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4676
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17176
int lppos
Definition: struct_lp.h:228
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5979
int divechgsidessize
Definition: struct_lp.h:320
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5562
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:14905
int * linkpos
Definition: struct_lp.h:155
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:347
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5789
SCIP_Real flushedlb
Definition: struct_lp.h:135
SCIP_Real inf
Definition: intervalarith.h:39
int lpiitlim
Definition: struct_lp.h:322
SCIP_Real lb
Definition: struct_lp.h:127
SCIP_Real dualsol
Definition: struct_lp.h:202
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:7568
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1276
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:275
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:3306
int glbpseudoobjvalinf
Definition: struct_lp.h:316
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:16615
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13332
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16299
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:416
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2422
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13597
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:448
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15057
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16035
SCIP_Real sbdown
Definition: struct_lp.h:142
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6527
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:15363
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5486
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:5836
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2414
SCIP_ROW ** divechgrows
Definition: struct_lp.h:290
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:370
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:7912
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:1758
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:15590
SCIP_Bool installing
Definition: struct_lp.h:350
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16222
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:4736
SCIP_Real SCIPsetLpfeastol(SCIP_SET *set)
Definition: set.c:5446
#define SCIPerrorMessage
Definition: pub_message.h:45
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:668
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition: lp.c:3112
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:13675
interval arithmetics for provable bounds
SCIP_Real sqrnorm
Definition: struct_lp.h:197
SCIP_Longint lpcount
Definition: struct_stat.h:168
SCIP_Bool lpilpinfo
Definition: struct_lp.h:361
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:16180
SCIP_Real pseudoactivity
Definition: struct_lp.h:205
SCIP_PRICING lpipricing
Definition: struct_lp.h:328
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9123
SCIP_COL ** cols
Definition: struct_lp.h:216
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:953
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1557
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9306
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:16564
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16420
SCIP_Bool adjustlpval
Definition: struct_lp.h:358
SCIP_Real minval
Definition: struct_lp.h:201
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:3941
SCIP_Real flushedub
Definition: struct_lp.h:136
SCIPInterval sqrt(const SCIPInterval &x)
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3331
SCIP_ROW ** lpirows
Definition: struct_lp.h:281
unsigned int sbupvalid
Definition: struct_lp.h:179
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:2190
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:180
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2448
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:14834
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8349
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5550
SCIP_Longint validfarkaslp
Definition: struct_lp.h:293
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:9620
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:209
SCIP_Real lhs
Definition: struct_lp.h:193
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9463
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5467
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16002
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:96
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
int nuses
Definition: struct_lp.h:227
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16552
int lpiscaling
Definition: struct_lp.h:327
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:1986
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3715
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:16410
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:855
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6156
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1028
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1842
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:13987
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:5968
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2653
SCIP_Real cutoffbound
Definition: struct_lp.h:271
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6270
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:9182
internal miscellaneous methods
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:16460
static SCIP_RETCODE lpPrimalSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:9922
SCIP_Bool isrelax
Definition: struct_lp.h:348
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:16679
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
#define REALABS(x)
Definition: def.h:159
int maxidx
Definition: struct_lp.h:232
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:291
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2639
SCIP_Bool looseobjvalid
Definition: struct_lp.h:334
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:432
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:14217
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:306
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2521
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6008
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:17304
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6346
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:16594
int lpirandomseed
Definition: struct_lp.h:326
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:584
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:212
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16819
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:340
SCIP_Bool resolvelperror
Definition: struct_lp.h:357
unsigned int removable
Definition: struct_lp.h:176
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:262
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:16321
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8107
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2395
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5544
#define lpCutoffDisabled(set)
Definition: lp.c:2593
int lpicolssize
Definition: struct_lp.h:294
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:16746
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12468
SCIP_LPI * lpi
Definition: struct_lp.h:279
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5119
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2379
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:16430
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1770
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:887
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:263
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5964
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16257
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6643
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:179
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:289
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2243
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4039
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:147
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:1475
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:8727
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:2671
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8579
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5172
int var_probindex
Definition: struct_lp.h:167
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:11534
SCIP_Longint nduallps
Definition: struct_stat.h:174
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6286
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16091
SCIP_Real sblpobjval
Definition: struct_lp.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:419
internal methods for problem variables
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7704
#define SCIP_UNKNOWN
Definition: def.h:156
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9489
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5667
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16267
int nchgcols
Definition: struct_lp.h:301
int len
Definition: struct_lp.h:158
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:16736
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9444
#define SCIP_Bool
Definition: def.h:61
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12551
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5416
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:180
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:408
int numminval
Definition: struct_lp.h:234
int lpipos
Definition: struct_lp.h:229
int size
Definition: struct_lp.h:223
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3510
unsigned int modifiable
Definition: struct_lp.h:247
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:772
void SCIPprintSysError(const char *message)
Definition: misc.c:9276
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:14456
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:9050
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2715
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16022
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5869
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:95
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3758
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:909
int chgrowssize
Definition: struct_lp.h:302
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:16626
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:17553
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3658
SCIP_Longint validfarkaslp
Definition: struct_lp.h:153
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:285
unsigned int lbchanged
Definition: struct_lp.h:172
SCIP_Bool divingobjchg
Definition: struct_lp.h:355
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9523
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_clp.cpp:3428
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:421
SCIP_Longint sbnode
Definition: struct_lp.h:146
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16809
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3616
#define MAX(x, y)
Definition: tclique_def.h:75
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition: lp.c:1052
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_Bool updateintegrality
Definition: struct_lp.h:341
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17024
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:2211
#define DIVESTACKINITSIZE
Definition: lp.c:8792
#define SCIPsetDebugMsg
Definition: set.h:1870
SCIP_Real unchangedobj
Definition: struct_lp.h:129
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:369
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:4069
int minidx
Definition: struct_lp.h:231
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:16112
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2127
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2200
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2817
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17014
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
int nlprows
Definition: struct_lp.h:159
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition: lp.c:5250
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1653
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:8795
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9506
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:747
unsigned int lpcolssorted
Definition: struct_lp.h:238
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:356
SCIP_Longint validsollp
Definition: struct_lp.h:292
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3156
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9475
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16344
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16880
static void colSortLP(SCIP_COL *col)
Definition: lp.c:920
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13225
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:793
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6600
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:3794
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6659
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:239
SCIP_Real ub
Definition: struct_lp.h:128
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2347
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:14983
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5942
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5753
SCIP_ROW ** rows
Definition: struct_lp.h:286
SCIP_Longint validredcostlp
Definition: struct_lp.h:152
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3661
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1166
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:287
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:9785
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:2896
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:7592
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3236
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3266
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:11883
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1127
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:861
SCIP_Real flushedrhs
Definition: struct_lp.h:196
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:16400
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:12773
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:145
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16048
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3412
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9094
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:4317
#define SCIP_REAL_MAX
Definition: def.h:136
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5198
SCIP_Real maxval
Definition: struct_lp.h:200
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6252
SCIP_Real minactivity
Definition: struct_lp.h:206
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6427
SCIP_Real rhs
Definition: struct_lp.h:194
static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:12905
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:10835
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:192
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7459
#define checkRowObjprod(row)
Definition: lp.c:721
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12507
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:15429
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:7896
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:12675
unsigned int removable
Definition: struct_lp.h:248
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lp.c:532
unsigned int lhschanged
Definition: struct_lp.h:242
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2564
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:148
SCIP_COL ** lazycols
Definition: struct_lp.h:285
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:457
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:952
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:1417
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:265
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16277
int sbitlim
Definition: struct_lp.h:164
static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:14553
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12527
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16155
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6584
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2607
int age
Definition: struct_lp.h:166
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3221
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:208
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:148
SCIP_Real * vals
Definition: struct_lp.h:151
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6406
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:353
SCIP_Real rellooseobjval
Definition: struct_lp.h:261
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16081
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8693
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:9853
static const SCIP_Real scalars[]
Definition: lp.c:5563
int lpipos
Definition: struct_lp.h:162
int chgcolssize
Definition: struct_lp.h:300
int lpitiming
Definition: struct_lp.h:325
internal methods for main solving loop and node processing
SCIP_Longint domchgcount
Definition: struct_stat.h:103
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:213
SCIP_Real * divechgsides
Definition: struct_lp.h:288
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:16533
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8451
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1584
SCIP_Real rootlpobjval
Definition: struct_lp.h:269
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:480
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1718
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:135
unsigned int coefchanged
Definition: struct_lp.h:244
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:139
SCIP_Longint nbarrierlps
Definition: struct_stat.h:177
SCIP_Bool flushed
Definition: struct_lp.h:342
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8251
SCIP_CLOCK * primallptime
Definition: struct_stat.h:143
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13182
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5887
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:101
int lpdepth
Definition: struct_lp.h:163
unsigned int inglobalcutpool
Definition: struct_lp.h:249
int nrows
Definition: struct_lp.h:311
#define checkRowSqrnorm(row)
Definition: lp.c:719
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:14629
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:142
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13418
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:170
public methods for message output
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4617
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:372
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:221
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:608
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6074
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5598
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:16212
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16671
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:16500
int ndivingrows
Definition: struct_lp.h:318
SCIP_Real lpobjval
Definition: struct_lp.h:258
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4158
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:135
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:113
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Real flushedobj
Definition: struct_lp.h:134
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:16779
int size
Definition: struct_lp.h:157
#define MIN(x, y)
Definition: memory.c:75
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7535
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6041
SCIP_Longint validsblp
Definition: struct_lp.h:154
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:3241
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:5436
static SCIP_RETCODE lpSetUobjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real uobjlim)
Definition: lp.c:2597
#define SCIPsetDebugMsgPrint
Definition: set.h:1871
int lpirowssize
Definition: struct_lp.h:297
int nunlinked
Definition: struct_lp.h:160
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4020
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2302
#define BMSallocMemory(ptr)
Definition: memory.h:74
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13654
#define SCIP_INVALID
Definition: def.h:155
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:82
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5518
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:2236
SCIP_Real primsol
Definition: struct_lp.h:137
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:16769
SCIP_CLOCK * duallptime
Definition: struct_stat.h:144
SCIP_Real maxprimsol
Definition: struct_lp.h:141
#define SCIP_Longint
Definition: def.h:120
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17278
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6241
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:9899
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:2958
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2772
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3073
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:16511
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14160
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2899
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:5567
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:716
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:333
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5986
SCIP_VAR * var
Definition: struct_lp.h:149
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9571
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7613
int SCIPsetInitializeRandomSeed(SCIP_SET *set, int initialseedvalue)
Definition: set.c:6702
int nlazycols
Definition: struct_lp.h:307
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:16380
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:308
SCIP_Bool dualfeasible
Definition: struct_lp.h:345
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6479
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3994
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6044
unsigned int nlocks
Definition: struct_lp.h:251
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2799
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2365
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17232
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:406
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6263
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3294
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3835
SCIP_Longint obsoletenode
Definition: struct_lp.h:147
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:901
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9596
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13530
SCIP_Longint obsoletenode
Definition: struct_lp.h:210
common defines and data types used in all packages of SCIP
SCIP_Longint nnodes
Definition: struct_stat.h:71
SCIP_Real lpifeastol
Definition: struct_lp.h:273
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:12715
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:878
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4123
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13394
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:1447
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3082
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:16604
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16058
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:5229
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
unsigned int validminmaxidx
Definition: struct_lp.h:241
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3811
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:13693
#define SCIP_ALLOC(x)
Definition: def.h:317
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12496
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6215
#define SCIPABORT()
Definition: def.h:278
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2824
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:193
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:329
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:2187
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:16169
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2461
unsigned int nonlpcolssorted
Definition: struct_lp.h:239
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16122
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16743
SCIP_Bool flushaddedcols
Definition: struct_lp.h:338
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:10237
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:16554
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:335
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7945
int ncols
Definition: struct_lp.h:305
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2553
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4054
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:16287
static SCIP_RETCODE lpDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:10063
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16830
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:412
SCIP_Real objsqrnorm
Definition: struct_lp.h:277
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1315
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3521
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16144
unsigned int local
Definition: struct_lp.h:246
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3021
SCIP_Real activity
Definition: struct_lp.h:203
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5087
SCIP_Bool probing
Definition: struct_lp.h:352
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:339
SCIP_Real looseobjval
Definition: struct_lp.h:259
int len
Definition: struct_lp.h:224
int age
Definition: struct_lp.h:235
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7523
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1801
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6052
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:11705
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9253
SCIP_Real flushedlhs
Definition: struct_lp.h:195
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:5460
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:886
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5213
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:3396
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:3889
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:276
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3048
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:16490
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:720