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->primalchecked = lp->primalchecked;
359  storedsolvals->dualfeasible = lp->dualfeasible;
360  storedsolvals->dualchecked = lp->dualchecked;
361  storedsolvals->solisbasic = lp->solisbasic;
362  storedsolvals->lpissolved = lp->solved;
363 
364  return SCIP_OKAY;
365 }
366 
367 /** restore LP solution values in column */
368 static
370  SCIP_LP* lp, /**< LP data */
371  BMS_BLKMEM* blkmem, /**< block memory */
372  SCIP_Longint validlp /**< number of lp for which restored values are valid */
373  )
374 {
375  SCIP_LPSOLVALS* storedsolvals;
376 
377  assert(lp != NULL);
378  assert(blkmem != NULL);
379 
380  /* if stored values are available, restore them */
381  storedsolvals = lp->storedsolvals;
382  if( storedsolvals != NULL )
383  {
384  lp->solved = storedsolvals->lpissolved;
385  lp->validsollp = validlp;
386 
387  lp->lpsolstat = storedsolvals->lpsolstat;
388  lp->lpobjval = storedsolvals->lpobjval;
389  lp->primalfeasible = storedsolvals->primalfeasible;
390  lp->primalchecked = storedsolvals->primalchecked;
391  lp->dualfeasible = storedsolvals->dualfeasible;
392  lp->dualchecked = storedsolvals->dualchecked;
393  lp->solisbasic = storedsolvals->solisbasic;
394 
395  /* solution values are stored only for LPs solved to optimality or unboundedness */
396  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
402  lp->validsollp == -1);
403  }
404  /* no values available, mark LP as unsolved */
405  else
406  {
407  lp->solved = FALSE;
408  lp->validsollp = -1;
409 
411  lp->lpobjval = SCIP_INVALID;
412  lp->primalfeasible = FALSE;
413  lp->primalchecked = FALSE;
414  lp->dualfeasible = FALSE;
415  lp->dualchecked = FALSE;
416  lp->solisbasic = FALSE;
417  lp->validfarkaslp = -1;
418  }
419 
420  /* intentionally keep storage space allocated */
421 
422  return SCIP_OKAY;
423 }
424 
425 /** save current LP solution values stored in each column */
426 static
428  SCIP_COL* col, /**< LP column */
429  BMS_BLKMEM* blkmem /**< block memory */
430  )
431 {
432  SCIP_COLSOLVALS* storedsolvals;
433 
434  assert(col != NULL);
435  assert(blkmem != NULL);
436 
437  /* allocate memory for storage */
438  if( col->storedsolvals == NULL )
439  {
440  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
441  }
442  storedsolvals = col->storedsolvals;
443 
444  /* store values */
445  storedsolvals->primsol = col->primsol;
446  storedsolvals->redcost = col->redcost;
447  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
448 
449  return SCIP_OKAY;
450 }
451 
452 /** restore LP solution values in column */
453 static
455  SCIP_COL* col, /**< LP column */
456  BMS_BLKMEM* blkmem, /**< block memory */
457  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
458  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
459  )
460 {
461  SCIP_COLSOLVALS* storedsolvals;
462 
463  assert(col != NULL);
464  assert(blkmem != NULL);
465 
466  /* if stored values are available, restore them */
467  storedsolvals = col->storedsolvals;
468  if( storedsolvals != NULL )
469  {
470  col->primsol = storedsolvals->primsol;
471  col->redcost = storedsolvals->redcost;
472  col->validredcostlp = validlp;
473  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
474 
475  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
476  col->validfarkaslp = -1;
477  }
478  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
479  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
480  */
481  else
482  {
483  col->primsol = 0.0;
484  col->validredcostlp = -1;
485  col->validfarkaslp = -1;
486  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
487  }
488 
489  /* free memory */
490  if( freebuffer )
491  {
492  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
493  assert(col->storedsolvals == NULL);
494  }
495 
496  return SCIP_OKAY;
497 }
498 
499 /** save current LP solution values stored in each column */
500 static
502  SCIP_ROW* row, /**< LP row */
503  BMS_BLKMEM* blkmem, /**< block memory */
504  SCIP_Bool infeasible /**< is the solution infeasible? */
505  )
506 {
507  SCIP_ROWSOLVALS* storedsolvals;
508 
509  assert(row != NULL);
510  assert(blkmem != NULL);
511 
512  /* allocate memory for storage */
513  if( row->storedsolvals == NULL )
514  {
515  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
516  }
517  storedsolvals = row->storedsolvals;
518 
519  /* store values */
520  if ( infeasible )
521  {
522  storedsolvals->dualsol = row->dualfarkas;
523  storedsolvals->activity = SCIP_INVALID;
524  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
525  }
526  else
527  {
528  storedsolvals->dualsol = row->dualsol;
529  storedsolvals->activity = row->activity;
530  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
531  }
532 
533  return SCIP_OKAY;
534 }
535 
536 /** restore LP solution values in row */
537 static
539  SCIP_ROW* row, /**< LP column */
540  BMS_BLKMEM* blkmem, /**< block memory */
541  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
542  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
543  SCIP_Bool infeasible /**< is the solution infeasible? */
544  )
545 {
546  SCIP_ROWSOLVALS* storedsolvals;
547 
548  assert(row != NULL);
549  assert(blkmem != NULL);
550 
551  /* if stored values are available, restore them */
552  storedsolvals = row->storedsolvals;
553  if( storedsolvals != NULL )
554  {
555  if ( infeasible )
556  row->dualfarkas = storedsolvals->dualsol;
557  else
558  row->dualsol = storedsolvals->dualsol;
559  row->activity = storedsolvals->activity;
560  row->validactivitylp = validlp;
561  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
562  }
563  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
564  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
565  */
566  else
567  {
568  row->dualsol = 0.0;
569  row->dualfarkas = 0.0;
570  row->activity = SCIP_INVALID;
571  row->validactivitylp = -1;
572  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
573  }
574 
575  /* free memory */
576  if( freebuffer )
577  {
578  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
579  assert(row->storedsolvals == NULL);
580  }
581 
582  return SCIP_OKAY;
583 }
584 
585 /** ensures, that column array of row can store at least num entries */
587  SCIP_ROW* row, /**< LP row */
588  BMS_BLKMEM* blkmem, /**< block memory */
589  SCIP_SET* set, /**< global SCIP settings */
590  int num /**< minimum number of entries to store */
591  )
592 {
593  assert(row != NULL);
594  assert(row->len <= row->size);
595 
596  if( num > row->size )
597  {
598  int newsize;
599 
600  newsize = SCIPsetCalcMemGrowSize(set, num);
601  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
602  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
603  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
604  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
605  row->size = newsize;
606  }
607  assert(num <= row->size);
608 
609  return SCIP_OKAY;
610 }
611 
612 
613 #if 0 /* enable this to check the sortings within rows (for debugging, very slow!) */
614 static SCIP_Bool msgdisp_checkrow = FALSE;
615 
616 static
617 void checkRow(
618  SCIP_ROW* row
619  )
620 {
621  int i;
622 
623  if( !msgdisp_checkrow )
624  {
625  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
626  msgdisp_checkrow = TRUE;
627  }
628 
629  /* validate sorting of LP part of row */
630  if( row->lpcolssorted && row->nlpcols > 0)
631  {
632  assert(row->cols_index[0] == row->cols[0]->index);
633  for( i = 1; i < row->nlpcols; ++i )
634  {
635  assert(row->cols_index[i] == row->cols[i]->index);
636  assert(row->cols_index[i] >= row->cols_index[i-1]);
637  }
638  }
639 
640  /* validate sorting of non-LP part of row */
641  if( row->nonlpcolssorted && row->len > row->nlpcols )
642  {
643  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
644  for( i = row->nlpcols + 1; i < row->len; ++i )
645  {
646  assert(row->cols_index[i] == row->cols[i]->index);
647  assert(row->cols_index[i] >= row->cols_index[i-1]);
648  }
649  }
650 }
651 #else
652 #define checkRow(row) /**/
653 #endif
654 
655 #if 0 /* enable this to check norms of rows (for debugging, very slow!) */
656 static
657 void checkRowSqrnorm(
658  SCIP_ROW* row
659  )
660 {
661  SCIP_COL** cols;
662  SCIP_Real sqrnorm;
663  int c;
664 
665  cols = row->cols;
666  assert(cols != NULL || row->len == 0);
667 
668  sqrnorm = 0.0;
669 
670  for( c = row->len - 1; c >= 0; --c )
671  {
672  if( cols[c]->lppos >= 0 )
673  sqrnorm += SQR(row->vals[c]);
674  }
675 
676  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
677 }
678 
679 static
680 void checkRowSumnorm(
681  SCIP_ROW* row
682  )
683 {
684  SCIP_COL** cols;
685  SCIP_Real sumnorm;
686  int c;
687 
688  cols = row->cols;
689  assert(cols != NULL || row->len == 0);
690 
691  sumnorm = 0.0;
692 
693  for( c = row->len - 1; c >= 0; --c )
694  {
695  if( cols[c]->lppos >= 0 )
696  sumnorm += REALABS(row->vals[c]);
697  }
698 
699  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
700 }
701 
702 static
703 void checkRowObjprod(
704  SCIP_ROW* row
705  )
706 {
707  SCIP_COL** cols;
708  SCIP_Real objprod;
709  int c;
710 
711  cols = row->cols;
712  assert(cols != NULL || row->len == 0);
713 
714  objprod = 0.0;
715 
716  for( c = row->len - 1; c >= 0; --c )
717  {
718  if( cols[c]->lppos >= 0 )
719  objprod += row->vals[c] * cols[c]->unchangedobj;
720  }
721 
722  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
723 }
724 #else
725 #define checkRowSqrnorm(row) /**/
726 #define checkRowSumnorm(row) /**/
727 #define checkRowObjprod(row) /**/
728 #endif
729 
730 /*
731  * Local methods for pseudo and loose objective values
732  */
733 
734 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
735 static
737  SCIP_LP* lp, /**< current LP data */
738  SCIP_SET* set, /**< global SCIP settings */
739  SCIP_PROB* prob /**< problem data */
740  )
741 {
742  SCIP_VAR** vars;
743  SCIP_Real obj;
744  int nvars;
745  int v;
746 
747  assert(lp != NULL);
748  assert(set != NULL);
749  assert(prob != NULL);
750  assert(!lp->looseobjvalid);
751 
752  vars = prob->vars;
753  nvars = prob->nvars;
754  lp->looseobjval = 0.0;
755 
756  /* iterate over all variables in the problem */
757  for( v = 0; v < nvars; ++v )
758  {
759  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
760  {
761  obj = SCIPvarGetObj(vars[v]);
762 
763  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
764  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
765  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
766  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
767  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
768  }
769  }
770 
771  /* the recomputed value is reliable */
772  lp->rellooseobjval = lp->looseobjval;
773  lp->looseobjvalid = TRUE;
774 }
775 
776 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
777 static
779  SCIP_LP* lp, /**< current LP data */
780  SCIP_SET* set, /**< global SCIP settings */
781  SCIP_PROB* prob /**< problem data */
782  )
783 {
784  SCIP_VAR** vars;
785  int nvars;
786  int v;
787 
788  assert(lp != NULL);
789  assert(set != NULL);
790  assert(prob != NULL);
791  assert(!lp->pseudoobjvalid);
792 
793  vars = prob->vars;
794  nvars = prob->nvars;
795  lp->pseudoobjval = 0.0;
796 
797  /* iterate over all variables in the problem */
798  for( v = 0; v < nvars; ++v )
799  {
800  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
801  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
802  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
803  {
804  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
805  }
806  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
807  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
808  {
809  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
810  }
811  }
812 
813  /* the recomputed value is reliable */
814  lp->relpseudoobjval = lp->pseudoobjval;
815  lp->pseudoobjvalid = TRUE;
816 }
817 
818 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
819 static
821  SCIP_LP* lp, /**< current LP data */
822  SCIP_SET* set, /**< global SCIP settings */
823  SCIP_PROB* prob /**< problem data */
824  )
825 {
826  SCIP_VAR** vars;
827  int nvars;
828  int v;
829 
830  assert(lp != NULL);
831  assert(set != NULL);
832  assert(prob != NULL);
833  assert(!lp->glbpseudoobjvalid);
834 
835  vars = prob->vars;
836  nvars = prob->nvars;
837  lp->glbpseudoobjval = 0.0;
838 
839  /* iterate over all variables in the problem */
840  for( v = 0; v < nvars; ++v )
841  {
842  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
843  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
844  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
845  {
846  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
847  }
848  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
849  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
850  {
851  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
852  }
853  }
854 
855  /* the recomputed value is reliable */
857  lp->glbpseudoobjvalid = TRUE;
858 }
859 
860 /** gets finite part of objective value of current LP that results from LOOSE variables only */
861 static
863  SCIP_LP* lp, /**< current LP data */
864  SCIP_SET* set, /**< global SCIP settings */
865  SCIP_PROB* prob /**< problem data */
866  )
867 {
868  assert(lp != NULL);
869  assert(set != NULL);
870  assert(prob != NULL);
871  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
872  assert(lp->flushed);
873  assert(lp->looseobjvalinf == 0);
874 
875  /* recalculate the loose objective value, if needed */
876  if( !lp->looseobjvalid )
877  recomputeLooseObjectiveValue(lp, set, prob);
878 
879  return lp->looseobjval;
880 }
881 
882 /** gets finite part of pseudo objective value of current LP */
883 static
885  SCIP_LP* lp, /**< current LP data */
886  SCIP_SET* set, /**< global SCIP settings */
887  SCIP_PROB* prob /**< problem data */
888  )
889 {
890  assert(lp != NULL);
891  assert(set != NULL);
892  assert(prob != NULL);
893 
894  /* recalculate the pseudo objective value, if needed */
895  if( !lp->pseudoobjvalid )
896  recomputePseudoObjectiveValue(lp, set, prob);
897 
898  return lp->pseudoobjval;
899 }
900 
901 /*
902  * Sorting and searching rows and columns
903  */
904 
905 
906 /** comparison method for sorting rows by non-decreasing index */
908 {
909  assert(elem1 != NULL);
910  assert(elem2 != NULL);
911 
912  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
913  return -1;
914  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
915  return +1;
916  else
917  {
918  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
919  return 0;
920  }
921 }
922 
923 
924 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
925 static
927  SCIP_COL* col /**< column to be sorted */
928  )
929 {
930  int i;
931 
932  assert(col != NULL);
933 
934  /* check, if column is already sorted in the LP part */
935  if( col->lprowssorted )
936  return;
937 
938  /* sort coefficients */
939  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
940 
941  /* update links */
942  for( i = 0; i < col->nlprows; ++i )
943  {
944  if( col->linkpos[i] >= 0 )
945  {
946  assert(col->rows[i]->cols[col->linkpos[i]] == col);
947  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
948  col->rows[i]->linkpos[col->linkpos[i]] = i;
949  }
950  }
951 
952  col->lprowssorted = TRUE;
953 }
954 
955 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
956  * ones
957  */
958 static
960  SCIP_COL* col /**< column to be sorted */
961  )
962 {
963  int i;
964 
965  assert(col != NULL);
966 
967  /* check, if column is already sorted in the non-LP part */
968  if( col->nonlprowssorted )
969  return;
970 
971  /* sort coefficients */
972  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
973 
974  /* update links */
975  for( i = col->nlprows; i < col->len; ++i )
976  {
977  if( col->linkpos[i] >= 0 )
978  {
979  assert(col->rows[i]->cols[col->linkpos[i]] == col);
980  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
981  col->rows[i]->linkpos[col->linkpos[i]] = i;
982  }
983  }
984 
985  col->nonlprowssorted = TRUE;
986 }
987 
988 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
989 static
991  SCIP_ROW* row /**< row to be sorted */
992  )
993 {
994  int i;
995 
996  assert(row != NULL);
997 
998  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
999  if( row->lpcolssorted || row->delaysort )
1000  return;
1001 
1002  /* sort coefficients */
1003  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1004 
1005  /* update links */
1006  for( i = 0; i < row->nlpcols; ++i )
1007  {
1008  if( row->linkpos[i] >= 0 )
1009  {
1010  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1011  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1012  row->cols[i]->linkpos[row->linkpos[i]] = i;
1013  }
1014  }
1015 
1016  row->lpcolssorted = TRUE;
1017 }
1018 
1019 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1020  * higher ones
1021  */
1022 static
1024  SCIP_ROW* row /**< row to be sorted */
1025  )
1026 {
1027  int i;
1028 
1029  assert(row != NULL);
1030 
1031  checkRow(row);
1032 
1033  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1034  if( row->nonlpcolssorted || row->delaysort )
1035  return;
1036 
1037  /* sort coefficients */
1038  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1039 
1040  /* update links */
1041  for( i = row->nlpcols; i < row->len; ++i )
1042  {
1043  if( row->linkpos[i] >= 0 )
1044  {
1045  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1046  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1047  row->cols[i]->linkpos[row->linkpos[i]] = i;
1048  }
1049  }
1050 
1051  checkRow(row);
1052 
1053  row->nonlpcolssorted = TRUE;
1054 }
1055 
1056 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1057 static
1059  SCIP_COL* col, /**< column to be searched in */
1060  const SCIP_ROW* row, /**< coefficient to be searched for */
1061  int minpos, /**< first position of search range */
1062  int maxpos /**< last position of search range */
1063  )
1064 {
1065  int pos;
1066  int idx;
1067  int searchidx;
1068 
1069  assert(col != NULL);
1070  assert(row != NULL);
1071 
1072  /* binary search */
1073  searchidx = row->index;
1074  while(minpos <= maxpos)
1075  {
1076  pos = (minpos + maxpos)/2;
1077  assert(0 <= pos && pos < col->len);
1078  assert(col->rows[pos] != NULL);
1079  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1080  idx = col->rows[pos]->index;
1081  if( searchidx == idx )
1082  return pos;
1083  else if( searchidx < idx )
1084  maxpos = pos-1;
1085  else
1086  minpos = pos+1;
1087  }
1088 
1089  return -1;
1090 }
1091 
1092 /** searches coefficient in column, returns position in col vector or -1 if not found */
1093 static
1095  SCIP_COL* col, /**< column to be searched in */
1096  const SCIP_ROW* row /**< coefficient to be searched for */
1097  )
1098 {
1099  int pos;
1100 
1101  assert(col != NULL);
1102  assert(row != NULL);
1103 
1104  pos = -1;
1105 
1106  /* search in the linked LP rows */
1107  if( row->lppos >= 0 )
1108  {
1109  /* column has to be sorted, such that binary search works */
1110  colSortLP(col);
1111  assert(col->lprowssorted);
1112 
1113  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1114  if( pos >= 0 )
1115  return pos;
1116  }
1117 
1118  /* search in the non-LP/unlinked rows */
1119  if( row->lppos == -1 || col->nunlinked > 0 )
1120  {
1121  /* column has to be sorted, such that binary search works */
1122  colSortNonLP(col);
1123  assert(col->nonlprowssorted);
1124 
1125  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1126  }
1127 
1128  return pos;
1129 }
1130 
1131 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1132 static
1134  SCIP_ROW* row, /**< row to be searched in */
1135  const SCIP_COL* col, /**< coefficient to be searched for */
1136  int minpos, /**< first position of search range */
1137  int maxpos /**< last position of search range */
1138  )
1139 {
1140  int pos;
1141  int idx;
1142  int searchidx;
1143 
1144  assert(row != NULL);
1145  assert(col != NULL);
1146 
1147  /* binary search */
1148  searchidx = col->index;
1149  while(minpos <= maxpos)
1150  {
1151  pos = (minpos + maxpos)/2;
1152  assert(0 <= pos && pos < row->len);
1153  assert(row->cols[pos] != NULL);
1154  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1155  assert(row->cols_index[pos] == row->cols[pos]->index);
1156  idx = row->cols_index[pos];
1157  if( searchidx == idx )
1158  return pos;
1159  else if( searchidx < idx )
1160  maxpos = pos-1;
1161  else
1162  minpos = pos+1;
1163  }
1164 
1165  return -1;
1166 }
1167 
1168 /** searches coefficient in row, returns position in row vector or -1 if not found;
1169  * if the sorting of the row is delayed, returns -1
1170  */
1171 static
1173  SCIP_ROW* row, /**< row to be searched in */
1174  const SCIP_COL* col /**< coefficient to be searched for */
1175  )
1176 {
1177  int pos;
1178 
1179  assert(row != NULL);
1180  assert(col != NULL);
1181 
1182  if( row->delaysort )
1183  return -1;
1184 
1185  pos = -1;
1186 
1187  /* search in the linked LP columns */
1188  if( col->lppos >= 0 )
1189  {
1190  /* row has to be sorted, such that binary search works */
1191  rowSortLP(row);
1192  assert(row->lpcolssorted);
1193 
1194  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1195  }
1196 
1197  /* search in the non-LP/unlinked columns */
1198  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1199  {
1200  /* row has to be sorted, such that binary search works */
1201  rowSortNonLP(row);
1202  assert(row->nonlpcolssorted);
1203 
1204  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1205  }
1206 
1207 #ifndef NDEBUG
1208  /* validate result */
1209  assert(-1 <= pos && pos < row->len);
1210  if( pos >= 0 )
1211  assert(row->cols[pos] == col);
1212  else
1213  {
1214  int i;
1215  for( i = 0; i < row->len; ++i )
1216  assert(row->cols[i] != col);
1217  }
1218 #endif
1219 
1220  return pos;
1221 }
1222 
1223 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1224 static
1226  SCIP_COL* col, /**< LP column */
1227  int oldpos, /**< old position of coefficient */
1228  int newpos /**< new position of coefficient */
1229  )
1230 {
1231  assert(col != NULL);
1232  assert(0 <= oldpos && oldpos < col->len);
1233  assert(0 <= newpos && newpos < col->len);
1234  assert(col->rows[oldpos] != NULL);
1235 
1236  if( oldpos == newpos )
1237  return;
1238 
1239  col->rows[newpos] = col->rows[oldpos];
1240  col->vals[newpos] = col->vals[oldpos];
1241  col->linkpos[newpos] = col->linkpos[oldpos];
1242 
1243  /* update link position in row */
1244  if( col->linkpos[newpos] >= 0 )
1245  {
1246  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1247  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1248 
1249  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1250  }
1251 
1252  /* update sorted flags */
1253  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1254  col->lprowssorted = FALSE;
1255  else
1256  col->nonlprowssorted = FALSE;
1257 }
1258 
1259 /** swaps two coefficients in a column, and updates all corresponding data structures */
1260 static
1262  SCIP_COL* col, /**< LP column */
1263  int pos1, /**< position of first coefficient */
1264  int pos2 /**< position of second coefficient */
1265  )
1266 {
1267  SCIP_ROW* tmprow;
1268  SCIP_Real tmpval;
1269  int tmplinkpos;
1270 
1271  assert(col != NULL);
1272  assert(0 <= pos1 && pos1 < col->len);
1273  assert(0 <= pos2 && pos2 < col->len);
1274  assert(col->rows[pos1] != NULL);
1275 
1276  if( pos1 == pos2 )
1277  return;
1278 
1279  /* swap coefficients */
1280  tmprow = col->rows[pos2];
1281  tmpval = col->vals[pos2];
1282  tmplinkpos = col->linkpos[pos2];
1283 
1284  col->rows[pos2] = col->rows[pos1];
1285  col->vals[pos2] = col->vals[pos1];
1286  col->linkpos[pos2] = col->linkpos[pos1];
1287 
1288  col->rows[pos1] = tmprow;
1289  col->vals[pos1] = tmpval;
1290  col->linkpos[pos1] = tmplinkpos;
1291 
1292  /* update link position in rows */
1293  if( col->linkpos[pos1] >= 0 )
1294  {
1295  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1296  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1297 
1298  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1299  }
1300  if( col->linkpos[pos2] >= 0 )
1301  {
1302  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1303  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1304 
1305  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1306  }
1307 
1308  /* update sorted flags */
1309  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1310  col->lprowssorted = FALSE;
1311  else
1312  col->nonlprowssorted = FALSE;
1313  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1314  col->lprowssorted = FALSE;
1315  else
1316  col->nonlprowssorted = FALSE;
1317 }
1318 
1319 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1320 static
1322  SCIP_ROW* row, /**< LP row */
1323  int oldpos, /**< old position of coefficient */
1324  int newpos /**< new position of coefficient */
1325  )
1326 {
1327  assert(row != NULL);
1328  assert(0 <= oldpos && oldpos < row->len);
1329  assert(0 <= newpos && newpos < row->len);
1330  assert(row->cols[oldpos] != NULL);
1331 
1332  if( oldpos == newpos )
1333  return;
1334 
1335  row->cols[newpos] = row->cols[oldpos];
1336  row->cols_index[newpos] = row->cols_index[oldpos];
1337  row->vals[newpos] = row->vals[oldpos];
1338  row->linkpos[newpos] = row->linkpos[oldpos];
1339 
1340  /* update link position in column */
1341  if( row->linkpos[newpos] >= 0 )
1342  {
1343  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1344  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1345 
1346  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1347  }
1348 
1349  /* update sorted flags */
1350  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1351  row->lpcolssorted = FALSE;
1352  else
1353  row->nonlpcolssorted = FALSE;
1354 }
1355 
1356 /** swaps two coefficients in a row, and updates all corresponding data structures */
1357 static
1359  SCIP_ROW* row, /**< LP row */
1360  int pos1, /**< position of first coefficient */
1361  int pos2 /**< position of second coefficient */
1362  )
1363 {
1364  SCIP_COL* tmpcol;
1365  SCIP_Real tmpval;
1366  int tmpindex;
1367  int tmplinkpos;
1368 
1369  assert(row != NULL);
1370  assert(0 <= pos1 && pos1 < row->len);
1371  assert(0 <= pos2 && pos2 < row->len);
1372  assert(row->cols[pos1] != NULL);
1373  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1374 
1375  if( pos1 == pos2 )
1376  return;
1377 
1378  /* swap coefficients */
1379  tmpcol = row->cols[pos2];
1380  tmpindex = row->cols_index[pos2];
1381  tmpval = row->vals[pos2];
1382  tmplinkpos = row->linkpos[pos2];
1383 
1384  row->cols[pos2] = row->cols[pos1];
1385  row->cols_index[pos2] = row->cols_index[pos1];
1386  row->vals[pos2] = row->vals[pos1];
1387  row->linkpos[pos2] = row->linkpos[pos1];
1388 
1389  row->cols[pos1] = tmpcol;
1390  row->cols_index[pos1] = tmpindex;
1391  row->vals[pos1] = tmpval;
1392  row->linkpos[pos1] = tmplinkpos;
1393 
1394  /* update link position in columns */
1395  if( row->linkpos[pos1] >= 0 )
1396  {
1397  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1398  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1399 
1400  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1401  }
1402  if( row->linkpos[pos2] >= 0 )
1403  {
1404  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1405  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1406 
1407  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1408  }
1409 
1410  /* update sorted flags */
1411  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1412  row->lpcolssorted = FALSE;
1413  else
1414  row->nonlpcolssorted = FALSE;
1415  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1416  row->lpcolssorted = FALSE;
1417  else
1418  row->nonlpcolssorted = FALSE;
1419 }
1420 
1421 /** issues a ROWCOEFCHANGED event on the given row */
1422 static
1424  SCIP_ROW* row, /**< row which coefficient has changed */
1425  BMS_BLKMEM* blkmem, /**< block memory */
1426  SCIP_SET* set, /**< global SCIP settings */
1427  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1428  SCIP_COL* col, /**< the column which coefficient has changed */
1429  SCIP_Real oldval, /**< old value of the coefficient */
1430  SCIP_Real newval /**< new value of the coefficient */
1431  )
1432 {
1433  assert(row != NULL);
1434  assert(row->eventfilter != NULL);
1435  assert(col != NULL);
1436 
1437  /* check, if the row is being tracked for coefficient changes
1438  * if so, issue ROWCOEFCHANGED event
1439  */
1440  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1441  {
1442  SCIP_EVENT* event;
1443 
1444  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1445  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1446  }
1447 
1448  return SCIP_OKAY;
1449 }
1450 
1451 /** issues a ROWCONSTCHANGED event on the given row */
1452 static
1454  SCIP_ROW* row, /**< row which coefficient has changed */
1455  BMS_BLKMEM* blkmem, /**< block memory */
1456  SCIP_SET* set, /**< global SCIP settings */
1457  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1458  SCIP_Real oldval, /**< old value of the constant */
1459  SCIP_Real newval /**< new value of the constant */
1460  )
1461 {
1462  assert(row != NULL);
1463  assert(row->eventfilter != NULL);
1464 
1465  /* check, if the row is being tracked for coefficient changes
1466  * if so, issue ROWCONSTCHANGED event
1467  */
1468  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED) != 0) )
1469  {
1470  SCIP_EVENT* event;
1471 
1472  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1473  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1474  }
1475 
1476  return SCIP_OKAY;
1477 }
1478 
1479 /** issues a ROWSIDECHANGED event on the given row */
1480 static
1482  SCIP_ROW* row, /**< row which coefficient has changed */
1483  BMS_BLKMEM* blkmem, /**< block memory */
1484  SCIP_SET* set, /**< global SCIP settings */
1485  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1486  SCIP_SIDETYPE side, /**< the side that has changed */
1487  SCIP_Real oldval, /**< old value of side */
1488  SCIP_Real newval /**< new value of side */
1489  )
1490 {
1491  assert(row != NULL);
1492  assert(row->eventfilter != NULL);
1493 
1494  /* check, if the row is being tracked for coefficient changes
1495  * if so, issue ROWSIDECHANGED event
1496  */
1497  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED) != 0) )
1498  {
1499  SCIP_EVENT* event;
1500 
1501  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1502  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1503  }
1504 
1505  return SCIP_OKAY;
1506 }
1507 
1508 #if 0 /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1509 
1510 #ifdef NDEBUG
1511 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1512 #else
1513 #define ASSERT(x) assert(x)
1514 #endif
1515 
1516 static SCIP_Bool msgdisp_checklinks = FALSE;
1517 
1518 
1519 static
1520 void checkLinks(
1521  SCIP_LP* lp /**< current LP data */
1522  )
1523 {
1524  SCIP_COL* col;
1525  SCIP_ROW* row;
1526  int i;
1527  int j;
1528 
1529  ASSERT(lp != NULL);
1530 
1531  if( !msgdisp_checklinks )
1532  {
1533  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1534  msgdisp_checklinks = TRUE;
1535  }
1536 
1537  for( i = 0; i < lp->ncols; ++i )
1538  {
1539  col = lp->cols[i];
1540  ASSERT(col != NULL);
1541  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1542  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1543  ASSERT(col->nlprows <= col->len);
1544  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1545 
1546  for( j = 0; j < col->len; ++j )
1547  {
1548  row = col->rows[j];
1549  ASSERT(row != NULL);
1550  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1551  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1552  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1553  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1554  }
1555  }
1556 
1557  for( i = 0; i < lp->nrows; ++i )
1558  {
1559  row = lp->rows[i];
1560  ASSERT(row != NULL);
1561  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1562  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1563  ASSERT(row->nlpcols <= row->len);
1564  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1565 
1566  for( j = 0; j < row->len; ++j )
1567  {
1568  col = row->cols[j];
1569  ASSERT(col != NULL);
1570  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1571  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1572  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1573  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1574  }
1575  }
1576 }
1577 
1578 #undef ASSERT
1579 
1580 #else
1581 #define checkLinks(lp) /**/
1582 #endif
1583 
1584 /*
1585  * Changing announcements
1586  */
1587 
1588 /** announces, that the given coefficient in the constraint matrix changed */
1589 static
1591  SCIP_ROW* row, /**< LP row */
1592  SCIP_COL* col, /**< LP col */
1593  SCIP_LP* lp /**< current LP data */
1594  )
1595 {
1596  assert(row != NULL);
1597  assert(col != NULL);
1598  assert(lp != NULL);
1599 
1600  if( row->lpipos >= 0 && col->lpipos >= 0 )
1601  {
1602  assert(row->lpipos < lp->nlpirows);
1603  assert(col->lpipos < lp->nlpicols);
1604 
1605  /* we have to remember the change only in the row or in the column,
1606  * because the readdition of one vector would change the other automatically.
1607  */
1608  if( row->lpipos >= lp->lpifirstchgrow )
1609  row->coefchanged = TRUE;
1610  else if( col->lpipos >= lp->lpifirstchgcol )
1611  col->coefchanged = TRUE;
1612  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1613  {
1614  row->coefchanged = TRUE;
1615  lp->lpifirstchgrow = row->lpipos;
1616  }
1617  else
1618  {
1619  col->coefchanged = TRUE;
1620  lp->lpifirstchgcol = col->lpipos;
1621  }
1622 
1623  /* mark the current LP unflushed */
1624  lp->flushed = FALSE;
1625  }
1626 
1628  row->minactivity = SCIP_INVALID;
1629  row->maxactivity = SCIP_INVALID;
1630  row->validpsactivitydomchg = -1;
1631  row->validactivitybdsdomchg = -1;
1632 }
1633 
1634 
1635 
1636 /*
1637  * local column changing methods
1638  */
1639 
1640 /* forward declaration for colAddCoef() */
1641 static
1643  SCIP_ROW* row, /**< LP row */
1644  BMS_BLKMEM* blkmem, /**< block memory */
1645  SCIP_SET* set, /**< global SCIP settings */
1646  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1647  SCIP_LP* lp, /**< current LP data */
1648  SCIP_COL* col, /**< LP column */
1649  SCIP_Real val, /**< value of coefficient */
1650  int linkpos /**< position of row in the column's row array, or -1 */
1651  );
1652 
1653 /** adds a previously non existing coefficient to an LP column */
1654 static
1656  SCIP_COL* col, /**< LP column */
1657  BMS_BLKMEM* blkmem, /**< block memory */
1658  SCIP_SET* set, /**< global SCIP settings */
1659  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1660  SCIP_LP* lp, /**< current LP data */
1661  SCIP_ROW* row, /**< LP row */
1662  SCIP_Real val, /**< value of coefficient */
1663  int linkpos /**< position of column in the row's col array, or -1 */
1664  )
1665 {
1666  int pos;
1667 
1668  assert(blkmem != NULL);
1669  assert(col != NULL);
1670  assert(col->nlprows <= col->len);
1671  assert(col->var != NULL);
1672  assert(row != NULL);
1673  assert(!SCIPsetIsZero(set, val));
1674  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1675 
1676  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1677  assert(col->rows != NULL);
1678  assert(col->vals != NULL);
1679  assert(col->linkpos != NULL);
1680 
1681  pos = col->len;
1682  col->len++;
1683 
1684  /* 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
1685  * part of the column's arrays
1686  */
1687  if( row->lppos >= 0 && linkpos >= 0 )
1688  {
1689  /* move the first non-LP/not linked row to the end */
1690  if( col->nlprows < pos )
1691  {
1692  colMoveCoef(col, col->nlprows, pos);
1693  pos = col->nlprows;
1694  }
1695  col->nlprows++;
1696  }
1697 
1698  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1699  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1700 
1701  /* insert the row at the correct position and update the links */
1702  col->rows[pos] = row;
1703  col->vals[pos] = val;
1704  col->linkpos[pos] = linkpos;
1705  if( linkpos == -1 )
1706  {
1707  col->nunlinked++;
1708 
1709  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1710  * of the row is not complete
1711  */
1712  if( col->lppos >= 0 )
1713  {
1714  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1715  * has to be updated
1716  */
1717  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1718  if( row->lppos >= 0 )
1719  pos = col->nlprows-1;
1720  linkpos = col->linkpos[pos];
1721 
1722  assert(0 <= linkpos && linkpos < row->len);
1723  assert(row->cols[linkpos] == col);
1724  assert(col->rows[pos] == row);
1725  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1726  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1727  }
1728  }
1729  else
1730  {
1731  assert(row->linkpos[linkpos] == -1);
1732  assert(row->nunlinked > 0);
1733  row->linkpos[linkpos] = pos;
1734  row->nunlinked--;
1735 
1736  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1737  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1738  */
1739  if( col->lppos >= 0 )
1740  {
1741  row->nlpcols++;
1742  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1743 
1744  /* if no swap was necessary, mark nonlpcols to be unsorted */
1745  if( linkpos == row->nlpcols-1 )
1746  row->lpcolssorted = FALSE;
1747  }
1748  }
1749 
1750  /* update the sorted flags */
1751  if( row->lppos >= 0 && linkpos >= 0 )
1752  {
1753  assert(col->nlprows >= 1);
1754  assert(col->rows[col->nlprows-1] == row);
1755  if( col->nlprows > 1 )
1756  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1757  }
1758  else
1759  {
1760  assert(col->len - col->nlprows >= 1);
1761  assert(col->rows[col->len-1] == row);
1762  if( col->len - col->nlprows > 1 )
1763  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1764  }
1765 
1766  coefChanged(row, col, lp);
1767 
1768  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1769  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1770 
1771  return SCIP_OKAY;
1772 }
1773 
1774 /** deletes coefficient at given position from column */
1775 static
1777  SCIP_COL* col, /**< column to be changed */
1778  SCIP_SET* set, /**< global SCIP settings */
1779  SCIP_LP* lp, /**< current LP data */
1780  int pos /**< position in column vector to delete */
1781  )
1782 {
1783  SCIP_ROW* row;
1784 
1785  assert(col != NULL);
1786  assert(col->var != NULL);
1787  assert(set != NULL);
1788  assert(0 <= pos && pos < col->len);
1789  assert(col->rows[pos] != NULL);
1790  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1791  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1792 
1793  row = col->rows[pos];
1794  assert((row->lppos >= 0) == (pos < col->nlprows));
1795 
1796  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1797  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1798 
1799  if( col->linkpos[pos] == -1 )
1800  col->nunlinked--;
1801 
1802  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1803  if( pos < col->nlprows )
1804  {
1805  colMoveCoef(col, col->nlprows-1, pos);
1806  col->nlprows--;
1807  pos = col->nlprows;
1808  }
1809 
1810  /* move last coefficient to position of empty slot */
1811  colMoveCoef(col, col->len-1, pos);
1812  col->len--;
1813 
1814  coefChanged(row, col, lp);
1815 
1816  return SCIP_OKAY;
1817 }
1818 
1819 /** changes a coefficient at given position of an LP column */
1820 static
1822  SCIP_COL* col, /**< LP column */
1823  SCIP_SET* set, /**< global SCIP settings */
1824  SCIP_LP* lp, /**< current LP data */
1825  int pos, /**< position in column vector to change */
1826  SCIP_Real val /**< value of coefficient */
1827  )
1828 {
1829  assert(col != NULL);
1830  assert(col->var != NULL);
1831  assert(0 <= pos && pos < col->len);
1832  assert(col->rows[pos] != NULL);
1833  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1834 
1835  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1836  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1837 
1838  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1839  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1840 
1841  if( SCIPsetIsZero(set, val) )
1842  {
1843  /* delete existing coefficient */
1844  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1845  }
1846  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1847  {
1848  /* change existing coefficient */
1849  col->vals[pos] = val;
1850  coefChanged(col->rows[pos], col, lp);
1851  }
1852 
1853  return SCIP_OKAY;
1854 }
1855 
1856 
1857 
1858 
1859 /*
1860  * local row changing methods
1861  */
1862 
1863 /** update row norms after addition of coefficient */
1864 static
1866  SCIP_ROW* row, /**< LP row */
1867  SCIP_SET* set, /**< global SCIP settings */
1868  SCIP_COL* col, /**< column of added coefficient */
1869  SCIP_Real val, /**< value of added coefficient */
1870  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1871  )
1872 {
1873  SCIP_Real absval;
1874 
1875  assert(row != NULL);
1876  assert(row->nummaxval >= 0);
1877  assert(row->numminval >= 0);
1878  assert(set != NULL);
1879  assert(col != NULL);
1880 
1881  absval = REALABS(val);
1882  assert(!SCIPsetIsZero(set, absval));
1883 
1884  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1885  if( col->lppos >= 0 )
1886  {
1887  /* update squared Euclidean norm and sum norm */
1888  row->sqrnorm += SQR(absval);
1889  row->sumnorm += absval;
1890 
1891  /* update objective function scalar product */
1892  row->objprod += val * col->unchangedobj;
1893  }
1894 
1895  if( updateidxvals )
1896  {
1897  /* update min/maxidx */
1898  row->minidx = MIN(row->minidx, col->index);
1899  row->maxidx = MAX(row->maxidx, col->index);
1900 
1901  /* update maximal and minimal non-zero value */
1902  if( row->nummaxval > 0 )
1903  {
1904  if( SCIPsetIsGT(set, absval, row->maxval) )
1905  {
1906  row->maxval = absval;
1907  row->nummaxval = 1;
1908  }
1909  else if( SCIPsetIsGE(set, absval, row->maxval) )
1910  {
1911  /* make sure the maxval is always exactly the same */
1912  row->maxval = MAX(absval, row->maxval);
1913  row->nummaxval++;
1914  }
1915  }
1916  if( row->numminval > 0 )
1917  {
1918  if( SCIPsetIsLT(set, absval, row->minval) )
1919  {
1920  row->minval = absval;
1921  row->numminval = 1;
1922  }
1923  else if( SCIPsetIsLE(set, absval, row->minval) )
1924  {
1925  /* make sure the minval is always exactly the same */
1926  row->minval = MIN(absval, row->minval);
1927  row->numminval++;
1928  }
1929  }
1930  }
1931  else
1932  {
1933  assert(row->minidx <= col->index);
1934  assert(row->maxidx >= col->index);
1935  assert(row->numminval <= 0 || absval >= row->minval);
1936  assert(row->nummaxval <= 0 || absval <= row->maxval);
1937  }
1938 }
1939 
1940 /** update row norms after deletion of coefficient */
1941 static
1943  SCIP_ROW* row, /**< LP row */
1944  SCIP_SET* set, /**< global SCIP settings */
1945  SCIP_COL* col, /**< column of deleted coefficient */
1946  SCIP_Real val, /**< value of deleted coefficient */
1947  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1948  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1949  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1950  )
1951 {
1952  SCIP_Real absval;
1953 
1954  assert(row != NULL);
1955  assert(row->nummaxval >= 0);
1956  assert(row->numminval >= 0);
1957  assert(set != NULL);
1958  assert(col != NULL);
1959 
1960  absval = REALABS(val);
1961  assert(!SCIPsetIsZero(set, absval));
1962  assert(row->nummaxval == 0 || row->maxval >= absval);
1963  assert(row->numminval == 0 || row->minval <= absval);
1964 
1965  /* update min/maxidx validity */
1966  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
1967  row->validminmaxidx = FALSE;
1968 
1969  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1970  if( forcenormupdate || col->lppos >= 0 )
1971  {
1972  /* update squared Euclidean norm and sum norm */
1973  row->sqrnorm -= SQR(absval);
1974  row->sqrnorm = MAX(row->sqrnorm, 0.0);
1975  row->sumnorm -= absval;
1976  row->sumnorm = MAX(row->sumnorm, 0.0);
1977 
1978  /* update objective function scalar product */
1979  row->objprod -= val * col->unchangedobj;
1980  }
1981 
1982  if( updateval )
1983  {
1984  /* update maximal and minimal non-zero value */
1985  if( row->nummaxval > 0 )
1986  {
1987  if( SCIPsetIsGE(set, absval, row->maxval) )
1988  row->nummaxval--;
1989  }
1990  if( row->numminval > 0 )
1991  {
1992  if( SCIPsetIsLE(set, absval, row->minval) )
1993  row->numminval--;
1994  }
1995  }
1996 }
1997 
1998 /** adds a previously non existing coefficient to an LP row */
1999 static
2001  SCIP_ROW* row, /**< LP row */
2002  BMS_BLKMEM* blkmem, /**< block memory */
2003  SCIP_SET* set, /**< global SCIP settings */
2004  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2005  SCIP_LP* lp, /**< current LP data */
2006  SCIP_COL* col, /**< LP column */
2007  SCIP_Real val, /**< value of coefficient */
2008  int linkpos /**< position of row in the column's row array, or -1 */
2009  )
2010 {
2011  int pos;
2012 
2013  assert(row != NULL);
2014  assert(row->nlpcols <= row->len);
2015  assert(blkmem != NULL);
2016  assert(col != NULL);
2017  assert(col->var != NULL);
2018  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2019  assert(!SCIPsetIsZero(set, val));
2020  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2021 
2022  if( row->nlocks > 0 )
2023  {
2024  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2025  return SCIP_INVALIDDATA;
2026  }
2027 
2028  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2029  assert(row->cols != NULL);
2030  assert(row->vals != NULL);
2031 
2032  pos = row->len;
2033  row->len++;
2034 
2035  /* 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
2036  * part of the row's arrays
2037  */
2038  if( col->lppos >= 0 && linkpos >= 0 )
2039  {
2040  /* move the first non-LP/not linked column to the end */
2041  if( row->nlpcols < pos )
2042  {
2043  rowMoveCoef(row, row->nlpcols, pos);
2044  pos = row->nlpcols;
2045  }
2046  row->nlpcols++;
2047  }
2048 
2049  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2050  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2051 
2052  /* insert the column at the correct position and update the links */
2053  row->cols[pos] = col;
2054  row->cols_index[pos] = col->index;
2055  row->vals[pos] = val;
2056  row->linkpos[pos] = linkpos;
2057  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2058  if( linkpos == -1 )
2059  {
2060  row->nunlinked++;
2061 
2062  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2063  * of the column is not complete
2064  */
2065  if( row->lppos >= 0 )
2066  {
2067  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2068  * has to be updated
2069  */
2070  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2071  if( col->lppos >= 0 )
2072  pos = row->nlpcols-1;
2073  linkpos = row->linkpos[pos];
2074 
2075  assert(0 <= linkpos && linkpos < col->len);
2076  assert(col->rows[linkpos] == row);
2077  assert(row->cols[pos] == col);
2078  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2079  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2080  }
2081  }
2082  else
2083  {
2084  assert(col->linkpos[linkpos] == -1);
2085  assert(col->nunlinked > 0);
2086  col->linkpos[linkpos] = pos;
2087  col->nunlinked--;
2088 
2089  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2090  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2091  */
2092  if( row->lppos >= 0 )
2093  {
2094  col->nlprows++;
2095  colSwapCoefs(col, linkpos, col->nlprows-1);
2096 
2097  /* if no swap was necessary, mark lprows to be unsorted */
2098  if( linkpos == col->nlprows-1 )
2099  col->lprowssorted = FALSE;
2100  }
2101  }
2102 
2103  /* update the sorted flags */
2104  if( col->lppos >= 0 && linkpos >= 0 )
2105  {
2106  assert(row->nlpcols >= 1);
2107  assert(row->cols[row->nlpcols-1] == col);
2108  if( row->nlpcols > 1 )
2109  {
2110  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2111  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2112  }
2113  }
2114  else
2115  {
2116  assert(row->len - row->nlpcols >= 1);
2117  assert(row->cols[row->len-1] == col);
2118  if( row->len - row->nlpcols > 1 )
2119  {
2120  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2121  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2122  }
2123  }
2124 
2125  /* update row norm */
2126  rowAddNorms(row, set, col, val, TRUE);
2127 
2128  coefChanged(row, col, lp);
2129 
2130  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2131  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2132 
2133  /* issue row coefficient changed event */
2134  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2135 
2136  return SCIP_OKAY;
2137 }
2138 
2139 /** deletes coefficient at given position from row */
2140 static
2142  SCIP_ROW* row, /**< row to be changed */
2143  BMS_BLKMEM* blkmem, /**< block memory */
2144  SCIP_SET* set, /**< global SCIP settings */
2145  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2146  SCIP_LP* lp, /**< current LP data */
2147  int pos /**< position in row vector to delete */
2148  )
2149 {
2150  SCIP_COL* col;
2151  SCIP_Real val;
2152 
2153  assert(row != NULL);
2154  assert(set != NULL);
2155  assert(0 <= pos && pos < row->len);
2156  assert(row->cols[pos] != NULL);
2157  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2158 
2159  col = row->cols[pos];
2160  val = row->vals[pos];
2161  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2162 
2163  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2164  val, SCIPvarGetName(col->var), pos, row->name);*/
2165 
2166  if( row->nlocks > 0 )
2167  {
2168  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2169  return SCIP_INVALIDDATA;
2170  }
2171 
2172  if( row->linkpos[pos] == -1 )
2173  row->nunlinked--;
2174 
2175  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2176  if( pos < row->nlpcols )
2177  {
2178  rowMoveCoef(row, row->nlpcols-1, pos);
2179  assert(!row->lpcolssorted);
2180  row->nlpcols--;
2181  pos = row->nlpcols;
2182  }
2183 
2184  /* move last coefficient to position of empty slot */
2185  rowMoveCoef(row, row->len-1, pos);
2186  row->len--;
2187 
2188  /* update norms */
2189  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2190 
2191  coefChanged(row, col, lp);
2192 
2193  /* issue row coefficient changed event */
2194  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2195 
2196  return SCIP_OKAY;
2197 }
2198 
2199 /** changes a coefficient at given position of an LP row */
2200 static
2202  SCIP_ROW* row, /**< LP row */
2203  BMS_BLKMEM* blkmem, /**< block memory */
2204  SCIP_SET* set, /**< global SCIP settings */
2205  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2206  SCIP_LP* lp, /**< current LP data */
2207  int pos, /**< position in row vector to change */
2208  SCIP_Real val /**< value of coefficient */
2209  )
2210 {
2211  SCIP_COL* col;
2212 
2213  assert(row != NULL);
2214  assert(0 <= pos && pos < row->len);
2215 
2216  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2217  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2218 
2219  if( row->nlocks > 0 )
2220  {
2221  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2222  return SCIP_INVALIDDATA;
2223  }
2224 
2225  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2226  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2227  col = row->cols[pos];
2228  assert(row->cols[pos] != NULL);
2229 
2230  if( SCIPsetIsZero(set, val) )
2231  {
2232  /* delete existing coefficient */
2233  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2234  }
2235  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2236  {
2237  SCIP_Real oldval;
2238 
2239  oldval = row->vals[pos];
2240 
2241  /* change existing coefficient */
2242  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2243  row->vals[pos] = val;
2244  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2245  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2246  coefChanged(row, col, lp);
2247 
2248  /* issue row coefficient changed event */
2249  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2250  }
2251 
2252  return SCIP_OKAY;
2253 }
2254 
2255 /** notifies LP row, that its sides were changed */
2256 static
2258  SCIP_ROW* row, /**< LP row */
2259  SCIP_SET* set, /**< global SCIP settings */
2260  SCIP_LP* lp, /**< current LP data */
2261  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2262  )
2263 {
2264  assert(row != NULL);
2265  assert(lp != NULL);
2266 
2267  if( row->lpipos >= 0 )
2268  {
2269  /* insert row in the chgrows list (if not already there) */
2270  if( !row->lhschanged && !row->rhschanged )
2271  {
2272  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2273  lp->chgrows[lp->nchgrows] = row;
2274  lp->nchgrows++;
2275  }
2276 
2277  /* mark side change in the row */
2278  switch( sidetype )
2279  {
2280  case SCIP_SIDETYPE_LEFT:
2281  row->lhschanged = TRUE;
2282  break;
2283  case SCIP_SIDETYPE_RIGHT:
2284  row->rhschanged = TRUE;
2285  break;
2286  default:
2287  SCIPerrorMessage("unknown row side type\n");
2288  SCIPABORT();
2289  return SCIP_INVALIDDATA; /*lint !e527*/
2290  }
2291 
2292  /* mark the current LP unflushed */
2293  lp->flushed = FALSE;
2294 
2295  assert(lp->nchgrows > 0);
2296  }
2297 
2298  return SCIP_OKAY;
2299 }
2300 
2301 
2302 
2303 
2304 /*
2305  * double linked coefficient matrix methods
2306  */
2307 
2308 /** insert column coefficients in corresponding rows */
2309 static
2311  SCIP_COL* col, /**< column data */
2312  BMS_BLKMEM* blkmem, /**< block memory */
2313  SCIP_SET* set, /**< global SCIP settings */
2314  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2315  SCIP_LP* lp /**< current LP data */
2316  )
2317 {
2318  int i;
2319 
2320  assert(col != NULL);
2321  assert(col->var != NULL);
2322  assert(blkmem != NULL);
2323  assert(set != NULL);
2324  assert(lp != NULL);
2325 
2326  if( col->nunlinked > 0 )
2327  {
2328  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2329 
2330  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2331  for( i = col->nlprows; i < col->len; ++i )
2332  {
2333  assert(!SCIPsetIsZero(set, col->vals[i]));
2334  if( col->linkpos[i] == -1 )
2335  {
2336  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2337  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2338  }
2339  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2340  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2341  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2342  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2343  }
2344  }
2345  assert(col->nunlinked == 0);
2346 
2347  checkLinks(lp);
2348 
2349  return SCIP_OKAY;
2350 }
2351 
2352 /** removes column coefficients from corresponding rows */
2353 static
2355  SCIP_COL* col, /**< column data */
2356  BMS_BLKMEM* blkmem, /**< block memory */
2357  SCIP_SET* set, /**< global SCIP settings */
2358  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2359  SCIP_LP* lp /**< current LP data */
2360  )
2361 {
2362  int i;
2363 
2364  assert(col != NULL);
2365  assert(col->var != NULL);
2366  assert(blkmem != NULL);
2367  assert(set != NULL);
2368  assert(lp != NULL);
2369 
2370  if( col->nunlinked < col->len )
2371  {
2372  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2373  for( i = 0; i < col->len; ++i )
2374  {
2375  if( col->linkpos[i] >= 0 )
2376  {
2377  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2378  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2379  col->linkpos[i] = -1;
2380  col->nunlinked++;
2381  }
2382  }
2383  }
2384  assert(col->nunlinked == col->len);
2385 
2386  checkLinks(lp);
2387 
2388  return SCIP_OKAY;
2389 }
2390 
2391 /** insert row coefficients in corresponding columns */
2392 static
2394  SCIP_ROW* row, /**< row data */
2395  BMS_BLKMEM* blkmem, /**< block memory */
2396  SCIP_SET* set, /**< global SCIP settings */
2397  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2398  SCIP_LP* lp /**< current LP data */
2399  )
2400 {
2401  int i;
2402 
2403  assert(row != NULL);
2404  assert(blkmem != NULL);
2405  assert(set != NULL);
2406  assert(lp != NULL);
2407 
2408  if( row->nunlinked > 0 )
2409  {
2410  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2411 
2412  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2413  for( i = row->nlpcols; i < row->len; ++i )
2414  {
2415  assert(!SCIPsetIsZero(set, row->vals[i]));
2416  if( row->linkpos[i] == -1 )
2417  {
2418  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2419  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2420  }
2421  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2422  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2423  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2424  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2425  }
2426  }
2427  assert(row->nunlinked == 0);
2428 
2429  checkLinks(lp);
2430 
2431  return SCIP_OKAY;
2432 }
2433 
2434 /** removes row coefficients from corresponding columns */
2435 static
2437  SCIP_ROW* row, /**< row data */
2438  SCIP_SET* set, /**< global SCIP settings */
2439  SCIP_LP* lp /**< current LP data */
2440  )
2441 {
2442  int i;
2443 
2444  assert(row != NULL);
2445  assert(set != NULL);
2446  assert(lp != NULL);
2447 
2448  if( row->nunlinked < row->len )
2449  {
2450  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2451  for( i = 0; i < row->len; ++i )
2452  {
2453  if( row->linkpos[i] >= 0 )
2454  {
2455  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2456  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2457  row->nunlinked++;
2458  }
2459  }
2460  }
2461  assert(row->nunlinked == row->len);
2462 
2463  return SCIP_OKAY;
2464 }
2465 
2466 
2467 
2468 
2469 /*
2470  * local LP parameter methods
2471  */
2472 
2473 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2474 static
2476  SCIP_LP* lp, /**< current LP data */
2477  SCIP_LPPARAM lpparam, /**< LP parameter */
2478  int value, /**< value to set parameter to */
2479  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2480  )
2481 {
2482  SCIP_RETCODE retcode;
2483 
2484  assert(lp != NULL);
2485  assert(success != NULL);
2486 
2487  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2488 
2489  /* check, if parameter is unknown */
2490  if( retcode == SCIP_PARAMETERUNKNOWN )
2491  {
2492  *success = FALSE;
2493  return SCIP_OKAY;
2494  }
2495  *success = TRUE;
2496 
2497  return retcode;
2498 }
2499 
2500 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2501 static
2503  SCIP_LP* lp, /**< current LP data */
2504  SCIP_LPPARAM lpparam, /**< LP parameter */
2505  SCIP_Bool value, /**< value to set parameter to */
2506  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2507  )
2508 {
2509  return lpSetIntpar(lp, lpparam, (int)value, success);
2510 }
2511 
2512 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2513 static
2515  SCIP_LP* lp, /**< current LP data */
2516  SCIP_LPPARAM lpparam, /**< LP parameter */
2517  SCIP_Real value, /**< value to set parameter to */
2518  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2519  )
2520 {
2521  SCIP_RETCODE retcode;
2522 
2523  assert(lp != NULL);
2524  assert(success != NULL);
2525 
2526  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2527 
2528  /* check, if parameter is unknown */
2529  if( retcode == SCIP_PARAMETERUNKNOWN )
2530  {
2531  *success = FALSE;
2532  return SCIP_OKAY;
2533  }
2534  *success = TRUE;
2535 
2536  return retcode;
2537 }
2538 
2539 #ifndef NDEBUG
2540 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2541 static
2543  SCIP_LP* lp, /**< current LP data */
2544  SCIP_LPPARAM lpparam, /**< LP parameter */
2545  int value /**< value parameter should have */
2546  )
2547 {
2548  SCIP_RETCODE retcode;
2549  int lpivalue;
2550 
2551  assert(lp != NULL);
2552 
2553  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2554 
2555  /* ignore unknown parameter error */
2556  if( retcode == SCIP_PARAMETERUNKNOWN )
2557  return SCIP_OKAY;
2558 
2559  /* check value */
2560  assert(lpivalue == value);
2561 
2562  return retcode;
2563 }
2564 
2565 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2566 static
2568  SCIP_LP* lp, /**< current LP data */
2569  SCIP_LPPARAM lpparam, /**< LP parameter */
2570  SCIP_Bool value /**< value parameter should have */
2571  )
2572 {
2573  return lpCheckIntpar(lp, lpparam, (int)value);
2574 }
2575 
2576 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2577 static
2579  SCIP_LP* lp, /**< current LP data */
2580  SCIP_LPPARAM lpparam, /**< LP parameter */
2581  SCIP_Real value /**< value parameter should have */
2582  )
2583 {
2584  SCIP_RETCODE retcode;
2585  SCIP_Real lpivalue;
2586 
2587  assert(lp != NULL);
2588 
2589  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2590 
2591  /* ignore unknown parameter error */
2592  if( retcode == SCIP_PARAMETERUNKNOWN )
2593  return SCIP_OKAY;
2594 
2595  /* check value */
2596  assert(lpivalue == value); /*lint !e777*/
2597 
2598  return retcode;
2599 }
2600 #else
2601 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2602 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2603 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2604 #endif
2605 
2606 /** should the objective limit of the LP solver be disabled */
2607 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2608 
2609 /** sets the objective limit of the LP solver
2610  *
2611  * Note that we are always minimizing.
2612  */
2613 static
2615  SCIP_LP* lp, /**< current LP data */
2616  SCIP_SET* set, /**< global SCIP settings */
2617  SCIP_Real objlim /**< new objective limit */
2618  )
2619 {
2620  assert(lp != NULL);
2621  assert(set != NULL);
2622 
2623  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2624  * solver's objective limit handling, so we return here and do not apply the objective limit. */
2625  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2626  return SCIP_OKAY;
2627 
2628  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2629  if( SCIPsetIsInfinity(set, objlim) )
2630  objlim = SCIPlpiInfinity(lp->lpi);
2631 
2633 
2634  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2635  {
2636  SCIP_Bool success;
2637 
2638  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, &success) );
2639  if( success )
2640  {
2641  /* mark the current solution invalid */
2642  lp->solved = FALSE;
2643  lp->primalfeasible = FALSE;
2644  lp->primalchecked = FALSE;
2645  lp->lpobjval = SCIP_INVALID;
2647  lp->lpiobjlim = objlim;
2648  }
2649  }
2650 
2651  return SCIP_OKAY;
2652 }
2653 
2654 /** sets the feasibility tolerance of the LP solver */
2655 static
2657  SCIP_LP* lp, /**< current LP data */
2658  SCIP_Real feastol, /**< new feasibility tolerance */
2659  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2660  )
2661 {
2662  assert(lp != NULL);
2663  assert(feastol >= 0.0);
2664  assert(success != NULL);
2665 
2667 
2668  if( feastol != lp->lpifeastol ) /*lint !e777*/
2669  {
2670  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2671  if( *success )
2672  {
2673  if( lp->nrows > 0 && feastol < lp->lpifeastol )
2674  {
2675  /* mark the current solution invalid */
2676  lp->solved = FALSE;
2677  lp->primalfeasible = FALSE;
2678  lp->primalchecked = FALSE;
2679  lp->lpobjval = SCIP_INVALID;
2681  }
2682  lp->lpifeastol = feastol;
2683  }
2684  }
2685  else
2686  *success = FALSE;
2687 
2688  return SCIP_OKAY;
2689 }
2690 
2691 /** sets the reduced costs feasibility tolerance of the LP solver */
2692 static
2694  SCIP_LP* lp, /**< current LP data */
2695  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2696  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2697  )
2698 {
2699  assert(lp != NULL);
2700  assert(dualfeastol >= 0.0);
2701  assert(success != NULL);
2702 
2704 
2705  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2706  {
2707  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2708  if( *success )
2709  {
2710  if( lp->nrows > 0 && dualfeastol < lp->lpidualfeastol )
2711  {
2712  /* mark the current solution invalid */
2713  lp->solved = FALSE;
2714  lp->dualfeasible = FALSE;
2715  lp->dualchecked = FALSE;
2716  lp->lpobjval = SCIP_INVALID;
2718  }
2719  lp->lpidualfeastol = dualfeastol;
2720  }
2721  }
2722  else
2723  *success = FALSE;
2724 
2725  return SCIP_OKAY;
2726 }
2727 
2728 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2729 static
2731  SCIP_LP* lp, /**< current LP data */
2732  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2733  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2734  )
2735 {
2736  assert(lp != NULL);
2737  assert(barrierconvtol >= 0.0);
2738  assert(success != NULL);
2739 
2741 
2742  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2743  {
2744  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2745  if( *success )
2746  {
2747  if( lp->nrows > 0 && barrierconvtol < lp->lpibarrierconvtol
2749  {
2750  /* mark the current solution invalid */
2751  lp->solved = FALSE;
2752  lp->dualfeasible = FALSE;
2753  lp->dualchecked = FALSE;
2754  lp->lpobjval = SCIP_INVALID;
2756  }
2757  lp->lpibarrierconvtol = barrierconvtol;
2758  }
2759  }
2760  else
2761  *success = FALSE;
2762 
2763  return SCIP_OKAY;
2764 }
2765 
2766 /** sets the FROMSCRATCH setting of the LP solver */
2767 static
2769  SCIP_LP* lp, /**< current LP data */
2770  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2771  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2772  )
2773 {
2774  assert(lp != NULL);
2775  assert(success != NULL);
2776 
2778 
2779  if( fromscratch != lp->lpifromscratch )
2780  {
2781  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2782  if( *success )
2783  lp->lpifromscratch = fromscratch;
2784  }
2785  else
2786  *success = FALSE;
2787 
2788  return SCIP_OKAY;
2789 }
2790 
2791 /** sets the FASTMIP setting of the LP solver */
2792 static
2794  SCIP_LP* lp, /**< current LP data */
2795  int fastmip, /**< new FASTMIP setting */
2796  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2797  )
2798 {
2799  assert(lp != NULL);
2800  assert(success != NULL);
2801  assert(0 <= fastmip && fastmip <= 1);
2802 
2804 
2805  if( fastmip != lp->lpifastmip )
2806  {
2807  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2808  if( *success )
2809  lp->lpifastmip = fastmip;
2810  }
2811  else
2812  *success = FALSE;
2813 
2814  return SCIP_OKAY;
2815 }
2816 
2817 /** sets the SCALING setting of the LP solver */
2818 static
2820  SCIP_LP* lp, /**< current LP data */
2821  int scaling, /**< new SCALING setting */
2822  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2823  )
2824 {
2825  assert(lp != NULL);
2826  assert(success != NULL);
2827 
2829 
2830  if( scaling != lp->lpiscaling )
2831  {
2832  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2833  if( *success )
2834  lp->lpiscaling = scaling;
2835  }
2836  else
2837  *success = FALSE;
2838 
2839  return SCIP_OKAY;
2840 }
2841 
2842 /** sets the number of THREADS of the LP solver */
2843 static
2845  SCIP_LP* lp, /**< current LP data */
2846  int threads, /**< new number of threads used to solve the LP */
2847  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2848  )
2849 {
2850  assert(lp != NULL);
2851  assert(success != NULL);
2852 
2854 
2855  if( threads != lp->lpithreads )
2856  {
2857  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2858  if( *success )
2859  lp->lpithreads = threads;
2860  }
2861  else
2862  *success = FALSE;
2863 
2864  return SCIP_OKAY;
2865 }
2866 
2867 /** sets the PRESOLVING setting of the LP solver */
2868 static
2870  SCIP_LP* lp, /**< current LP data */
2871  SCIP_Bool presolving, /**< new PRESOLVING setting */
2872  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2873  )
2874 {
2875  assert(lp != NULL);
2876  assert(success != NULL);
2877 
2879 
2880  if( presolving != lp->lpipresolving )
2881  {
2882  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2883  if( *success )
2884  lp->lpipresolving = presolving;
2885  }
2886  else
2887  *success = FALSE;
2888 
2889  return SCIP_OKAY;
2890 }
2891 
2892 /** sets the ROWREPSWITCH setting of the LP solver */
2893 static
2895  SCIP_LP* lp, /**< current LP data */
2896  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2897  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2898  )
2899 {
2900  assert(lp != NULL);
2901  assert(success != NULL);
2902 
2904 
2905  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2906  {
2907  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2908  if( *success )
2909  lp->lpirowrepswitch = rowrepswitch;
2910  }
2911  else
2912  *success = FALSE;
2913 
2914  return SCIP_OKAY;
2915 }
2916 
2917 /** sets the iteration limit of the LP solver */
2918 static
2920  SCIP_LP* lp, /**< current LP data */
2921  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2922  )
2923 {
2924  SCIP_Bool success;
2925 
2926  assert(lp != NULL);
2927  assert(itlim >= -1);
2928 
2929  if( itlim == -1 )
2930  itlim = INT_MAX;
2931 
2933 
2934  if( itlim != lp->lpiitlim )
2935  {
2936  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2937  if( success )
2938  {
2939  if( itlim > lp->lpiitlim )
2940  {
2941  /* mark the current solution invalid */
2942  lp->solved = FALSE;
2943  lp->lpobjval = SCIP_INVALID;
2945  }
2946  lp->lpiitlim = itlim;
2947  }
2948  }
2949 
2950  return SCIP_OKAY;
2951 }
2952 
2953 /** sets the pricing strategy of the LP solver */
2954 static
2956  SCIP_LP* lp, /**< current LP data */
2957  SCIP_PRICING pricing /**< pricing strategy */
2958  )
2959 {
2960  SCIP_Bool success;
2961 
2962  assert(lp != NULL);
2963 
2965 
2966  if( pricing != lp->lpipricing )
2967  {
2968  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
2969  if( success )
2970  lp->lpipricing = pricing;
2971  }
2972 
2973  return SCIP_OKAY;
2974 }
2975 
2976 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
2977 static
2979  SCIP_LP* lp, /**< current LP data */
2980  char pricingchar /**< character representing the pricing strategy */
2981  )
2982 {
2983  SCIP_PRICING pricing;
2984 
2985  switch( pricingchar )
2986  {
2987  case 'l':
2988  pricing = SCIP_PRICING_LPIDEFAULT;
2989  break;
2990  case 'a':
2991  pricing = SCIP_PRICING_AUTO;
2992  break;
2993  case 'f':
2994  pricing = SCIP_PRICING_FULL;
2995  break;
2996  case 'p':
2997  pricing = SCIP_PRICING_PARTIAL;
2998  break;
2999  case 's':
3000  pricing = SCIP_PRICING_STEEP;
3001  break;
3002  case 'q':
3003  pricing = SCIP_PRICING_STEEPQSTART;
3004  break;
3005  case 'd':
3006  pricing = SCIP_PRICING_DEVEX;
3007  break;
3008  default:
3009  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3010  return SCIP_INVALIDDATA;
3011  }
3012 
3013  SCIP_CALL( lpSetPricing(lp, pricing) );
3014 
3015  return SCIP_OKAY;
3016 }
3017 
3018 /** sets the verbosity of the LP solver */
3019 static
3021  SCIP_LP* lp, /**< current LP data */
3022  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3023  )
3024 {
3025  SCIP_Bool success;
3026 
3027  assert(lp != NULL);
3028 
3030 
3031  if( lpinfo != lp->lpilpinfo )
3032  {
3033  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3034  if( success )
3035  lp->lpilpinfo = lpinfo;
3036  }
3037 
3038  return SCIP_OKAY;
3039 }
3040 
3041 /** sets the CONDITIONLIMIT setting of the LP solver */
3042 static
3044  SCIP_LP* lp, /**< current LP data */
3045  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3046  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3047  )
3048 {
3049  assert(lp != NULL);
3050  assert(success != NULL);
3051 
3053 
3054  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3055  {
3056  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3057  if( *success )
3058  lp->lpiconditionlimit = condlimit;
3059  }
3060  else
3061  *success = FALSE;
3062 
3063  return SCIP_OKAY;
3064 }
3065 
3066 /** sets the type of timer of the LP solver */
3067 static
3069  SCIP_LP* lp, /**< current LP data */
3070  SCIP_CLOCKTYPE timing, /**< new timing value */
3071  SCIP_Bool enabled, /**< is timing enabled? */
3072  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3073  )
3074 {
3075  int lptiming;
3076 
3077  assert(lp != NULL);
3078  assert(success != NULL);
3079  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2);
3080 
3082 
3083  if( !enabled )
3084  lptiming = 0;
3085  else
3086  lptiming = (int) timing;
3087 
3088  if( lptiming != lp->lpitiming ) /*lint !e777*/
3089  {
3090  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3091  if( *success )
3092  lp->lpitiming = lptiming;
3093  }
3094  else
3095  *success = FALSE;
3096 
3097  return SCIP_OKAY;
3098 }
3099 
3100 /** sets the initial random seed of the LP solver */
3101 static
3103  SCIP_LP* lp, /**< current LP data */
3104  int randomseed, /**< new initial random seed */
3105  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3106  )
3107 {
3108  assert(lp != NULL);
3109  assert(success != NULL);
3110 
3111  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3112 
3113  if( randomseed == 0 )
3114  {
3115  lp->lpirandomseed = randomseed;
3116  *success = TRUE;
3117  }
3118  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3119  {
3120  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3121  if( *success )
3122  lp->lpirandomseed = randomseed;
3123  }
3124  else
3125  *success = FALSE;
3126 
3127  return SCIP_OKAY;
3128 }
3129 
3130 /** sets the LP solution polishing method */
3131 static
3133  SCIP_LP* lp, /**< current LP data */
3134  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3135  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3136  )
3137 {
3138  assert(lp != NULL);
3139  assert(success != NULL);
3140 
3141  if( polishing != lp->lpisolutionpolishing )
3142  {
3143  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3144  if( *success )
3145  lp->lpisolutionpolishing = polishing;
3146  }
3147  else
3148  *success = FALSE;
3149 
3150  return SCIP_OKAY;
3151 }
3152 
3153 /** sets the LP refactorization interval */
3154 static
3156  SCIP_LP* lp, /**< current LP data */
3157  int refactor, /**< LP refactorization interval (0: automatic) */
3158  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3159  )
3160 {
3161  assert(lp != NULL);
3162  assert(success != NULL);
3163 
3164  if( refactor != lp->lpirefactorinterval )
3165  {
3166  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3167  if( *success )
3168  lp->lpirefactorinterval = refactor;
3169  }
3170  else
3171  *success = FALSE;
3172 
3173  return SCIP_OKAY;
3174 }
3175 
3176 
3177 /*
3178  * Column methods
3179  */
3180 
3181 /** creates an LP column */
3183  SCIP_COL** col, /**< pointer to column data */
3184  BMS_BLKMEM* blkmem, /**< block memory */
3185  SCIP_SET* set, /**< global SCIP settings */
3186  SCIP_STAT* stat, /**< problem statistics */
3187  SCIP_VAR* var, /**< variable, this column represents */
3188  int len, /**< number of nonzeros in the column */
3189  SCIP_ROW** rows, /**< array with rows of column entries */
3190  SCIP_Real* vals, /**< array with coefficients of column entries */
3191  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3192  )
3193 {
3194  int i;
3195 
3196  assert(col != NULL);
3197  assert(blkmem != NULL);
3198  assert(set != NULL);
3199  assert(stat != NULL);
3200  assert(var != NULL);
3201  assert(len >= 0);
3202  assert(len == 0 || (rows != NULL && vals != NULL));
3203 
3204  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3205 
3206  if( len > 0 )
3207  {
3208  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3209  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3210  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3211 
3212  for( i = 0; i < len; ++i )
3213  {
3214  assert(rows[i] != NULL);
3215  assert(!SCIPsetIsZero(set, vals[i]));
3216  (*col)->linkpos[i] = -1;
3217  }
3218  }
3219  else
3220  {
3221  (*col)->rows = NULL;
3222  (*col)->vals = NULL;
3223  (*col)->linkpos = NULL;
3224  }
3225 
3226  (*col)->var = var;
3227  (*col)->obj = SCIPvarGetObj(var);
3228  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3229  (*col)->lb = SCIPvarGetLbLocal(var);
3230  (*col)->ub = SCIPvarGetUbLocal(var);
3231  (*col)->flushedobj = 0.0;
3232  (*col)->flushedlb = 0.0;
3233  (*col)->flushedub = 0.0;
3234  (*col)->index = stat->ncolidx;
3235  SCIPstatIncrement(stat, set, ncolidx);
3236  (*col)->size = len;
3237  (*col)->len = len;
3238  (*col)->nlprows = 0;
3239  (*col)->nunlinked = len;
3240  (*col)->lppos = -1;
3241  (*col)->lpipos = -1;
3242  (*col)->lpdepth = -1;
3243  (*col)->primsol = 0.0;
3244  (*col)->redcost = SCIP_INVALID;
3245  (*col)->farkascoef = SCIP_INVALID;
3246  (*col)->minprimsol = (*col)->ub;
3247  (*col)->maxprimsol = (*col)->lb;
3248  (*col)->sbdown = SCIP_INVALID;
3249  (*col)->sbup = SCIP_INVALID;
3250  (*col)->sbsolval = SCIP_INVALID;
3251  (*col)->sblpobjval = SCIP_INVALID;
3252  (*col)->sbnode = -1;
3253  (*col)->validredcostlp = -1;
3254  (*col)->validfarkaslp = -1;
3255  (*col)->validsblp = -1;
3256  (*col)->sbitlim = -1;
3257  (*col)->nsbcalls = 0;
3258  (*col)->age = 0;
3259  (*col)->obsoletenode = -1;
3260  (*col)->var_probindex = SCIPvarGetProbindex(var);
3261  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3262  (*col)->lprowssorted = TRUE;
3263  (*col)->nonlprowssorted = (len <= 1);
3264  (*col)->objchanged = FALSE;
3265  (*col)->lbchanged = FALSE;
3266  (*col)->ubchanged = FALSE;
3267  (*col)->coefchanged = FALSE;
3268  (*col)->integral = SCIPvarIsIntegral(var);
3269  (*col)->removable = removable;
3270  (*col)->sbdownvalid = FALSE;
3271  (*col)->sbupvalid = FALSE;
3272  (*col)->lazylb = SCIPvarGetLbLazy(var);
3273  (*col)->lazyub = SCIPvarGetUbLazy(var);
3274  (*col)->storedsolvals = NULL;
3275 
3276  return SCIP_OKAY;
3277 }
3278 
3279 /** frees an LP column */
3281  SCIP_COL** col, /**< pointer to LP column */
3282  BMS_BLKMEM* blkmem, /**< block memory */
3283  SCIP_SET* set, /**< global SCIP settings */
3284  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3285  SCIP_LP* lp /**< current LP data */
3286  )
3287 {
3288  assert(blkmem != NULL);
3289  assert(col != NULL);
3290  assert(*col != NULL);
3291  assert((*col)->var != NULL);
3292  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3293  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3294  assert((*col)->lppos == -1);
3295  assert((*col)->lpipos == -1);
3296 
3297  /* remove column indices from corresponding rows */
3298  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3299 
3300  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3301  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3302  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3303  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3304  BMSfreeBlockMemory(blkmem, col);
3305 
3306  return SCIP_OKAY;
3307 }
3308 
3309 /** output column to file stream */
3311  SCIP_COL* col, /**< LP column */
3312  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3313  FILE* file /**< output file (or NULL for standard output) */
3314  )
3315 {
3316  int r;
3317 
3318  assert(col != NULL);
3319  assert(col->var != NULL);
3320 
3321  /* print bounds */
3322  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3323 
3324  /* print coefficients */
3325  if( col->len == 0 )
3326  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3327  for( r = 0; r < col->len; ++r )
3328  {
3329  assert(col->rows[r] != NULL);
3330  assert(col->rows[r]->name != NULL);
3331  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3332  }
3333  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3334 }
3335 
3336 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3337  */
3339  SCIP_COL* col /**< column to be sorted */
3340  )
3341 {
3342  /* sort LP rows */
3343  colSortLP(col);
3344 
3345  /* sort non-LP rows */
3346  colSortNonLP(col);
3347 }
3348 
3349 /** adds a previously non existing coefficient to an LP column */
3351  SCIP_COL* col, /**< LP column */
3352  BMS_BLKMEM* blkmem, /**< block memory */
3353  SCIP_SET* set, /**< global SCIP settings */
3354  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3355  SCIP_LP* lp, /**< current LP data */
3356  SCIP_ROW* row, /**< LP row */
3357  SCIP_Real val /**< value of coefficient */
3358  )
3359 {
3360  assert(lp != NULL);
3361  assert(!lp->diving);
3362 
3363  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3364 
3365  checkLinks(lp);
3366 
3367  return SCIP_OKAY;
3368 }
3369 
3370 /** deletes existing coefficient from column */
3372  SCIP_COL* col, /**< column to be changed */
3373  BMS_BLKMEM* blkmem, /**< block memory */
3374  SCIP_SET* set, /**< global SCIP settings */
3375  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3376  SCIP_LP* lp, /**< current LP data */
3377  SCIP_ROW* row /**< coefficient to be deleted */
3378  )
3379 {
3380  int pos;
3381 
3382  assert(col != NULL);
3383  assert(col->var != NULL);
3384  assert(lp != NULL);
3385  assert(!lp->diving);
3386  assert(row != NULL);
3387 
3388  /* search the position of the row in the column's row vector */
3389  pos = colSearchCoef(col, row);
3390  if( pos == -1 )
3391  {
3392  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3393  return SCIP_INVALIDDATA;
3394  }
3395  assert(0 <= pos && pos < col->len);
3396  assert(col->rows[pos] == row);
3397 
3398  /* if row knows of the column, remove the column from the row's col vector */
3399  if( col->linkpos[pos] >= 0 )
3400  {
3401  assert(row->cols[col->linkpos[pos]] == col);
3402  assert(row->cols_index[col->linkpos[pos]] == col->index);
3403  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3404  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3405  }
3406 
3407  /* delete the row from the column's row vector */
3408  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3409 
3410  checkLinks(lp);
3411 
3412  return SCIP_OKAY;
3413 }
3414 
3415 /** changes or adds a coefficient to an LP column */
3417  SCIP_COL* col, /**< LP column */
3418  BMS_BLKMEM* blkmem, /**< block memory */
3419  SCIP_SET* set, /**< global SCIP settings */
3420  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3421  SCIP_LP* lp, /**< current LP data */
3422  SCIP_ROW* row, /**< LP row */
3423  SCIP_Real val /**< value of coefficient */
3424  )
3425 {
3426  int pos;
3427 
3428  assert(col != NULL);
3429  assert(lp != NULL);
3430  assert(!lp->diving);
3431  assert(row != NULL);
3432 
3433  /* search the position of the row in the column's row vector */
3434  pos = colSearchCoef(col, row);
3435 
3436  /* check, if row already exists in the column's row vector */
3437  if( pos == -1 )
3438  {
3439  /* add previously not existing coefficient */
3440  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3441  }
3442  else
3443  {
3444  /* modify already existing coefficient */
3445  assert(0 <= pos && pos < col->len);
3446  assert(col->rows[pos] == row);
3447 
3448  /* if row knows of the column, change the corresponding coefficient in the row */
3449  if( col->linkpos[pos] >= 0 )
3450  {
3451  assert(row->cols[col->linkpos[pos]] == col);
3452  assert(row->cols_index[col->linkpos[pos]] == col->index);
3453  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3454  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3455  }
3456 
3457  /* change the coefficient in the column */
3458  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3459  }
3460 
3461  checkLinks(lp);
3462 
3463  return SCIP_OKAY;
3464 }
3465 
3466 /** increases value of an existing or non-existing coefficient in an LP column */
3468  SCIP_COL* col, /**< LP column */
3469  BMS_BLKMEM* blkmem, /**< block memory */
3470  SCIP_SET* set, /**< global SCIP settings */
3471  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3472  SCIP_LP* lp, /**< current LP data */
3473  SCIP_ROW* row, /**< LP row */
3474  SCIP_Real incval /**< value to add to the coefficient */
3475  )
3476 {
3477  int pos;
3478 
3479  assert(col != NULL);
3480  assert(lp != NULL);
3481  assert(!lp->diving);
3482  assert(row != NULL);
3483 
3484  if( SCIPsetIsZero(set, incval) )
3485  return SCIP_OKAY;
3486 
3487  /* search the position of the row in the column's row vector */
3488  pos = colSearchCoef(col, row);
3489 
3490  /* check, if row already exists in the column's row vector */
3491  if( pos == -1 )
3492  {
3493  /* add previously not existing coefficient */
3494  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3495  }
3496  else
3497  {
3498  /* modify already existing coefficient */
3499  assert(0 <= pos && pos < col->len);
3500  assert(col->rows[pos] == row);
3501 
3502  /* if row knows of the column, change the corresponding coefficient in the row */
3503  if( col->linkpos[pos] >= 0 )
3504  {
3505  assert(row->cols[col->linkpos[pos]] == col);
3506  assert(row->cols_index[col->linkpos[pos]] == col->index);
3507  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3508  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3509  }
3510 
3511  /* change the coefficient in the column */
3512  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3513  }
3514 
3515  checkLinks(lp);
3516 
3517  return SCIP_OKAY;
3518 }
3519 
3520 /** insert column in the chgcols list (if not already there) */
3521 static
3523  SCIP_COL* col, /**< LP column to change */
3524  SCIP_SET* set, /**< global SCIP settings */
3525  SCIP_LP* lp /**< current LP data */
3526  )
3527 {
3528  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3529  {
3530  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3531  lp->chgcols[lp->nchgcols] = col;
3532  lp->nchgcols++;
3533  }
3534 
3535  /* mark the current LP unflushed */
3536  lp->flushed = FALSE;
3537 
3538  return SCIP_OKAY;
3539 }
3540 
3541 /** Is the new value reliable or may we have cancellation?
3542  *
3543  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3544  * cancellations which can occur during increasing the oldvalue to the newvalue
3545  */
3546 static
3548  SCIP_SET* set, /**< global SCIP settings */
3549  SCIP_Real newvalue, /**< new value */
3550  SCIP_Real oldvalue /**< old reliable value */
3551  )
3552 {
3553  SCIP_Real quotient;
3554 
3555  assert(set != NULL);
3556  assert(oldvalue < SCIP_INVALID);
3557 
3558  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3559 
3560  return SCIPsetIsZero(set, quotient);
3561 }
3562 
3563 /** update norms of objective function vector */
3564 static
3566  SCIP_LP* lp, /**< current LP data */
3567  SCIP_SET* set, /**< global SCIP settings */
3568  SCIP_Real oldobj, /**< old objective value of variable */
3569  SCIP_Real newobj /**< new objective value of variable */
3570  )
3571 {
3572  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3573  {
3574  if( !lp->objsqrnormunreliable )
3575  {
3576  SCIP_Real oldvalue;
3577 
3578  oldvalue = lp->objsqrnorm;
3579  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3580 
3581  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3582  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3583  lp->objsqrnormunreliable = TRUE;
3584  else
3585  {
3586  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3587 
3588  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3589  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3590 
3591  assert(lp->objsqrnorm >= 0.0);
3592  }
3593  }
3594 
3595  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3596  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3597  }
3598 }
3599 
3600 /** changes objective value of column */
3602  SCIP_COL* col, /**< LP column to change */
3603  SCIP_SET* set, /**< global SCIP settings */
3604  SCIP_LP* lp, /**< current LP data */
3605  SCIP_Real newobj /**< new objective value */
3606  )
3607 {
3608  assert(col != NULL);
3609  assert(col->var != NULL);
3610  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3611  assert(SCIPvarGetCol(col->var) == col);
3612  assert(lp != NULL);
3613 
3614  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3615 
3616  /* only add actual changes */
3617  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3618  {
3619  /* only variables with a real position in the LPI can be inserted */
3620  if( col->lpipos >= 0 )
3621  {
3622  /* insert column in the chgcols list (if not already there) */
3623  SCIP_CALL( insertColChgcols(col, set, lp) );
3624 
3625  /* mark objective value change in the column */
3626  col->objchanged = TRUE;
3627 
3628  assert(lp->nchgcols > 0);
3629  }
3630  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3631  * LP and the LP has to be flushed
3632  */
3633  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3634  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3635  {
3636  /* mark the LP unflushed */
3637  lp->flushed = FALSE;
3638  }
3639  }
3640 
3641  /* store new objective function value */
3642  col->obj = newobj;
3643 
3644  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3645  if( !lp->divingobjchg )
3646  {
3647  SCIP_Real oldobj = col->unchangedobj;
3648 
3649  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3650  col->unchangedobj = newobj;
3651 
3652  /* update the objective function vector norms */
3653  lpUpdateObjNorms(lp, set, oldobj, newobj);
3654  }
3655 
3656  return SCIP_OKAY;
3657 }
3658 
3659 /** changes lower bound of column */
3661  SCIP_COL* col, /**< LP column to change */
3662  SCIP_SET* set, /**< global SCIP settings */
3663  SCIP_LP* lp, /**< current LP data */
3664  SCIP_Real newlb /**< new lower bound value */
3665  )
3666 {
3667  assert(col != NULL);
3668  assert(col->var != NULL);
3669  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3670  assert(SCIPvarGetCol(col->var) == col);
3671  assert(lp != NULL);
3672 
3673  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3674 
3675  /* only add actual changes */
3676  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3677  {
3678  /* only variables with a real position in the LPI can be inserted */
3679  if( col->lpipos >= 0 )
3680  {
3681  /* insert column in the chgcols list (if not already there) */
3682  SCIP_CALL( insertColChgcols(col, set, lp) );
3683 
3684  /* mark bound change in the column */
3685  col->lbchanged = TRUE;
3686 
3687  assert(lp->nchgcols > 0);
3688  }
3689  /* 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
3690  * flushed
3691  */
3692  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3693  {
3694  /* mark the LP unflushed */
3695  lp->flushed = FALSE;
3696  }
3697  }
3698 
3699  col->lb = newlb;
3700 
3701  return SCIP_OKAY;
3702 }
3703 
3704 /** changes upper bound of column */
3706  SCIP_COL* col, /**< LP column to change */
3707  SCIP_SET* set, /**< global SCIP settings */
3708  SCIP_LP* lp, /**< current LP data */
3709  SCIP_Real newub /**< new upper bound value */
3710  )
3711 {
3712  assert(col != NULL);
3713  assert(col->var != NULL);
3714  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3715  assert(SCIPvarGetCol(col->var) == col);
3716  assert(lp != NULL);
3717 
3718  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3719 
3720  /* only add actual changes */
3721  if( !SCIPsetIsEQ(set, col->ub, newub) )
3722  {
3723  /* only variables with a real position in the LPI can be inserted */
3724  if( col->lpipos >= 0 )
3725  {
3726  /* insert column in the chgcols list (if not already there) */
3727  SCIP_CALL( insertColChgcols(col, set, lp) );
3728 
3729  /* mark bound change in the column */
3730  col->ubchanged = TRUE;
3731 
3732  assert(lp->nchgcols > 0);
3733  }
3734  /* 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
3735  * flushed
3736  */
3737  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3738  {
3739  /* mark the LP unflushed */
3740  lp->flushed = FALSE;
3741  }
3742  }
3743 
3744  col->ub = newub;
3745 
3746  return SCIP_OKAY;
3747 }
3748 
3749 /** calculates the reduced costs of a column using the given dual solution vector */
3751  SCIP_COL* col, /**< LP column */
3752  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3753  )
3754 {
3755  SCIP_ROW* row;
3756  SCIP_Real redcost;
3757  int i;
3758 
3759  assert(col != NULL);
3760  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3761  assert(SCIPvarGetCol(col->var) == col);
3762  assert(dualsol != NULL);
3763 
3764  redcost = col->obj;
3765  for( i = 0; i < col->nlprows; ++i )
3766  {
3767  row = col->rows[i];
3768  assert(row != NULL);
3769  assert(row->lppos >= 0);
3770  redcost -= col->vals[i] * dualsol[row->lppos];
3771  }
3772 
3773  if( col->nunlinked > 0 )
3774  {
3775  for( i = col->nlprows; i < col->len; ++i )
3776  {
3777  row = col->rows[i];
3778  assert(row != NULL);
3779  assert(row->lppos == -1 || col->linkpos[i] == -1);
3780  if( row->lppos >= 0 )
3781  redcost -= col->vals[i] * dualsol[row->lppos];
3782  }
3783  }
3784 #ifndef NDEBUG
3785  else
3786  {
3787  for( i = col->nlprows; i < col->len; ++i )
3788  {
3789  row = col->rows[i];
3790  assert(row != NULL);
3791  assert(row->lppos == -1);
3792  assert(col->linkpos[i] >= 0);
3793  }
3794  }
3795 #endif
3796 
3797  return redcost;
3798 }
3799 
3800 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3801 static
3803  SCIP_COL* col /**< LP column */
3804  )
3805 {
3806  SCIP_ROW* row;
3807  SCIP_Real redcost;
3808  int i;
3809 
3810  assert(col != NULL);
3811  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3812  assert(SCIPvarGetCol(col->var) == col);
3813 
3814  redcost = col->obj;
3815  for( i = 0; i < col->nlprows; ++i )
3816  {
3817  row = col->rows[i];
3818  assert(row != NULL);
3819  assert(row->dualsol < SCIP_INVALID);
3820  assert(row->lppos >= 0);
3821  assert(col->linkpos[i] >= 0);
3822  redcost -= col->vals[i] * row->dualsol;
3823  }
3824 
3825  if( col->nunlinked > 0 )
3826  {
3827  for( i = col->nlprows; i < col->len; ++i )
3828  {
3829  row = col->rows[i];
3830  assert(row != NULL);
3831  assert(row->lppos >= 0 || row->dualsol == 0.0);
3832  assert(row->lppos == -1 || col->linkpos[i] == -1);
3833  if( row->lppos >= 0 )
3834  redcost -= col->vals[i] * row->dualsol;
3835  }
3836  }
3837 #ifndef NDEBUG
3838  else
3839  {
3840  for( i = col->nlprows; i < col->len; ++i )
3841  {
3842  row = col->rows[i];
3843  assert(row != NULL);
3844  assert(row->dualsol == 0.0);
3845  assert(row->lppos == -1);
3846  assert(col->linkpos[i] >= 0);
3847  }
3848  }
3849 #endif
3850 
3851  return redcost;
3852 }
3853 
3854 /** gets the reduced costs of a column in last LP or after recalculation */
3856  SCIP_COL* col, /**< LP column */
3857  SCIP_STAT* stat, /**< problem statistics */
3858  SCIP_LP* lp /**< current LP data */
3859  )
3860 {
3861  assert(col != NULL);
3862  assert(stat != NULL);
3863  assert(lp != NULL);
3864  assert(col->validredcostlp <= stat->lpcount);
3865  assert(lp->validsollp == stat->lpcount);
3866 
3867  if( col->validredcostlp < stat->lpcount )
3868  {
3869  col->redcost = colCalcInternalRedcost(col);
3870  col->validredcostlp = stat->lpcount;
3871  }
3872  assert(col->validredcostlp == stat->lpcount);
3873  assert(col->redcost < SCIP_INVALID);
3874 
3875  return col->redcost;
3876 }
3877 
3878 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3880  SCIP_COL* col, /**< LP column */
3881  SCIP_SET* set, /**< global SCIP settings */
3882  SCIP_STAT* stat, /**< problem statistics */
3883  SCIP_LP* lp /**< current LP data */
3884  )
3885 {
3886  assert(col != NULL);
3887  assert(set != NULL);
3888  assert(stat != NULL);
3889  assert(lp != NULL);
3890  assert(lp->validsollp == stat->lpcount);
3891 
3892  /* A column's reduced cost is defined as
3893  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3894  * The activity is equal to the activity of the corresponding row in the dual LP.
3895  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3896  * The sides of the dual row depend on the bounds of the column:
3897  * - lb == ub : dual row is a free row with infinite sides
3898  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3899  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3900  * - lb < ub <= 0: obj <= activity => redcost <= 0
3901  */
3902  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3903  {
3904  /* dual row is free */
3905  return SCIPsetInfinity(set);
3906  }
3907  else
3908  {
3909  SCIP_Real redcost;
3910 
3911  /* calculate reduced costs */
3912  redcost = SCIPcolGetRedcost(col, stat, lp);
3913 
3914  if( !SCIPsetIsNegative(set, col->lb) )
3915  {
3916  /* dual row is activity <= obj <=> redcost >= 0 */
3917  return redcost;
3918  }
3919  else if( SCIPsetIsPositive(set, col->ub) )
3920  {
3921  /* dual row is activity == obj <=> redcost == 0 */
3922  return -REALABS(redcost);
3923  }
3924  else
3925  {
3926  /* dual row is activity >= obj <=> redcost <= 0 */
3927  return -redcost;
3928  }
3929  }
3930 }
3931 
3932 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
3934  SCIP_COL* col, /**< LP column */
3935  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
3936  )
3937 {
3938  SCIP_ROW* row;
3939  SCIP_Real farkas;
3940  int i;
3941 
3942  assert(col != NULL);
3943  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3944  assert(SCIPvarGetCol(col->var) == col);
3945  assert(dualfarkas != NULL);
3946 
3947  farkas = 0.0;
3948  for( i = 0; i < col->nlprows; ++i )
3949  {
3950  row = col->rows[i];
3951  assert(row != NULL);
3952  assert(row->lppos >= 0);
3953  farkas += col->vals[i] * dualfarkas[row->lppos];
3954  }
3955 
3956  if( col->nunlinked > 0 )
3957  {
3958  for( i = col->nlprows; i < col->len; ++i )
3959  {
3960  row = col->rows[i];
3961  assert(row != NULL);
3962  assert(row->lppos == -1 || col->linkpos[i] == -1);
3963  if( row->lppos >= 0 )
3964  farkas += col->vals[i] * dualfarkas[row->lppos];
3965  }
3966  }
3967 #ifndef NDEBUG
3968  else
3969  {
3970  for( i = col->nlprows; i < col->len; ++i )
3971  {
3972  row = col->rows[i];
3973  assert(row != NULL);
3974  assert(row->lppos == -1);
3975  assert(col->linkpos[i] >= 0);
3976  }
3977  }
3978 #endif
3979 
3980  return farkas;
3981 }
3982 
3983 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
3984 static
3986  SCIP_COL* col /**< LP column */
3987  )
3988 {
3989  SCIP_ROW* row;
3990  SCIP_Real farkas;
3991  int i;
3992 
3993  assert(col != NULL);
3994  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3995  assert(SCIPvarGetCol(col->var) == col);
3996 
3997  farkas = 0.0;
3998  for( i = 0; i < col->nlprows; ++i )
3999  {
4000  row = col->rows[i];
4001  assert(row != NULL);
4002  assert(row->dualfarkas < SCIP_INVALID);
4003  assert(row->lppos >= 0);
4004  assert(col->linkpos[i] >= 0);
4005  farkas += col->vals[i] * row->dualfarkas;
4006  }
4007 
4008  if( col->nunlinked > 0 )
4009  {
4010  for( i = col->nlprows; i < col->len; ++i )
4011  {
4012  row = col->rows[i];
4013  assert(row != NULL);
4014  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4015  assert(row->lppos == -1 || col->linkpos[i] == -1);
4016  if( row->lppos >= 0 )
4017  farkas += col->vals[i] * row->dualfarkas;
4018  }
4019  }
4020 #ifndef NDEBUG
4021  else
4022  {
4023  for( i = col->nlprows; i < col->len; ++i )
4024  {
4025  row = col->rows[i];
4026  assert(row != NULL);
4027  assert(row->dualfarkas == 0.0);
4028  assert(row->lppos == -1);
4029  assert(col->linkpos[i] >= 0);
4030  }
4031  }
4032 #endif
4033 
4034  return farkas;
4035 }
4036 
4037 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4039  SCIP_COL* col, /**< LP column */
4040  SCIP_STAT* stat, /**< problem statistics */
4041  SCIP_LP* lp /**< current LP data */
4042  )
4043 {
4044  assert(col != NULL);
4045  assert(stat != NULL);
4046  assert(lp != NULL);
4047  assert(col->validfarkaslp <= stat->lpcount);
4048  assert(lp->validfarkaslp == stat->lpcount);
4049 
4050  if( col->validfarkaslp < stat->lpcount )
4051  {
4053  col->validfarkaslp = stat->lpcount;
4054  }
4055  assert(col->validfarkaslp == stat->lpcount);
4056  assert(col->farkascoef < SCIP_INVALID);
4057 
4058  return col->farkascoef;
4059 }
4060 
4061 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4062  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4063  */
4065  SCIP_COL* col, /**< LP column */
4066  SCIP_STAT* stat, /**< problem statistics */
4067  SCIP_LP* lp /**< current LP data */
4068  )
4069 {
4070  SCIP_Real farkascoef;
4071 
4072  assert(col != NULL);
4073 
4074  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4075 
4076  if( farkascoef > 0.0 )
4077  return col->ub * farkascoef;
4078  else
4079  return col->lb * farkascoef;
4080 }
4081 
4082 /** start strong branching - call before any strong branching */
4084  SCIP_LP* lp /**< LP data */
4085  )
4086 {
4087  assert(lp != NULL);
4088  assert(!lp->strongbranching);
4089 
4090  lp->strongbranching = TRUE;
4091  SCIPdebugMessage("starting strong branching ...\n");
4093 
4094  return SCIP_OKAY;
4095 }
4096 
4097 /** end strong branching - call after any strong branching */
4099  SCIP_LP* lp /**< LP data */
4100  )
4101 {
4102  assert(lp != NULL);
4103  assert(lp->strongbranching);
4104 
4105  lp->strongbranching = FALSE;
4106  SCIPdebugMessage("ending strong branching ...\n");
4108 
4109  return SCIP_OKAY;
4110 }
4111 
4112 /** sets strong branching information for a column variable */
4114  SCIP_COL* col, /**< LP column */
4115  SCIP_SET* set, /**< global SCIP settings */
4116  SCIP_STAT* stat, /**< dynamic problem statistics */
4117  SCIP_LP* lp, /**< LP data */
4118  SCIP_Real lpobjval, /**< objective value of the current LP */
4119  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4120  SCIP_Real sbdown, /**< dual bound after branching column down */
4121  SCIP_Real sbup, /**< dual bound after branching column up */
4122  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4123  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4124  SCIP_Longint iter, /**< total number of strong branching iterations */
4125  int itlim /**< iteration limit applied to the strong branching call */
4126  )
4127 {
4128  assert(col != NULL);
4129  assert(col->var != NULL);
4130  assert(SCIPcolIsIntegral(col));
4131  assert(SCIPvarIsIntegral(col->var));
4132  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4133  assert(SCIPvarGetCol(col->var) == col);
4134  assert(col->lpipos >= 0);
4135  assert(col->lppos >= 0);
4136  assert(set != NULL);
4137  assert(stat != NULL);
4138  assert(lp != NULL);
4139  assert(lp->strongbranchprobing);
4140  assert(col->lppos < lp->ncols);
4141  assert(lp->cols[col->lppos] == col);
4142  assert(itlim >= 1);
4143 
4144  col->sblpobjval = lpobjval;
4145  col->sbsolval = primsol;
4146  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4147  col->sbnode = stat->nnodes;
4148 
4149  col->sbitlim = itlim;
4150  col->nsbcalls++;
4151 
4152  col->sbdown = MIN(sbdown, lp->cutoffbound);
4153  col->sbup = MIN(sbup, lp->cutoffbound);
4154  col->sbdownvalid = sbdownvalid;
4155  col->sbupvalid = sbupvalid;
4156 
4157  SCIPstatIncrement(stat, set, nstrongbranchs);
4158  SCIPstatAdd(stat, set, nsblpiterations, iter);
4159  if( stat->nnodes == 1 )
4160  {
4161  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4162  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4163  }
4164 }
4165 
4166 /** invalidates strong branching information for a column variable */
4168  SCIP_COL* col, /**< LP column */
4169  SCIP_SET* set, /**< global SCIP settings */
4170  SCIP_STAT* stat, /**< dynamic problem statistics */
4171  SCIP_LP* lp /**< LP data */
4172  )
4173 {
4174  assert(col != NULL);
4175  assert(col->var != NULL);
4176  assert(SCIPcolIsIntegral(col));
4177  assert(SCIPvarIsIntegral(col->var));
4178  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4179  assert(SCIPvarGetCol(col->var) == col);
4180  assert(col->lpipos >= 0);
4181  assert(col->lppos >= 0);
4182  assert(set != NULL);
4183  assert(stat != NULL);
4184  assert(lp != NULL);
4185  assert(lp->strongbranchprobing);
4186  assert(col->lppos < lp->ncols);
4187  assert(lp->cols[col->lppos] == col);
4188 
4189  col->sbdown = SCIP_INVALID;
4190  col->sbup = SCIP_INVALID;
4191  col->sbdownvalid = FALSE;
4192  col->sbupvalid = FALSE;
4193  col->validsblp = -1;
4194  col->sbsolval = SCIP_INVALID;
4195  col->sblpobjval = SCIP_INVALID;
4196  col->sbnode = -1;
4197  col->sbitlim = -1;
4198 }
4199 
4200 
4201 /** gets strong branching information on a column variable */
4203  SCIP_COL* col, /**< LP column */
4204  SCIP_Bool integral, /**< should integral strong branching be performed? */
4205  SCIP_SET* set, /**< global SCIP settings */
4206  SCIP_STAT* stat, /**< dynamic problem statistics */
4207  SCIP_PROB* prob, /**< problem data */
4208  SCIP_LP* lp, /**< LP data */
4209  int itlim, /**< iteration limit for strong branchings */
4210  SCIP_Real* down, /**< stores dual bound after branching column down */
4211  SCIP_Real* up, /**< stores dual bound after branching column up */
4212  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4213  * otherwise, it can only be used as an estimate value */
4214  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4215  * otherwise, it can only be used as an estimate value */
4216  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4217  )
4218 {
4219  assert(col != NULL);
4220  assert(col->var != NULL);
4221  assert(SCIPcolIsIntegral(col));
4222  assert(SCIPvarIsIntegral(col->var));
4223  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4224  assert(SCIPvarGetCol(col->var) == col);
4225  assert(col->primsol < SCIP_INVALID);
4226  assert(col->lpipos >= 0);
4227  assert(col->lppos >= 0);
4228  assert(set != NULL);
4229  assert(stat != NULL);
4230  assert(lp != NULL);
4231  assert(lp->flushed);
4232  assert(lp->solved);
4233  assert(lp->strongbranching);
4234  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4235  assert(lp->validsollp == stat->lpcount);
4236  assert(col->lppos < lp->ncols);
4237  assert(lp->cols[col->lppos] == col);
4238  assert(itlim >= 1);
4239  /* assert(down != NULL);
4240  * assert(up != NULL); temporary hack for cloud branching
4241  */
4242  assert(lperror != NULL);
4243 
4244  *lperror = FALSE;
4245 
4246  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4247  {
4248  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4249  col->sbsolval = col->primsol;
4250  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4251  col->sbnode = stat->nnodes;
4252  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4253 
4254  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4255  if( lp->looseobjvalinf > 0 )
4256  {
4257  col->sbdown = -SCIPsetInfinity(set);
4258  col->sbup = -SCIPsetInfinity(set);
4259  col->sbdownvalid = FALSE;
4260  col->sbupvalid = FALSE;
4261  }
4262  else
4263  {
4264  SCIP_RETCODE retcode;
4265  SCIP_Real sbdown;
4266  SCIP_Real sbup;
4267  SCIP_Bool sbdownvalid;
4268  SCIP_Bool sbupvalid;
4269  int iter;
4270 
4271  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4272  SCIPvarGetName(col->var), col->primsol, itlim);
4273 
4274  /* start timing */
4275  SCIPclockStart(stat->strongbranchtime, set);
4276 
4277  /* call LPI strong branching */
4278  col->sbitlim = itlim;
4279  col->nsbcalls++;
4280 
4281  sbdown = lp->lpobjval;
4282  sbup = lp->lpobjval;
4283 
4284  if( integral )
4285  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4286  else
4287  {
4288  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4289  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4290  }
4291 
4292 
4293  /* check return code for errors */
4294  if( retcode == SCIP_LPERROR )
4295  {
4296  *lperror = TRUE;
4297  col->sbdown = SCIP_INVALID;
4298  col->sbup = SCIP_INVALID;
4299  col->sbdownvalid = FALSE;
4300  col->sbupvalid = FALSE;
4301  col->validsblp = -1;
4302  col->sbsolval = SCIP_INVALID;
4303  col->sblpobjval = SCIP_INVALID;
4304  col->sbnode = -1;
4305  }
4306  else
4307  {
4308  SCIP_Real looseobjval;
4309 
4310  *lperror = FALSE;
4311  SCIP_CALL( retcode );
4312 
4313  looseobjval = getFiniteLooseObjval(lp, set, prob);
4314  col->sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4315  col->sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4316 
4317  col->sbdownvalid = sbdownvalid;
4318  col->sbupvalid = sbupvalid;
4319 
4320  /* update strong branching statistics */
4321  if( iter == -1 )
4322  {
4323  /* calculate average iteration number */
4324  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4325  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4326  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4327  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4328  : 0;
4329  if( iter/2 >= itlim )
4330  iter = 2*itlim;
4331  }
4332  SCIPstatIncrement(stat, set, nstrongbranchs);
4333  SCIPstatAdd(stat, set, nsblpiterations, iter);
4334  if( stat->nnodes == 1 )
4335  {
4336  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4337  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4338  }
4339  }
4340 
4341  /* stop timing */
4342  SCIPclockStop(stat->strongbranchtime, set);
4343  }
4344  }
4345  assert(*lperror || col->sbdown < SCIP_INVALID);
4346  assert(*lperror || col->sbup < SCIP_INVALID);
4347 
4348  if( down != NULL)
4349  *down = col->sbdown;
4350  if( up != NULL )
4351  *up = col->sbup;
4352  if( downvalid != NULL )
4353  *downvalid = col->sbdownvalid;
4354  if( upvalid != NULL )
4355  *upvalid = col->sbupvalid;
4356 
4357  return SCIP_OKAY;
4358 }
4359 
4360 /** gets strong branching information on column variables */
4362  SCIP_COL** cols, /**< LP columns */
4363  int ncols, /**< number of columns */
4364  SCIP_Bool integral, /**< should integral strong branching be performed? */
4365  SCIP_SET* set, /**< global SCIP settings */
4366  SCIP_STAT* stat, /**< dynamic problem statistics */
4367  SCIP_PROB* prob, /**< problem data */
4368  SCIP_LP* lp, /**< LP data */
4369  int itlim, /**< iteration limit for strong branchings */
4370  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4371  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4372  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4373  * otherwise, they can only be used as an estimate value */
4374  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4375  * otherwise, they can only be used as an estimate value */
4376  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4377  )
4378 {
4379  SCIP_RETCODE retcode;
4380  SCIP_Real* sbdown;
4381  SCIP_Real* sbup;
4382  SCIP_Bool* sbdownvalid;
4383  SCIP_Bool* sbupvalid;
4384  SCIP_Real* primsols;
4385  SCIP_COL** subcols;
4386  int* lpipos;
4387  int* subidx;
4388  int nsubcols;
4389  int iter;
4390  int j;
4391 
4392  assert(cols != NULL);
4393  assert(set != NULL);
4394  assert(stat != NULL);
4395  assert(lp != NULL);
4396  assert(lp->flushed);
4397  assert(lp->solved);
4398  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4399  assert(lp->validsollp == stat->lpcount);
4400  assert(itlim >= 1);
4401  assert(down != NULL);
4402  assert(up != NULL);
4403  assert(lperror != NULL);
4404 
4405  *lperror = FALSE;
4406 
4407  if ( ncols <= 0 )
4408  return SCIP_OKAY;
4409 
4410  /* start timing */
4411  SCIPclockStart(stat->strongbranchtime, set);
4412 
4413  /* initialize storage */
4414  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4415  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4416  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4417  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4418  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4419  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4420  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4421  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4422 
4423  nsubcols = 0;
4424  for( j = 0; j < ncols; ++j )
4425  {
4426  SCIP_COL* col;
4427  col = cols[j];
4428 
4429  assert(col->lppos < lp->ncols);
4430  assert(lp->cols[col->lppos] == col);
4431  assert(SCIPcolIsIntegral(col));
4432  assert(SCIPvarIsIntegral(col->var));
4433  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4434  assert(SCIPvarGetCol(col->var) == col);
4435  assert(col->primsol < SCIP_INVALID);
4436  assert(col->lpipos >= 0);
4437  assert(col->lppos >= 0);
4438 
4439  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4440  {
4441  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4442  col->sbsolval = col->primsol;
4443  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4444  col->sbnode = stat->nnodes;
4445  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4446 
4447  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4448  if( lp->looseobjvalinf > 0 )
4449  {
4450  /* directly set up column and result vectors*/
4451  col->sbdown = -SCIPsetInfinity(set);
4452  col->sbup = -SCIPsetInfinity(set);
4453  col->sbdownvalid = FALSE;
4454  col->sbupvalid = FALSE;
4455  down[j] = col->sbdown;
4456  up[j] = col->sbup;
4457  if( downvalid != NULL )
4458  downvalid[j] = col->sbdownvalid;
4459  if( upvalid != NULL )
4460  upvalid[j] = col->sbupvalid;
4461  }
4462  else
4463  {
4464  col->sbitlim = itlim;
4465  col->nsbcalls++;
4466 
4467  lpipos[nsubcols] = col->lpipos;
4468  primsols[nsubcols] = col->primsol;
4469  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4470  subidx[nsubcols] = j;
4471  subcols[nsubcols++] = col;
4472  }
4473  }
4474  else
4475  {
4476  /* directly set up resulting values (use stored values) */
4477  down[j] = col->sbdown;
4478  up[j] = col->sbup;
4479  if( downvalid != NULL )
4480  downvalid[j] = col->sbdownvalid;
4481  if( upvalid != NULL )
4482  upvalid[j] = col->sbupvalid;
4483  }
4484  }
4485 
4486  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4487 
4488  /* call LPI strong branching */
4489  if ( integral )
4490  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4491  else
4492  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4493 
4494  /* check return code for errors */
4495  if( retcode == SCIP_LPERROR )
4496  {
4497  *lperror = TRUE;
4498 
4499  for( j = 0; j < nsubcols; ++j )
4500  {
4501  SCIP_COL* col;
4502  int idx;
4503 
4504  col = subcols[j];
4505  idx = subidx[j];
4506 
4507  col->sbdown = SCIP_INVALID;
4508  col->sbup = SCIP_INVALID;
4509  col->sbdownvalid = FALSE;
4510  col->sbupvalid = FALSE;
4511  col->validsblp = -1;
4512  col->sbsolval = SCIP_INVALID;
4513  col->sblpobjval = SCIP_INVALID;
4514  col->sbnode = -1;
4515 
4516  down[idx] = col->sbdown;
4517  up[idx] = col->sbup;
4518  if( downvalid != NULL )
4519  downvalid[idx] = col->sbdownvalid;
4520  if( upvalid != NULL )
4521  upvalid[idx] = col->sbupvalid;
4522  }
4523  }
4524  else
4525  {
4526  SCIP_Real looseobjval;
4527 
4528  *lperror = FALSE;
4529  SCIP_CALL( retcode );
4530 
4531  looseobjval = getFiniteLooseObjval(lp, set, prob);
4532 
4533  for( j = 0; j < nsubcols; ++j )
4534  {
4535  SCIP_COL* col;
4536  int idx;
4537 
4538  col = subcols[j];
4539  idx = subidx[j];
4540 
4541  assert( col->sbdown < SCIP_INVALID);
4542  assert( col->sbup < SCIP_INVALID);
4543 
4544  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4545  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4546  col->sbdownvalid = sbdownvalid[j];
4547  col->sbupvalid = sbupvalid[j];
4548 
4549  down[idx] = col->sbdown;
4550  up[idx] = col->sbup;
4551  if( downvalid != NULL )
4552  downvalid[idx] = col->sbdownvalid;
4553  if( upvalid != NULL )
4554  upvalid[idx] = col->sbupvalid;
4555  }
4556 
4557  /* update strong branching statistics */
4558  if( iter == -1 )
4559  {
4560  /* calculate average iteration number */
4561  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4562  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4563  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4564  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4565  : 0;
4566  if( iter/2 >= itlim )
4567  iter = 2*itlim;
4568  }
4569  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4570  SCIPstatAdd(stat, set, nsblpiterations, iter);
4571  if( stat->nnodes == 1 )
4572  {
4573  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4574  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4575  }
4576  }
4577 
4578  SCIPsetFreeBufferArray(set, &sbupvalid);
4579  SCIPsetFreeBufferArray(set, &sbdownvalid);
4580  SCIPsetFreeBufferArray(set, &sbup);
4581  SCIPsetFreeBufferArray(set, &sbdown);
4582  SCIPsetFreeBufferArray(set, &primsols);
4583  SCIPsetFreeBufferArray(set, &lpipos);
4584  SCIPsetFreeBufferArray(set, &subidx);
4585  SCIPsetFreeBufferArray(set, &subcols);
4586 
4587  /* stop timing */
4588  SCIPclockStop(stat->strongbranchtime, set);
4589 
4590  return SCIP_OKAY;
4591 }
4592 
4593 /** gets last strong branching information available for a column variable;
4594  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4595  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4596  */
4598  SCIP_COL* col, /**< LP column */
4599  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4600  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4601  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4602  * otherwise, it can only be used as an estimate value */
4603  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4604  * otherwise, it can only be used as an estimate value */
4605  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4606  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4607  )
4608 {
4609  assert(col != NULL);
4610 
4611  if( down != NULL )
4612  *down = col->sbdown;
4613  if( up != NULL )
4614  *up = col->sbup;
4615  if( downvalid != NULL )
4616  *downvalid = col->sbdownvalid;
4617  if( upvalid != NULL )
4618  *upvalid = col->sbupvalid;
4619  if( solval != NULL )
4620  *solval = col->sbsolval;
4621  if( lpobjval != NULL )
4622  *lpobjval = col->sblpobjval;
4623 }
4624 
4625 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4626  * the LP where the strong branching on this column was applied;
4627  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4628  */
4630  SCIP_COL* col, /**< LP column */
4631  SCIP_STAT* stat /**< dynamic problem statistics */
4632  )
4633 {
4634  assert(col != NULL);
4635  assert(stat != NULL);
4636 
4637  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->lpcount - stat->nsbdivinglps - col->validsblp);
4638 }
4639 
4640 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4642  SCIP_COL* col, /**< LP column */
4643  SCIP_STAT* stat /**< problem statistics */
4644  )
4645 {
4646  assert(col != NULL);
4647  assert(stat != NULL);
4648  assert(stat->nnodes > 0);
4649 
4650  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4651  col->obsoletenode = stat->nnodes;
4652 }
4653 
4654 
4655 /*
4656  * Row methods
4657  */
4658 
4659 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4660 static
4662  SCIP_ROW* row, /**< LP row */
4663  SCIP_SET* set /**< global SCIP settings */
4664  )
4665 {
4666  int i;
4667 
4668  assert(row != NULL);
4669  assert(set != NULL);
4670 
4671  row->sqrnorm = 0.0;
4672  row->sumnorm = 0.0;
4673  row->objprod = 0.0;
4674  row->maxval = 0.0;
4675  row->nummaxval = 1;
4676  row->minval = SCIPsetInfinity(set);
4677  row->numminval = 1;
4678  row->minidx = INT_MAX;
4679  row->maxidx = INT_MIN;
4680  row->validminmaxidx = TRUE;
4681  row->lpcolssorted = TRUE;
4682  row->nonlpcolssorted = TRUE;
4683 
4684  /* check, if row is sorted
4685  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4686  */
4687  for( i = 0; i < row->nlpcols; ++i )
4688  {
4689  assert(row->cols[i] != NULL);
4690  assert(!SCIPsetIsZero(set, row->vals[i]));
4691  assert(row->cols[i]->lppos >= 0);
4692  assert(row->linkpos[i] >= 0);
4693  assert(row->cols[i]->index == row->cols_index[i]);
4694 
4695  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4696  if( i > 0 )
4697  {
4698  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4699  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4700  }
4701  }
4702  for( i = row->nlpcols; i < row->len; ++i )
4703  {
4704  assert(row->cols[i] != NULL);
4705  assert(!SCIPsetIsZero(set, row->vals[i]));
4706  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4707  assert(row->cols[i]->index == row->cols_index[i]);
4708 
4709  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4710  if( i > row->nlpcols )
4711  {
4712  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4713  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4714  }
4715  }
4716 }
4717 
4718 /** calculates min/maxval and min/maxidx from scratch */
4719 static
4721  SCIP_ROW* row, /**< LP row */
4722  SCIP_SET* set /**< global SCIP settings */
4723  )
4724 {
4725  SCIP_COL* col;
4726  SCIP_Real absval;
4727  int i;
4728 
4729  assert(row != NULL);
4730  assert(set != NULL);
4731 
4732  row->maxval = 0.0;
4733  row->nummaxval = 1;
4734  row->numintcols = 0;
4735  row->minval = SCIPsetInfinity(set);
4736  row->numminval = 1;
4737  row->minidx = INT_MAX;
4738  row->maxidx = INT_MIN;
4739  row->validminmaxidx = TRUE;
4740 
4741  /* calculate maxval, minval, minidx, and maxidx */
4742  for( i = 0; i < row->len; ++i )
4743  {
4744  col = row->cols[i];
4745  assert(col != NULL);
4746  assert(!SCIPsetIsZero(set, row->vals[i]));
4747 
4748  absval = REALABS(row->vals[i]);
4749  assert(!SCIPsetIsZero(set, absval));
4750 
4751  /* update min/maxidx */
4752  row->minidx = MIN(row->minidx, col->index);
4753  row->maxidx = MAX(row->maxidx, col->index);
4754  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4755 
4756  /* update maximal and minimal non-zero value */
4757  if( row->nummaxval > 0 )
4758  {
4759  if( SCIPsetIsGT(set, absval, row->maxval) )
4760  {
4761  row->maxval = absval;
4762  row->nummaxval = 1;
4763  }
4764  else if( SCIPsetIsGE(set, absval, row->maxval) )
4765  {
4766  /* make sure the maxval is always exactly the same */
4767  row->maxval = MAX(absval, row->maxval);
4768  row->nummaxval++;
4769  }
4770  }
4771  if( row->numminval > 0 )
4772  {
4773  if( SCIPsetIsLT(set, absval, row->minval) )
4774  {
4775  row->minval = absval;
4776  row->numminval = 1;
4777  }
4778  else if( SCIPsetIsLE(set, absval, row->minval) )
4779  {
4780  /* make sure the minval is always exactly the same */
4781  row->minval = MIN(absval, row->minval);
4782  row->numminval++;
4783  }
4784  }
4785  }
4786 }
4787 
4788 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4789 static
4791  SCIP_Real val, /**< value that should be scaled to an integral value */
4792  SCIP_Real scalar, /**< scalar that should be tried */
4793  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4794  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4795  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4796  )
4797 {
4798  SCIP_Real sval;
4799  SCIP_Real downval;
4800  SCIP_Real upval;
4801 
4802  assert(mindelta <= 0.0);
4803  assert(maxdelta >= 0.0);
4804 
4805  sval = val * scalar;
4806  downval = floor(sval);
4807  upval = ceil(sval);
4808 
4809  if( SCIPrelDiff(sval, downval) <= maxdelta )
4810  {
4811  if( intval != NULL )
4812  *intval = downval;
4813  return TRUE;
4814  }
4815  else if( SCIPrelDiff(sval, upval) >= mindelta )
4816  {
4817  if( intval != NULL )
4818  *intval = upval;
4819  return TRUE;
4820  }
4821 
4822  return FALSE;
4823 }
4824 
4825 /** scales row with given factor, and rounds coefficients to integers if close enough;
4826  * the constant is automatically moved to the sides;
4827  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4828  */
4829 static
4831  SCIP_ROW* row, /**< LP row */
4832  BMS_BLKMEM* blkmem, /**< block memory */
4833  SCIP_SET* set, /**< global SCIP settings */
4834  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4835  SCIP_STAT* stat, /**< problem statistics */
4836  SCIP_LP* lp, /**< current LP data */
4837  SCIP_Real scaleval, /**< value to scale row with */
4838  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4839  * if they are close to integral values? */
4840  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4841  * upto which the integral is used instead of the scaled real coefficient */
4842  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4843  * upto which the integral is used instead of the scaled real coefficient */
4844  )
4845 {
4846  SCIP_COL* col;
4847  SCIP_Real val;
4848  SCIP_Real newval;
4849  SCIP_Real intval;
4850  SCIP_Real mindelta;
4851  SCIP_Real maxdelta;
4852  SCIP_Real lb;
4853  SCIP_Real ub;
4854  SCIP_Bool mindeltainf;
4855  SCIP_Bool maxdeltainf;
4856  int oldlen;
4857  int c;
4858 
4859  assert(row != NULL);
4860  assert(row->len == 0 || row->cols != NULL);
4861  assert(row->len == 0 || row->vals != NULL);
4862  assert(SCIPsetIsPositive(set, scaleval));
4863  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4864  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4865 
4866  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4867 
4868  mindelta = 0.0;
4869  maxdelta = 0.0;
4870  mindeltainf = FALSE;
4871  maxdeltainf = FALSE;
4872  oldlen = row->len;
4873 
4874  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4875  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4876  * this rounding can lead to
4877  */
4878  row->integral = TRUE;
4879 
4880  c = 0;
4881  while( c < row->len )
4882  {
4883  col = row->cols[c];
4884  val = row->vals[c];
4885  assert(!SCIPsetIsZero(set, val));
4886 
4887  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4888  if( row->local )
4889  {
4890  lb = col->lb;
4891  ub = col->ub;
4892  }
4893  else
4894  {
4895  lb = SCIPvarGetLbGlobal(col->var);
4896  ub = SCIPvarGetUbGlobal(col->var);
4897  }
4898 
4899  /* calculate scaled coefficient */
4900  newval = val * scaleval;
4901  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
4902  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
4903  {
4904  if( !SCIPsetIsEQ(set, intval, newval) )
4905  {
4906  if( intval < newval )
4907  {
4908  mindelta += (intval - newval)*ub;
4909  maxdelta += (intval - newval)*lb;
4910  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
4911  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
4912  }
4913  else
4914  {
4915  mindelta += (intval - newval)*lb;
4916  maxdelta += (intval - newval)*ub;
4917  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
4918  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
4919  }
4920  }
4921  newval = intval;
4922  }
4923 
4924  if( !SCIPsetIsEQ(set, val, newval) )
4925  {
4926  /* if column knows of the row, change the corresponding coefficient in the column */
4927  if( row->linkpos[c] >= 0 )
4928  {
4929  assert(col->rows[row->linkpos[c]] == row);
4930  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
4931  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
4932  }
4933 
4934  /* change the coefficient in the row, and update the norms and integrality status */
4935  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
4936 
4937  /* current coefficient has been deleted from the row because it was almost zero */
4938  if( oldlen != row->len )
4939  {
4940  assert(row->len == oldlen - 1);
4941  c--;
4942  oldlen = row->len;
4943  }
4944 
4945  }
4946  else
4947  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
4948 
4949  ++c;
4950  }
4951 
4952  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
4953  * to not destroy feasibility due to rounding
4954  */
4955  /**@todo ensure that returned cut does not have infinite lhs and rhs */
4956  if( !SCIPsetIsInfinity(set, -row->lhs) )
4957  {
4958  if( mindeltainf )
4959  newval = -SCIPsetInfinity(set);
4960  else
4961  {
4962  newval = (row->lhs - row->constant) * scaleval + mindelta;
4963  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4964  newval = SCIPsetSumCeil(set, newval);
4965  }
4966  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
4967  }
4968  if( !SCIPsetIsInfinity(set, row->rhs) )
4969  {
4970  if( maxdeltainf )
4971  newval = SCIPsetInfinity(set);
4972  else
4973  {
4974  newval = (row->rhs - row->constant) * scaleval + maxdelta;
4975  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4976  newval = SCIPsetSumFloor(set, newval);
4977  }
4978  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
4979  }
4980 
4981  /* clear the row constant */
4982  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
4983 
4984  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
4985  debugRowPrint(set, row);
4986 
4987 #ifdef SCIP_DEBUG
4988  /* check integrality status of row */
4989  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
4990  {}
4991  assert(row->integral == (c == row->len));
4992 #endif
4993 
4994  /* invalid the activity */
4995  row->validactivitylp = -1;
4996 
4997  return SCIP_OKAY;
4998 }
4999 
5000 /** creates and captures an LP row */
5002  SCIP_ROW** row, /**< pointer to LP row data */
5003  BMS_BLKMEM* blkmem, /**< block memory */
5004  SCIP_SET* set, /**< global SCIP settings */
5005  SCIP_STAT* stat, /**< problem statistics */
5006  SCIP_LP* lp, /**< current LP data */
5007  const char* name, /**< name of row */
5008  int len, /**< number of nonzeros in the row */
5009  SCIP_COL** cols, /**< array with columns of row entries */
5010  SCIP_Real* vals, /**< array with coefficients of row entries */
5011  SCIP_Real lhs, /**< left hand side of row */
5012  SCIP_Real rhs, /**< right hand side of row */
5013  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5014  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5015  SCIP_Bool local, /**< is row only valid locally? */
5016  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5017  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5018  )
5019 {
5020  assert(row != NULL);
5021  assert(blkmem != NULL);
5022  assert(stat != NULL);
5023  assert(len >= 0);
5024  assert(len == 0 || (cols != NULL && vals != NULL));
5025  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5026  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5027  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5028  */
5029  assert(lhs <= rhs);
5030 
5031  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5032 
5033  (*row)->integral = TRUE;
5034  if( len > 0 )
5035  {
5036  SCIP_VAR* var;
5037  int i;
5038 
5039  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5040  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5041  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5042  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5043 
5044  for( i = 0; i < len; ++i )
5045  {
5046  assert(cols[i] != NULL);
5047  assert(!SCIPsetIsZero(set, vals[i]));
5048 
5049  var = cols[i]->var;
5050  (*row)->cols_index[i] = cols[i]->index;
5051  (*row)->linkpos[i] = -1;
5052  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5053  {
5054  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5055  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5056  }
5057  else
5058  {
5059  (*row)->integral = FALSE;
5060  }
5061  }
5062  }
5063  else
5064  {
5065  (*row)->cols = NULL;
5066  (*row)->cols_index = NULL;
5067  (*row)->vals = NULL;
5068  (*row)->linkpos = NULL;
5069  }
5070 
5071  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5072  (*row)->constant = 0.0;
5073  (*row)->lhs = lhs;
5074  (*row)->rhs = rhs;
5075  (*row)->flushedlhs = -SCIPsetInfinity(set);
5076  (*row)->flushedrhs = SCIPsetInfinity(set);
5077  (*row)->sqrnorm = 0.0;
5078  (*row)->sumnorm = 0.0;
5079  (*row)->objprod = 0.0;
5080  (*row)->maxval = 0.0;
5081  (*row)->minval = SCIPsetInfinity(set);
5082  (*row)->dualsol = 0.0;
5083  (*row)->activity = SCIP_INVALID;
5084  (*row)->dualfarkas = 0.0;
5085  (*row)->pseudoactivity = SCIP_INVALID;
5086  (*row)->minactivity = SCIP_INVALID;
5087  (*row)->maxactivity = SCIP_INVALID;
5088  (*row)->origin = origin;
5089  (*row)->eventfilter = NULL;
5090  (*row)->index = stat->nrowidx;
5091  SCIPstatIncrement(stat, set, nrowidx);
5092  (*row)->size = len;
5093  (*row)->len = len;
5094  (*row)->nlpcols = 0;
5095  (*row)->nunlinked = len;
5096  (*row)->nuses = 0;
5097  (*row)->lppos = -1;
5098  (*row)->lpipos = -1;
5099  (*row)->lpdepth = -1;
5100  (*row)->minidx = INT_MAX;
5101  (*row)->maxidx = INT_MIN;
5102  (*row)->nummaxval = 0;
5103  (*row)->numminval = 0;
5104  (*row)->numintcols = -1;
5105  (*row)->validactivitylp = -1;
5106  (*row)->validpsactivitydomchg = -1;
5107  (*row)->validactivitybdsdomchg = -1;
5108  (*row)->nlpsaftercreation = 0L;
5109  (*row)->activeinlpcounter = 0L;
5110  (*row)->age = 0;
5111  (*row)->rank = 0;
5112  (*row)->obsoletenode = -1;
5113  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5114  (*row)->lpcolssorted = TRUE;
5115  (*row)->nonlpcolssorted = (len <= 1);
5116  (*row)->delaysort = FALSE;
5117  (*row)->validminmaxidx = FALSE;
5118  (*row)->lhschanged = FALSE;
5119  (*row)->rhschanged = FALSE;
5120  (*row)->coefchanged = FALSE;
5121  (*row)->local = local;
5122  (*row)->modifiable = modifiable;
5123  (*row)->nlocks = 0;
5124  (*row)->origintype = origintype; /*lint !e641*/
5125  (*row)->removable = removable;
5126  (*row)->inglobalcutpool = FALSE;
5127  (*row)->storedsolvals = NULL;
5128 
5129  /* calculate row norms and min/maxidx, and check if row is sorted */
5130  rowCalcNorms(*row, set);
5131 
5132  /* capture the row */
5133  SCIProwCapture(*row);
5134 
5135  /* create event filter */
5136  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5137 
5138  return SCIP_OKAY;
5139 } /*lint !e715*/
5140 
5141 /** frees an LP row */
5143  SCIP_ROW** row, /**< pointer to LP row */
5144  BMS_BLKMEM* blkmem, /**< block memory */
5145  SCIP_SET* set, /**< global SCIP settings */
5146  SCIP_LP* lp /**< current LP data */
5147  )
5148 {
5149  assert(blkmem != NULL);
5150  assert(row != NULL);
5151  assert(*row != NULL);
5152  assert((*row)->nuses == 0);
5153  assert((*row)->lppos == -1);
5154  assert((*row)->eventfilter != NULL);
5155 
5156  /* remove column indices from corresponding rows */
5157  SCIP_CALL( rowUnlink(*row, set, lp) );
5158 
5159  /* free event filter */
5160  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5161 
5162  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5163  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5164  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5165  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5166  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5167  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5168  BMSfreeBlockMemory(blkmem, row);
5169 
5170  return SCIP_OKAY;
5171 }
5172 
5173 /** output row to file stream */
5175  SCIP_ROW* row, /**< LP row */
5176  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5177  FILE* file /**< output file (or NULL for standard output) */
5178  )
5179 {
5180  int i;
5181 
5182  assert(row != NULL);
5183 
5184  /* print row name */
5185  if( row->name != NULL && row->name[0] != '\0' )
5186  {
5187  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5188  }
5189 
5190  /* print left hand side */
5191  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5192 
5193  /* print coefficients */
5194  if( row->len == 0 )
5195  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5196  for( i = 0; i < row->len; ++i )
5197  {
5198  assert(row->cols[i] != NULL);
5199  assert(row->cols[i]->var != NULL);
5200  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5201  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5202  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5203  }
5204 
5205  /* print constant */
5206  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5207  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5208 
5209  /* print right hand side */
5210  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5211 }
5212 
5213 /** increases usage counter of LP row */
5215  SCIP_ROW* row /**< LP row */
5216  )
5217 {
5218  assert(row != NULL);
5219  assert(row->nuses >= 0);
5220  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5221 
5222  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5223  row->nuses++;
5224 }
5225 
5226 /** decreases usage counter of LP row, and frees memory if necessary */
5228  SCIP_ROW** row, /**< pointer to LP row */
5229  BMS_BLKMEM* blkmem, /**< block memory */
5230  SCIP_SET* set, /**< global SCIP settings */
5231  SCIP_LP* lp /**< current LP data */
5232  )
5233 {
5234  assert(blkmem != NULL);
5235  assert(row != NULL);
5236  assert(*row != NULL);
5237  assert((*row)->nuses >= 1);
5238  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5239 
5240  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5241  (*row)->nuses--;
5242  if( (*row)->nuses == 0 )
5243  {
5244  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5245  }
5246 
5247  *row = NULL;
5248 
5249  return SCIP_OKAY;
5250 }
5251 
5252 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5254  SCIP_ROW* row /**< LP row */
5255  )
5256 {
5257  assert(row != NULL);
5258 
5259  /* check, if row is modifiable */
5260  if( !row->modifiable )
5261  {
5262  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5263  row->nlocks++;
5264  }
5265 }
5266 
5267 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5269  SCIP_ROW* row /**< LP row */
5270  )
5271 {
5272  assert(row != NULL);
5273 
5274  /* check, if row is modifiable */
5275  if( !row->modifiable )
5276  {
5277  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5278  assert(row->nlocks > 0);
5279  row->nlocks--;
5280  }
5281 }
5282 
5283 /** adds a previously non existing coefficient to an LP row */
5285  SCIP_ROW* row, /**< LP row */
5286  BMS_BLKMEM* blkmem, /**< block memory */
5287  SCIP_SET* set, /**< global SCIP settings */
5288  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5289  SCIP_LP* lp, /**< current LP data */
5290  SCIP_COL* col, /**< LP column */
5291  SCIP_Real val /**< value of coefficient */
5292  )
5293 {
5294  assert(lp != NULL);
5295  assert(!lp->diving || row->lppos == -1);
5296 
5297  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5298 
5299  checkLinks(lp);
5300 
5301  return SCIP_OKAY;
5302 }
5303 
5304 /** deletes coefficient from row */
5306  SCIP_ROW* row, /**< row to be changed */
5307  BMS_BLKMEM* blkmem, /**< block memory */
5308  SCIP_SET* set, /**< global SCIP settings */
5309  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5310  SCIP_LP* lp, /**< current LP data */
5311  SCIP_COL* col /**< coefficient to be deleted */
5312  )
5313 {
5314  int pos;
5315 
5316  assert(row != NULL);
5317  assert(!row->delaysort);
5318  assert(lp != NULL);
5319  assert(!lp->diving || row->lppos == -1);
5320  assert(col != NULL);
5321  assert(col->var != NULL);
5322 
5323  /* search the position of the column in the row's col vector */
5324  pos = rowSearchCoef(row, col);
5325  if( pos == -1 )
5326  {
5327  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5328  return SCIP_INVALIDDATA;
5329  }
5330  assert(0 <= pos && pos < row->len);
5331  assert(row->cols[pos] == col);
5332  assert(row->cols_index[pos] == col->index);
5333 
5334  /* if column knows of the row, remove the row from the column's row vector */
5335  if( row->linkpos[pos] >= 0 )
5336  {
5337  assert(col->rows[row->linkpos[pos]] == row);
5338  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5339  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5340  }
5341 
5342  /* delete the column from the row's col vector */
5343  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5344 
5345  checkLinks(lp);
5346 
5347  return SCIP_OKAY;
5348 }
5349 
5350 /** changes or adds a coefficient to an LP row */
5352  SCIP_ROW* row, /**< LP row */
5353  BMS_BLKMEM* blkmem, /**< block memory */
5354  SCIP_SET* set, /**< global SCIP settings */
5355  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5356  SCIP_LP* lp, /**< current LP data */
5357  SCIP_COL* col, /**< LP column */
5358  SCIP_Real val /**< value of coefficient */
5359  )
5360 {
5361  int pos;
5362 
5363  assert(row != NULL);
5364  assert(!row->delaysort);
5365  assert(lp != NULL);
5366  assert(!lp->diving || row->lppos == -1);
5367  assert(col != NULL);
5368 
5369  /* search the position of the column in the row's col vector */
5370  pos = rowSearchCoef(row, col);
5371 
5372  /* check, if column already exists in the row's col vector */
5373  if( pos == -1 )
5374  {
5375  /* add previously not existing coefficient */
5376  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5377  }
5378  else
5379  {
5380  /* modify already existing coefficient */
5381  assert(0 <= pos && pos < row->len);
5382  assert(row->cols[pos] == col);
5383  assert(row->cols_index[pos] == col->index);
5384 
5385  /* if column knows of the row, change the corresponding coefficient in the column */
5386  if( row->linkpos[pos] >= 0 )
5387  {
5388  assert(col->rows[row->linkpos[pos]] == row);
5389  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5390  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5391  }
5392 
5393  /* change the coefficient in the row */
5394  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5395  }
5396 
5397  checkLinks(lp);
5398 
5399  return SCIP_OKAY;
5400 }
5401 
5402 /** increases value of an existing or non-existing coefficient in an LP row */
5404  SCIP_ROW* row, /**< LP row */
5405  BMS_BLKMEM* blkmem, /**< block memory */
5406  SCIP_SET* set, /**< global SCIP settings */
5407  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5408  SCIP_LP* lp, /**< current LP data */
5409  SCIP_COL* col, /**< LP column */
5410  SCIP_Real incval /**< value to add to the coefficient */
5411  )
5412 {
5413  int pos;
5414 
5415  assert(row != NULL);
5416  assert(lp != NULL);
5417  assert(!lp->diving || row->lppos == -1);
5418  assert(col != NULL);
5419 
5420  if( SCIPsetIsZero(set, incval) )
5421  return SCIP_OKAY;
5422 
5423  /* search the position of the column in the row's col vector */
5424  pos = rowSearchCoef(row, col);
5425 
5426  /* check, if column already exists in the row's col vector */
5427  if( pos == -1 )
5428  {
5429  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5430  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5431  }
5432  else
5433  {
5434  /* modify already existing coefficient */
5435  assert(0 <= pos && pos < row->len);
5436  assert(row->cols[pos] == col);
5437  assert(row->cols_index[pos] == col->index);
5438 
5439  /* if column knows of the row, change the corresponding coefficient in the column */
5440  if( row->linkpos[pos] >= 0 )
5441  {
5442  assert(col->rows[row->linkpos[pos]] == row);
5443  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5444  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5445  }
5446 
5447  /* change the coefficient in the row */
5448  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5449  }
5450 
5451  checkLinks(lp);
5452 
5453  /* invalid the activity */
5454  row->validactivitylp = -1;
5455 
5456  return SCIP_OKAY;
5457 }
5458 
5459 /** changes constant value of 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 constant /**< new constant value */
5468  )
5469 {
5470  assert(row != NULL);
5471  assert(row->lhs <= row->rhs);
5472  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5473  assert(stat != NULL);
5474  assert(lp != NULL);
5475  assert(!lp->diving || row->lppos == -1);
5476 
5477  if( !SCIPsetIsEQ(set, constant, row->constant) )
5478  {
5479  SCIP_Real oldconstant;
5480 
5481  if( row->validpsactivitydomchg == stat->domchgcount )
5482  {
5483  assert(row->pseudoactivity < SCIP_INVALID);
5484  row->pseudoactivity += constant - row->constant;
5485  }
5486  if( row->validactivitybdsdomchg == stat->domchgcount )
5487  {
5488  assert(row->minactivity < SCIP_INVALID);
5489  assert(row->maxactivity < SCIP_INVALID);
5490  row->minactivity += constant - row->constant;
5491  row->maxactivity += constant - row->constant;
5492  }
5493 
5494  if( !SCIPsetIsInfinity(set, -row->lhs) )
5495  {
5496  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5497  }
5498  if( !SCIPsetIsInfinity(set, row->rhs) )
5499  {
5500  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5501  }
5502 
5503  oldconstant = row->constant;
5504 
5505  row->constant = constant;
5506 
5507  /* issue row constant changed event */
5508  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5509  }
5510 
5511  return SCIP_OKAY;
5512 }
5513 
5514 /** add constant value to a row */
5516  SCIP_ROW* row, /**< LP row */
5517  BMS_BLKMEM* blkmem, /**< block memory */
5518  SCIP_SET* set, /**< global SCIP settings */
5519  SCIP_STAT* stat, /**< problem statistics */
5520  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5521  SCIP_LP* lp, /**< current LP data */
5522  SCIP_Real addval /**< constant value to add to the row */
5523  )
5524 {
5525  assert(row != NULL);
5526  assert(row->lhs <= row->rhs);
5527  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5528  assert(stat != NULL);
5529  assert(lp != NULL);
5530  assert(!lp->diving || row->lppos == -1);
5531 
5532  if( !SCIPsetIsZero(set, addval) )
5533  {
5534  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5535  }
5536 
5537  return SCIP_OKAY;
5538 }
5539 
5540 /** changes left hand side of LP row */
5542  SCIP_ROW* row, /**< LP row */
5543  BMS_BLKMEM* blkmem, /**< block memory */
5544  SCIP_SET* set, /**< global SCIP settings */
5545  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5546  SCIP_LP* lp, /**< current LP data */
5547  SCIP_Real lhs /**< new left hand side */
5548  )
5549 {
5550  assert(row != NULL);
5551  assert(lp != NULL);
5552 
5553  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5554  {
5555  SCIP_Real oldlhs;
5556 
5557  oldlhs = row->lhs;
5558 
5559  row->lhs = lhs;
5560  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5561 
5562  if( !lp->diving )
5563  {
5564  /* issue row side changed event */
5565  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5566  }
5567  }
5568 
5569  return SCIP_OKAY;
5570 }
5571 
5572 /** changes right hand side of LP row */
5574  SCIP_ROW* row, /**< LP row */
5575  BMS_BLKMEM* blkmem, /**< block memory */
5576  SCIP_SET* set, /**< global SCIP settings */
5577  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5578  SCIP_LP* lp, /**< current LP data */
5579  SCIP_Real rhs /**< new right hand side */
5580  )
5581 {
5582  assert(row != NULL);
5583  assert(lp != NULL);
5584 
5585  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5586  {
5587  SCIP_Real oldrhs;
5588 
5589  oldrhs = row->rhs;
5590 
5591  row->rhs = rhs;
5592  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5593 
5594  if( !lp->diving )
5595  {
5596  /* issue row side changed event */
5597  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5598  }
5599  }
5600 
5601  return SCIP_OKAY;
5602 }
5603 
5604 /** changes the local flag of LP row */
5606  SCIP_ROW* row, /**< LP row */
5607  SCIP_Bool local /**< new value for local flag */
5608  )
5609 {
5610  assert(row != NULL);
5611 
5612  row->local = local;
5613 
5614  return SCIP_OKAY;
5615 }
5616 
5617 /** additional scalars that are tried in integrality scaling */
5618 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5619 static const int nscalars = 9;
5620 
5621 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5623  SCIP_ROW* row, /**< LP row */
5624  SCIP_SET* set, /**< global SCIP settings */
5625  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5626  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5627  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5628  SCIP_Real maxscale, /**< maximal allowed scalar */
5629  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5630  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5631  SCIP_Bool* success /**< stores whether returned value is valid */
5632  )
5633 {
5634 #ifndef NDEBUG
5635  SCIP_COL* col;
5636 #endif
5637  SCIP_Longint gcd;
5638  SCIP_Longint scm;
5639  SCIP_Longint nominator;
5640  SCIP_Longint denominator;
5641  SCIP_Real val;
5642  SCIP_Real absval;
5643  SCIP_Real minval;
5644  SCIP_Real scaleval;
5645  SCIP_Real twomultval;
5646  SCIP_Bool scalable;
5647  SCIP_Bool twomult;
5648  SCIP_Bool rational;
5649  int c;
5650  int s;
5651 
5652  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5653  assert(row != NULL);
5654  assert(row->len == 0 || row->cols != NULL);
5655  assert(row->len == 0 || row->cols_index != NULL);
5656  assert(row->len == 0 || row->vals != NULL);
5657  assert(maxdnom >= 1);
5658  assert(mindelta < 0.0);
5659  assert(maxdelta > 0.0);
5660  assert(success != NULL);
5661 
5662  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5663  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5664 
5665  if( intscalar != NULL )
5666  *intscalar = SCIP_INVALID;
5667  *success = FALSE;
5668 
5669  /* get minimal absolute non-zero value */
5670  minval = SCIP_REAL_MAX;
5671  for( c = 0; c < row->len; ++c )
5672  {
5673 #ifndef NDEBUG
5674  col = row->cols[c];
5675  assert(col != NULL);
5676  assert(col->var != NULL);
5677  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5678  assert(SCIPvarGetCol(col->var) == col);
5679 #endif
5680  val = row->vals[c];
5681  assert(!SCIPsetIsZero(set, val));
5682 
5683  if( val < mindelta || val > maxdelta )
5684  {
5685  absval = REALABS(val);
5686  minval = MIN(minval, absval);
5687  }
5688  }
5689  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5690  {
5691  /* all coefficients are zero (inside tolerances) */
5692  if( intscalar != NULL )
5693  *intscalar = 1.0;
5694  *success = TRUE;
5695  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5696 
5697  return SCIP_OKAY;
5698  }
5699  assert(minval > MIN(-mindelta, maxdelta));
5700  assert(SCIPsetIsPositive(set, minval));
5701  assert(!SCIPsetIsInfinity(set, minval));
5702 
5703  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5704  * and a power of 2
5705  */
5706  scaleval = 1.0/minval;
5707  scalable = (scaleval <= maxscale);
5708  for( c = 0; c < row->len && scalable; ++c )
5709  {
5710  /* don't look at continuous variables, if we don't have to */
5711  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5712  continue;
5713 
5714  /* check, if the coefficient can be scaled with a simple scalar */
5715  val = row->vals[c];
5716  absval = REALABS(val);
5717  while( scaleval <= maxscale
5718  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5719  {
5720  for( s = 0; s < nscalars; ++s )
5721  {
5722  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5723  {
5724  scaleval *= scalars[s];
5725  break;
5726  }
5727  }
5728  if( s >= nscalars )
5729  scaleval *= 2.0;
5730  }
5731  scalable = (scaleval <= maxscale);
5732  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5733  }
5734  if( scalable )
5735  {
5736  /* make row coefficients integral by dividing them by the smallest coefficient
5737  * (and multiplying them with a power of 2)
5738  */
5739  assert(scaleval <= maxscale);
5740  if( intscalar != NULL )
5741  *intscalar = scaleval;
5742  *success = TRUE;
5743  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5744 
5745  return SCIP_OKAY;
5746  }
5747 
5748  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5749  twomultval = 1.0;
5750  twomult = (twomultval <= maxscale);
5751  for( c = 0; c < row->len && twomult; ++c )
5752  {
5753  /* don't look at continuous variables, if we don't have to */
5754  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5755  continue;
5756 
5757  /* check, if the coefficient can be scaled with a simple scalar */
5758  val = row->vals[c];
5759  absval = REALABS(val);
5760  while( twomultval <= maxscale
5761  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5762  {
5763  for( s = 0; s < nscalars; ++s )
5764  {
5765  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5766  {
5767  twomultval *= scalars[s];
5768  break;
5769  }
5770  }
5771  if( s >= nscalars )
5772  twomultval *= 2.0;
5773  }
5774  twomult = (twomultval <= maxscale);
5775  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5776  val, twomultval, val*twomultval, twomult);
5777  }
5778  if( twomult )
5779  {
5780  /* make row coefficients integral by multiplying them with a power of 2 */
5781  assert(twomultval <= maxscale);
5782  if( intscalar != NULL )
5783  *intscalar = twomultval;
5784  *success = TRUE;
5785  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5786 
5787  return SCIP_OKAY;
5788  }
5789 
5790  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5791  * and the smallest common multiple of the denominators
5792  */
5793  gcd = 1;
5794  scm = 1;
5795  rational = (maxdnom > 1);
5796 
5797  /* first coefficient (to initialize gcd) */
5798  for( c = 0; c < row->len && rational; ++c )
5799  {
5800  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5801  {
5802  val = row->vals[c];
5803  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5804  if( rational && nominator != 0 )
5805  {
5806  assert(denominator > 0);
5807  gcd = ABS(nominator);
5808  scm = denominator;
5809  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5810  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5811  val, nominator, denominator, gcd, scm, rational);
5812  break;
5813  }
5814  }
5815  }
5816 
5817  /* remaining coefficients */
5818  for( ++c; c < row->len && rational; ++c )
5819  {
5820  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5821  {
5822  val = row->vals[c];
5823  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5824  if( rational && nominator != 0 )
5825  {
5826  assert(denominator > 0);
5827  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5828  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5829  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5830  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5831  val, nominator, denominator, gcd, scm, rational);
5832  }
5833  }
5834  }
5835 
5836  if( rational )
5837  {
5838  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5839  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5840  if( intscalar != NULL )
5841  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5842  *success = TRUE;
5843  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5844  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5845  }
5846  else
5847  {
5848  assert(!(*success));
5849  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5850  }
5851 
5852  return SCIP_OKAY;
5853 }
5854 
5855 /** tries to scale row, s.t. all coefficients become integral */
5857  SCIP_ROW* row, /**< LP row */
5858  BMS_BLKMEM* blkmem, /**< block memory */
5859  SCIP_SET* set, /**< global SCIP settings */
5860  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5861  SCIP_STAT* stat, /**< problem statistics */
5862  SCIP_LP* lp, /**< current LP data */
5863  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5864  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5865  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5866  SCIP_Real maxscale, /**< maximal value to scale row with */
5867  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5868  SCIP_Bool* success /**< stores whether row could be made rational */
5869  )
5870 {
5871  SCIP_Real intscalar;
5872 
5873  assert(success != NULL);
5874 
5875  /* calculate scalar to make coefficients integral */
5876  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5877  &intscalar, success) );
5878 
5879  if( *success )
5880  {
5881  /* scale the row */
5882  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
5883  }
5884 
5885  return SCIP_OKAY;
5886 }
5887 
5888 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
5889  * higher ones
5890  */
5892  SCIP_ROW* row /**< row to be sorted */
5893  )
5894 {
5895  assert(row != NULL);
5896 
5897  /* sort LP columns */
5898  rowSortLP(row);
5899 
5900  /* sort non-LP columns */
5901  rowSortNonLP(row);
5902 
5903 #ifdef SCIP_MORE_DEBUG
5904  /* check the sorting */
5905  {
5906  int c;
5907  if( !row->delaysort )
5908  {
5909  for( c = 1; c < row->nlpcols; ++c )
5910  assert(row->cols[c]->index >= row->cols[c-1]->index);
5911  for( c = row->nlpcols + 1; c < row->len; ++c )
5912  assert(row->cols[c]->index >= row->cols[c-1]->index);
5913  }
5914  }
5915 #endif
5916 }
5917 
5918 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
5919  * zero entries from row
5920  * the row must not be linked to the columns; otherwise, we would need to update the columns as
5921  * well, which is too expensive
5922  */
5923 static
5925  SCIP_ROW* row, /**< row to be sorted */
5926  SCIP_SET* set /**< global SCIP settings */
5927  )
5928 {
5929  assert(row != NULL);
5930  assert(!row->delaysort);
5931  assert(row->nunlinked == row->len);
5932  assert(row->nlpcols == 0);
5933 
5934  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
5935 
5936  /* do nothing on empty rows; if row is sorted, nothing has to be done */
5937  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
5938  {
5939  SCIP_COL** cols;
5940  int* cols_index;
5941  SCIP_Real* vals;
5942  int s;
5943  int t;
5944 
5945  /* make sure, the row is sorted */
5946  SCIProwSort(row);
5947  assert(row->lpcolssorted);
5948  assert(row->nonlpcolssorted);
5949 
5950  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
5951  cols = row->cols;
5952  cols_index = row->cols_index;
5953  vals = row->vals;
5954  assert(cols != NULL);
5955  assert(cols_index != NULL);
5956  assert(vals != NULL);
5957 
5958  t = 0;
5959  row->integral = TRUE;
5960  assert(!SCIPsetIsZero(set, vals[0]));
5961  assert(row->linkpos[0] == -1);
5962 
5963  for( s = 1; s < row->len; ++s )
5964  {
5965  assert(!SCIPsetIsZero(set, vals[s]));
5966  assert(row->linkpos[s] == -1);
5967 
5968  if( cols[s] == cols[t] )
5969  {
5970  /* merge entries with equal column */
5971  vals[t] += vals[s];
5972  }
5973  else
5974  {
5975  /* go to the next entry, overwriting current entry if coefficient is zero */
5976  if( !SCIPsetIsZero(set, vals[t]) )
5977  {
5978  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
5979  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
5980 
5981  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5982  t++;
5983  }
5984  cols[t] = cols[s];
5985  cols_index[t] = cols_index[s];
5986  vals[t] = vals[s];
5987  }
5988  }
5989  if( !SCIPsetIsZero(set, vals[t]) )
5990  {
5991  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5992  t++;
5993  }
5994  assert(s == row->len);
5995  assert(t <= row->len);
5996 
5997  row->len = t;
5998  row->nunlinked = t;
5999 
6000  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6001  if( t < s )
6002  rowCalcNorms(row, set);
6003  }
6004 
6005 #ifndef NDEBUG
6006  /* check for double entries */
6007  {
6008  int i;
6009  int j;
6010 
6011  for( i = 0; i < row->len; ++i )
6012  {
6013  assert(row->cols[i] != NULL);
6014  assert(row->cols[i]->index == row->cols_index[i]);
6015  for( j = i+1; j < row->len; ++j )
6016  assert(row->cols[i] != row->cols[j]);
6017  }
6018  }
6019 #endif
6020 }
6021 
6022 /** enables delaying of row sorting */
6024  SCIP_ROW* row /**< LP row */
6025  )
6026 {
6027  assert(row != NULL);
6028  assert(!row->delaysort);
6029 
6030  row->delaysort = TRUE;
6031 }
6032 
6033 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6035  SCIP_ROW* row, /**< LP row */
6036  SCIP_SET* set /**< global SCIP settings */
6037  )
6038 {
6039  assert(row != NULL);
6040  assert(row->delaysort);
6041 
6042  row->delaysort = FALSE;
6043  rowMerge(row, set);
6044 }
6045 
6046 /** recalculates the current activity of a row */
6048  SCIP_ROW* row, /**< LP row */
6049  SCIP_STAT* stat /**< problem statistics */
6050  )
6051 {
6052  SCIP_COL* col;
6053  int c;
6054 
6055  assert(row != NULL);
6056  assert(stat != NULL);
6057 
6058  row->activity = row->constant;
6059  for( c = 0; c < row->nlpcols; ++c )
6060  {
6061  col = row->cols[c];
6062  assert(col != NULL);
6063  assert(col->primsol < SCIP_INVALID);
6064  assert(col->lppos >= 0);
6065  assert(row->linkpos[c] >= 0);
6066  row->activity += row->vals[c] * col->primsol;
6067  }
6068 
6069  if( row->nunlinked > 0 )
6070  {
6071  for( c = row->nlpcols; c < row->len; ++c )
6072  {
6073  col = row->cols[c];
6074  assert(col != NULL);
6075  assert(col->lppos >= 0 || col->primsol == 0.0);
6076  assert(col->lppos == -1 || row->linkpos[c] == -1);
6077  if( col->lppos >= 0 )
6078  row->activity += row->vals[c] * col->primsol;
6079  }
6080  }
6081 #ifndef NDEBUG
6082  else
6083  {
6084  for( c = row->nlpcols; c < row->len; ++c )
6085  {
6086  col = row->cols[c];
6087  assert(col != NULL);
6088  assert(col->primsol == 0.0);
6089  assert(col->lppos == -1);
6090  assert(row->linkpos[c] >= 0);
6091  }
6092  }
6093 #endif
6094 
6095  row->validactivitylp = stat->lpcount;
6096 }
6097 
6098 /** returns the activity of a row in the current LP solution */
6100  SCIP_ROW* row, /**< LP row */
6101  SCIP_SET* set, /**< global SCIP settings */
6102  SCIP_STAT* stat, /**< problem statistics */
6103  SCIP_LP* lp /**< current LP data */
6104  )
6105 {
6106  SCIP_Real inf;
6107  SCIP_Real activity;
6108 
6109  assert(row != NULL);
6110  assert(stat != NULL);
6111  assert(lp != NULL);
6112  assert(row->validactivitylp <= stat->lpcount);
6113  assert(lp->validsollp == stat->lpcount);
6114 
6115  if( row->validactivitylp != stat->lpcount )
6116  SCIProwRecalcLPActivity(row, stat);
6117  assert(row->validactivitylp == stat->lpcount);
6118  assert(row->activity < SCIP_INVALID);
6119 
6120  activity = row->activity;
6121  inf = SCIPsetInfinity(set);
6122  activity = MAX(activity, -inf);
6123  activity = MIN(activity, +inf);
6124 
6125  return activity;
6126 }
6127 
6128 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6130  SCIP_ROW* row, /**< LP row */
6131  SCIP_SET* set, /**< global SCIP settings */
6132  SCIP_STAT* stat, /**< problem statistics */
6133  SCIP_LP* lp /**< current LP data */
6134  )
6135 {
6136  SCIP_Real activity;
6137 
6138  assert(row != NULL);
6139 
6140  activity = SCIProwGetLPActivity(row, set, stat, lp);
6141 
6142  return MIN(row->rhs - activity, activity - row->lhs);
6143 }
6144 
6145 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6146  *
6147  * @todo Implement calculation of activities similar to LPs.
6148  */
6150  SCIP_ROW* row, /**< LP row */
6151  SCIP_SET* set, /**< global SCIP settings */
6152  SCIP_STAT* stat /**< problem statistics */
6153  )
6154 {
6155  SCIP_Real inf;
6156  SCIP_Real activity;
6157  SCIP_COL* col;
6158  int c;
6159 
6160  assert( row != NULL );
6161  assert( stat != NULL );
6162 
6163  activity = row->constant;
6164  for (c = 0; c < row->nlpcols; ++c)
6165  {
6166  col = row->cols[c];
6167  assert( col != NULL );
6168  assert( col->lppos >= 0 );
6169  assert( col->var != NULL );
6170  assert( row->linkpos[c] >= 0 );
6171  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6172  }
6173 
6174  if ( row->nunlinked > 0 )
6175  {
6176  for (c = row->nlpcols; c < row->len; ++c)
6177  {
6178  col = row->cols[c];
6179  assert( col != NULL );
6180  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6181  if ( col->lppos >= 0 )
6182  {
6183  assert( col->var != NULL );
6184  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6185  }
6186  }
6187  }
6188 #ifndef NDEBUG
6189  else
6190  {
6191  for (c = row->nlpcols; c < row->len; ++c)
6192  {
6193  col = row->cols[c];
6194  assert( col != NULL );
6195  assert( col->lppos == -1 );
6196  assert( row->linkpos[c] >= 0 );
6197  }
6198  }
6199 #endif
6200  inf = SCIPsetInfinity(set);
6201  activity = MAX(activity, -inf);
6202  activity = MIN(activity, +inf);
6203 
6204  return MIN(row->rhs - activity, activity - row->lhs);
6205 }
6206 
6207 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6208  *
6209  * @todo Implement calculation of activities similar to LPs.
6210  */
6212  SCIP_ROW* row, /**< LP row */
6213  SCIP_SET* set, /**< global SCIP settings */
6214  SCIP_STAT* stat /**< problem statistics */
6215  )
6216 {
6217  SCIP_Real inf;
6218  SCIP_Real activity;
6219  SCIP_COL* col;
6220  int c;
6221 
6222  assert( row != NULL );
6223  assert( stat != NULL );
6224 
6225  activity = row->constant;
6226  for (c = 0; c < row->nlpcols; ++c)
6227  {
6228  col = row->cols[c];
6229  assert( col != NULL );
6230  assert( col->lppos >= 0 );
6231  assert( col->var != NULL );
6232  assert( row->linkpos[c] >= 0 );
6233  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6234  }
6235 
6236  if ( row->nunlinked > 0 )
6237  {
6238  for (c = row->nlpcols; c < row->len; ++c)
6239  {
6240  col = row->cols[c];
6241  assert( col != NULL );
6242  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6243  if ( col->lppos >= 0 )
6244  {
6245  assert( col->var != NULL );
6246  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6247  }
6248  }
6249  }
6250 #ifndef NDEBUG
6251  else
6252  {
6253  for (c = row->nlpcols; c < row->len; ++c)
6254  {
6255  col = row->cols[c];
6256  assert( col != NULL );
6257  assert( col->lppos == -1 );
6258  assert( row->linkpos[c] >= 0 );
6259  }
6260  }
6261 #endif
6262  inf = SCIPsetInfinity(set);
6263  activity = MAX(activity, -inf);
6264  activity = MIN(activity, +inf);
6265 
6266  return MIN(row->rhs - activity, activity - row->lhs);
6267 }
6268 
6269 /** calculates the current pseudo activity of a row */
6271  SCIP_ROW* row, /**< row data */
6272  SCIP_STAT* stat /**< problem statistics */
6273  )
6274 {
6275  SCIP_COL* col;
6276  int i;
6277 
6278  assert(row != NULL);
6279  assert(stat != NULL);
6280 
6281  row->pseudoactivity = row->constant;
6282  for( i = 0; i < row->len; ++i )
6283  {
6284  col = row->cols[i];
6285  assert(col != NULL);
6286  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6287  assert(col->var != NULL);
6288  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6289 
6290  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6291  }
6292  row->validpsactivitydomchg = stat->domchgcount;
6293  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6294 }
6295 
6296 /** returns the pseudo activity of a row in the current pseudo solution */
6298  SCIP_ROW* row, /**< LP row */
6299  SCIP_SET* set, /**< global SCIP settings */
6300  SCIP_STAT* stat /**< problem statistics */
6301  )
6302 {
6303  SCIP_Real inf;
6304  SCIP_Real activity;
6305 
6306  assert(row != NULL);
6307  assert(stat != NULL);
6308  assert(row->validpsactivitydomchg <= stat->domchgcount);
6309 
6310  /* check, if pseudo activity has to be calculated */
6311  if( row->validpsactivitydomchg != stat->domchgcount )
6312  SCIProwRecalcPseudoActivity(row, stat);
6313  assert(row->validpsactivitydomchg == stat->domchgcount);
6314  assert(row->pseudoactivity < SCIP_INVALID);
6315 
6316  activity = row->pseudoactivity;
6317  inf = SCIPsetInfinity(set);
6318  activity = MAX(activity, -inf);
6319  activity = MIN(activity, +inf);
6320 
6321  return activity;
6322 }
6323 
6324 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6326  SCIP_ROW* row, /**< LP row */
6327  SCIP_SET* set, /**< global SCIP settings */
6328  SCIP_STAT* stat /**< problem statistics */
6329  )
6330 {
6331  SCIP_Real pseudoactivity;
6332 
6333  assert(row != NULL);
6334 
6335  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6336 
6337  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6338 }
6339 
6340 /** returns the activity of a row for a given solution */
6342  SCIP_ROW* row, /**< LP row */
6343  SCIP_SET* set, /**< global SCIP settings */
6344  SCIP_STAT* stat, /**< problem statistics data */
6345  SCIP_SOL* sol /**< primal CIP solution */
6346  )
6347 {
6348  SCIP_COL* col;
6349  SCIP_Real inf;
6350  SCIP_Real activity;
6351  SCIP_Real solval;
6352  int i;
6353 
6354  assert(row != NULL);
6355 
6356  activity = row->constant;
6357  for( i = 0; i < row->len; ++i )
6358  {
6359  col = row->cols[i];
6360  assert(col != NULL);
6361  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6362  solval = SCIPsolGetVal(sol, set, stat, col->var);
6363  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6364  {
6365  if( SCIPsetIsInfinity(set, -row->lhs) )
6366  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6367  else if( SCIPsetIsInfinity(set, row->rhs) )
6368  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6369  else
6370  solval = (col->lb + col->ub)/2.0;
6371  }
6372  activity += row->vals[i] * solval;
6373  }
6374 
6375  inf = SCIPsetInfinity(set);
6376  activity = MAX(activity, -inf);
6377  activity = MIN(activity, +inf);
6378 
6379  return activity;
6380 }
6381 
6382 /** returns the feasibility of a row for the given solution */
6384  SCIP_ROW* row, /**< LP row */
6385  SCIP_SET* set, /**< global SCIP settings */
6386  SCIP_STAT* stat, /**< problem statistics data */
6387  SCIP_SOL* sol /**< primal CIP solution */
6388  )
6389 {
6390  SCIP_Real activity;
6391 
6392  assert(row != NULL);
6393 
6394  activity = SCIProwGetSolActivity(row, set, stat, sol);
6395 
6396  return MIN(row->rhs - activity, activity - row->lhs);
6397 }
6398 
6399 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6400 static
6402  SCIP_ROW* row, /**< row data */
6403  SCIP_SET* set, /**< global SCIP settings */
6404  SCIP_STAT* stat /**< problem statistics data */
6405  )
6406 {
6407  SCIP_COL* col;
6408  SCIP_Real val;
6409  SCIP_Bool mininfinite;
6410  SCIP_Bool maxinfinite;
6411  int i;
6412 
6413  assert(row != NULL);
6414  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6415  assert(stat != NULL);
6416 
6417  /* calculate activity bounds */
6418  mininfinite = FALSE;
6419  maxinfinite = FALSE;
6420  row->minactivity = row->constant;
6421  row->maxactivity = row->constant;
6422  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6423  {
6424  col = row->cols[i];
6425  assert(col != NULL);
6426  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6427  val = row->vals[i];
6428  if( val >= 0.0 )
6429  {
6430  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6431  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6432  if( !mininfinite )
6433  row->minactivity += val * col->lb;
6434  if( !maxinfinite )
6435  row->maxactivity += val * col->ub;
6436  }
6437  else
6438  {
6439  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6440  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6441  if( !mininfinite )
6442  row->minactivity += val * col->ub;
6443  if( !maxinfinite )
6444  row->maxactivity += val * col->lb;
6445  }
6446  }
6447 
6448  if( mininfinite )
6449  row->minactivity = -SCIPsetInfinity(set);
6450  if( maxinfinite )
6451  row->maxactivity = SCIPsetInfinity(set);
6452  row->validactivitybdsdomchg = stat->domchgcount;
6453 
6454  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6456  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6458 }
6459 
6460 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6462  SCIP_ROW* row, /**< LP row */
6463  SCIP_SET* set, /**< global SCIP settings */
6464  SCIP_STAT* stat /**< problem statistics data */
6465  )
6466 {
6467  assert(row != NULL);
6468  assert(stat != NULL);
6469  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6470 
6471  /* check, if activity bounds has to be calculated */
6472  if( row->validactivitybdsdomchg != stat->domchgcount )
6473  rowCalcActivityBounds(row, set, stat);
6474  assert(row->validactivitybdsdomchg == stat->domchgcount);
6475  assert(row->minactivity < SCIP_INVALID);
6476  assert(row->maxactivity < SCIP_INVALID);
6477 
6478  return row->minactivity;
6479 }
6480 
6481 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6483  SCIP_ROW* row, /**< LP row */
6484  SCIP_SET* set, /**< global SCIP settings */
6485  SCIP_STAT* stat /**< problem statistics data */
6486  )
6487 {
6488  assert(row != NULL);
6489  assert(stat != NULL);
6490  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6491 
6492  /* check, if activity bounds has to be calculated */
6493  if( row->validactivitybdsdomchg != stat->domchgcount )
6494  rowCalcActivityBounds(row, set, stat);
6495  assert(row->validactivitybdsdomchg == stat->domchgcount);
6496  assert(row->minactivity < SCIP_INVALID);
6497  assert(row->maxactivity < SCIP_INVALID);
6498 
6499  return row->maxactivity;
6500 }
6501 
6502 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6504  SCIP_ROW* row, /**< LP row */
6505  SCIP_SET* set, /**< global SCIP settings */
6506  SCIP_STAT* stat /**< problem statistics data */
6507  )
6508 {
6509  assert(row != NULL);
6510 
6511  if( row->modifiable )
6512  return FALSE;
6513  if( !SCIPsetIsInfinity(set, -row->lhs) )
6514  {
6515  SCIP_Real minactivity;
6516 
6517  minactivity = SCIProwGetMinActivity(row, set, stat);
6518  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6519  return FALSE;
6520  }
6521  if( !SCIPsetIsInfinity(set, row->rhs) )
6522  {
6523  SCIP_Real maxactivity;
6524 
6525  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6526  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6527  return FALSE;
6528  }
6529 
6530  return TRUE;
6531 }
6532 
6533 /** gets maximal absolute value of row vector coefficients */
6535  SCIP_ROW* row, /**< LP row */
6536  SCIP_SET* set /**< global SCIP settings */
6537  )
6538 {
6539  assert(row != NULL);
6540 
6541  if( row->nummaxval == 0 )
6542  rowCalcIdxsAndVals(row, set);
6543  assert(row->nummaxval > 0);
6544  assert(row->maxval >= 0.0 || row->len == 0);
6545 
6546  return row->maxval;
6547 }
6548 
6549 /** gets minimal absolute value of row vector's non-zero coefficients */
6551  SCIP_ROW* row, /**< LP row */
6552  SCIP_SET* set /**< global SCIP settings */
6553  )
6554 {
6555  assert(row != NULL);
6556 
6557  if( row->numminval == 0 )
6558  rowCalcIdxsAndVals(row, set);
6559  assert(row->numminval > 0);
6560  assert(row->minval >= 0.0 || row->len == 0);
6561 
6562  return row->minval;
6563 }
6564 
6565 /** gets maximal column index of row entries */
6567  SCIP_ROW* row, /**< LP row */
6568  SCIP_SET* set /**< global SCIP settings */
6569  )
6570 {
6571  assert(row != NULL);
6572 
6573  if( row->validminmaxidx == 0 )
6574  rowCalcIdxsAndVals(row, set);
6575  assert(row->maxidx >= 0 || row->len == 0);
6576  assert(row->validminmaxidx);
6577 
6578  return row->maxidx;
6579 }
6580 
6581 /** gets minimal column index of row entries */
6583  SCIP_ROW* row, /**< LP row */
6584  SCIP_SET* set /**< global SCIP settings */
6585  )
6586 {
6587  assert(row != NULL);
6588 
6589  if( row->validminmaxidx == 0 )
6590  rowCalcIdxsAndVals(row, set);
6591  assert(row->minidx >= 0 || row->len == 0);
6592  assert(row->validminmaxidx);
6593 
6594  return row->minidx;
6595 }
6596 
6597 /** gets number of integral columns in row */
6599  SCIP_ROW* row, /**< LP row */
6600  SCIP_SET* set /**< global SCIP settings */
6601  )
6602 {
6603  assert(row != NULL);
6604 
6605  if( row->numintcols == -1 )
6606  rowCalcIdxsAndVals(row, set);
6607 
6608  assert(row->numintcols <= row->len && row->numintcols >= 0);
6609 
6610  return row->numintcols;
6611 }
6612 
6613 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6615  SCIP_ROW* row, /**< LP row */
6616  SCIP_SET* set, /**< global SCIP settings */
6617  SCIP_STAT* stat, /**< problem statistics data */
6618  SCIP_LP* lp /**< current LP data */
6619  )
6620 {
6621  SCIP_Real norm;
6622  SCIP_Real feasibility;
6623  SCIP_Real eps;
6624 
6625  assert(set != NULL);
6626 
6627  switch( set->sepa_efficacynorm )
6628  {
6629  case 'e':
6630  norm = SCIProwGetNorm(row);
6631  break;
6632  case 'm':
6633  norm = SCIProwGetMaxval(row, set);
6634  break;
6635  case 's':
6636  norm = SCIProwGetSumNorm(row);
6637  break;
6638  case 'd':
6639  norm = (row->len == 0 ? 0.0 : 1.0);
6640  break;
6641  default:
6642  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6643  SCIPABORT();
6644  norm = 0.0; /*lint !e527*/
6645  }
6646 
6647  eps = SCIPsetSumepsilon(set);
6648  norm = MAX(norm, eps);
6649  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6650 
6651  return -feasibility / norm;
6652 }
6653 
6654 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6656  SCIP_ROW* row, /**< LP row */
6657  SCIP_SET* set, /**< global SCIP settings */
6658  SCIP_STAT* stat, /**< problem statistics data */
6659  SCIP_LP* lp, /**< current LP data */
6660  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6661  )
6662 {
6663  SCIP_Real efficacy;
6664 
6665  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6666 
6667  return SCIPsetIsEfficacious(set, root, efficacy);
6668 }
6669 
6670 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6672  SCIP_ROW* row, /**< LP row */
6673  SCIP_SET* set, /**< global SCIP settings */
6674  SCIP_STAT* stat, /**< problem statistics data */
6675  SCIP_SOL* sol /**< primal CIP solution */
6676  )
6677 {
6678  SCIP_Real norm;
6679  SCIP_Real feasibility;
6680  SCIP_Real eps;
6681 
6682  assert(set != NULL);
6683 
6684  switch( set->sepa_efficacynorm )
6685  {
6686  case 'e':
6687  norm = SCIProwGetNorm(row);
6688  break;
6689  case 'm':
6690  norm = SCIProwGetMaxval(row, set);
6691  break;
6692  case 's':
6693  norm = SCIProwGetSumNorm(row);
6694  break;
6695  case 'd':
6696  norm = (row->len == 0 ? 0.0 : 1.0);
6697  break;
6698  default:
6699  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6700  SCIPABORT();
6701  norm = 0.0; /*lint !e527*/
6702  }
6703 
6704  eps = SCIPsetSumepsilon(set);
6705  norm = MAX(norm, eps);
6706  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6707 
6708  return -feasibility / norm;
6709 }
6710 
6711 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6712  * efficacy
6713  */
6715  SCIP_ROW* row, /**< LP row */
6716  SCIP_SET* set, /**< global SCIP settings */
6717  SCIP_STAT* stat, /**< problem statistics data */
6718  SCIP_SOL* sol, /**< primal CIP solution */
6719  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6720  )
6721 {
6722  SCIP_Real efficacy;
6723 
6724  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6725 
6726  return SCIPsetIsEfficacious(set, root, efficacy);
6727 }
6728 
6729 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6731  SCIP_ROW* row, /**< LP row */
6732  SCIP_SET* set, /**< global SCIP settings */
6733  SCIP_STAT* stat /**< problem statistics data */
6734  )
6735 {
6736  SCIP_Real norm;
6737  SCIP_Real feasibility;
6738  SCIP_Real eps;
6739 
6740  assert(set != NULL);
6741 
6742  switch( set->sepa_efficacynorm )
6743  {
6744  case 'e':
6745  norm = SCIProwGetNorm(row);
6746  break;
6747  case 'm':
6748  norm = SCIProwGetMaxval(row, set);
6749  break;
6750  case 's':
6751  norm = SCIProwGetSumNorm(row);
6752  break;
6753  case 'd':
6754  norm = (row->len == 0 ? 0.0 : 1.0);
6755  break;
6756  default:
6757  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6758  SCIPABORT();
6759  norm = 0.0; /*lint !e527*/
6760  }
6761 
6762  eps = SCIPsetSumepsilon(set);
6763  norm = MAX(norm, eps);
6764  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6765 
6766  return -feasibility / norm;
6767 }
6768 
6769 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6771  SCIP_ROW* row, /**< LP row */
6772  SCIP_SET* set, /**< global SCIP settings */
6773  SCIP_STAT* stat /**< problem statistics data */
6774  )
6775 {
6776  SCIP_Real norm;
6777  SCIP_Real feasibility;
6778  SCIP_Real eps;
6779 
6780  assert(set != NULL);
6781 
6782  switch( set->sepa_efficacynorm )
6783  {
6784  case 'e':
6785  norm = SCIProwGetNorm(row);
6786  break;
6787  case 'm':
6788  norm = SCIProwGetMaxval(row, set);
6789  break;
6790  case 's':
6791  norm = SCIProwGetSumNorm(row);
6792  break;
6793  case 'd':
6794  norm = (row->len == 0 ? 0.0 : 1.0);
6795  break;
6796  default:
6797  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6798  SCIPABORT();
6799  norm = 0.0; /*lint !e527*/
6800  }
6801 
6802  eps = SCIPsetSumepsilon(set);
6803  norm = MAX(norm, eps);
6804  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6805 
6806  return -feasibility / norm;
6807 }
6808 
6809 /** returns the scalar product of the coefficient vectors of the two given rows
6810  *
6811  * @note the scalar product is computed w.r.t. the current LP columns only
6812  * @todo also consider non-LP columns for the computation?
6813  */
6815  SCIP_ROW* row1, /**< first LP row */
6816  SCIP_ROW* row2 /**< second LP row */
6817  )
6818 {
6819  SCIP_Real scalarprod;
6820  int* row1colsidx;
6821  int* row2colsidx;
6822  int i1;
6823  int i2;
6824 
6825  assert(row1 != NULL);
6826  assert(row2 != NULL);
6827 
6828  /* Sort the column indices of both rows.
6829  *
6830  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
6831  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
6832  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
6833  * for both or one of the non-LP columns for both.
6834  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
6835  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
6836  * columns can be added later and remain unlinked while all previously added columns might already be linked.
6837  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
6838  *
6839  * We distinguish the following cases:
6840  *
6841  * 1) both rows have no unlinked columns
6842  * -> we just check the LP partitions
6843  *
6844  * 2) exactly one row is completely unlinked, the other one is completely linked
6845  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
6846  * (thus all common LP columns are regarded)
6847  *
6848  * 3) we have unlinked and LP columns in both rows
6849  * -> we need to compare four partitions at once
6850  *
6851  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
6852  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
6853  * other row
6854  *
6855  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
6856  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
6857  *
6858  * 5) both rows are completely unlinked
6859  * -> we need to compare two partitions: both complete rows
6860  */
6861  SCIProwSort(row1);
6862  assert(row1->lpcolssorted);
6863  assert(row1->nonlpcolssorted);
6864  SCIProwSort(row2);
6865  assert(row2->lpcolssorted);
6866  assert(row2->nonlpcolssorted);
6867 
6868  assert(row1->nunlinked <= row1->len - row1->nlpcols);
6869  assert(row2->nunlinked <= row2->len - row2->nlpcols);
6870 
6871  row1colsidx = row1->cols_index;
6872  row2colsidx = row2->cols_index;
6873 
6874 #ifndef NDEBUG
6875  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
6876  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
6877  {
6878  i1 = 0;
6879  i2 = row2->nlpcols;
6880  while( i1 < row1->nlpcols && i2 < row2->len )
6881  {
6882  assert(row1->cols[i1] != row2->cols[i2]);
6883  if( row1->cols[i1]->index < row2->cols[i2]->index )
6884  ++i1;
6885  else
6886  {
6887  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6888  ++i2;
6889  }
6890  }
6891  assert(i1 == row1->nlpcols || i2 == row2->len);
6892 
6893  i1 = row1->nlpcols;
6894  i2 = 0;
6895  while( i1 < row1->len && i2 < row2->nlpcols )
6896  {
6897  assert(row1->cols[i1] != row2->cols[i2]);
6898  if( row1->cols[i1]->index < row2->cols[i2]->index )
6899  ++i1;
6900  else
6901  {
6902  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6903  ++i2;
6904  }
6905  }
6906  assert(i1 == row1->len || i2 == row2->nlpcols);
6907  }
6908 #endif
6909 
6910  /* The "easy" cases 1) and 2) */
6911  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
6912  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
6913  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
6914  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
6915  {
6916  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
6917  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
6918 
6919  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
6920  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
6921  */
6922  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
6923  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
6924  scalarprod = 0.0;
6925 
6926  /* calculate the scalar product */
6927  while( i1 >= 0 && i2 >= 0 )
6928  {
6929  assert(row1->cols[i1]->index == row1colsidx[i1]);
6930  assert(row2->cols[i2]->index == row2colsidx[i2]);
6931  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
6932  if( row1colsidx[i1] < row2colsidx[i2] )
6933  --i2;
6934  else if( row1colsidx[i1] > row2colsidx[i2] )
6935  --i1;
6936  else
6937  {
6938  scalarprod += row1->vals[i1] * row2->vals[i2];
6939  --i1;
6940  --i2;
6941  }
6942  }
6943  }
6944  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
6945  else
6946  {
6947  SCIP_Bool lpcols;
6948  int ilp1;
6949  int inlp1;
6950  int ilp2;
6951  int inlp2;
6952  int end1;
6953  int end2;
6954 
6955  scalarprod = 0;
6956  ilp1 = 0;
6957  ilp2 = 0;
6958 
6959  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
6960  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
6961  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
6962 
6963  /* handle the case of four partitions (case 3) until one partition is finished;
6964  * cases 4a), 4b), and 5) will fail the while-condition
6965  */
6966  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
6967  {
6968  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
6969  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
6970  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
6971  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
6972  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
6973  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
6974  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
6975  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
6976 
6977  /* rows have the same linked LP columns */
6978  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
6979  {
6980  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
6981  ++ilp1;
6982  ++ilp2;
6983  }
6984  /* LP column of row1 is the same as unlinked column of row2 */
6985  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
6986  {
6987  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
6988  ++ilp1;
6989  ++inlp2;
6990  }
6991  /* unlinked column of row1 is the same as LP column of row2 */
6992  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
6993  {
6994  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
6995  ++inlp1;
6996  ++ilp2;
6997  }
6998  /* two unlinked LP columns are the same */
6999  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7000  {
7001  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7002  ++inlp1;
7003  ++inlp2;
7004  }
7005  /* increase smallest counter */
7006  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7007  {
7008  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7009  {
7010  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7011  ++ilp1;
7012  else
7013  ++ilp2;
7014  }
7015  else
7016  {
7017  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7018  ++ilp1;
7019  else
7020  ++inlp2;
7021  }
7022  }
7023  else
7024  {
7025  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7026  {
7027  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7028  ++inlp1;
7029  else
7030  ++ilp2;
7031  }
7032  else
7033  {
7034  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7035  ++inlp1;
7036  else
7037  ++inlp2;
7038  }
7039  }
7040  }
7041 
7042  /* One partition was completely handled, we just have to handle the three remaining partitions:
7043  * the remaining partition of this row and the two partitions of the other row.
7044  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7045  */
7046  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7047  {
7048  int tmpilp;
7049  int tmpinlp;
7050 
7051  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7052 
7053  SCIPswapPointers((void**) &row1, (void**) &row2);
7054  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7055  tmpilp = ilp1;
7056  tmpinlp = inlp1;
7057  ilp1 = ilp2;
7058  inlp1 = inlp2;
7059  ilp2 = tmpilp;
7060  inlp2 = tmpinlp;
7061  }
7062 
7063  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7064  * -> this merges cases 4a) and 4b)
7065  */
7066  if( ilp1 == row1->nlpcols )
7067  {
7068  i1 = inlp1;
7069  end1 = row1->len;
7070  lpcols = FALSE;
7071  }
7072  else
7073  {
7074  assert(inlp1 == row1->len);
7075 
7076  i1 = ilp1;
7077  end1 = row1->nlpcols;
7078  lpcols = TRUE;
7079  }
7080 
7081  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7082  * case 5) will fail the while-condition
7083  */
7084  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7085  {
7086  assert(row1->cols[i1]->index == row1colsidx[i1]);
7087  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7088  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7089  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7090  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7091 
7092  /* current column in row 1 is the same as the current LP column in row 2 */
7093  if( row1colsidx[i1] == row2colsidx[ilp2] )
7094  {
7095  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7096  ++i1;
7097  ++ilp2;
7098  }
7099  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7100  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7101  {
7102  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7103  ++i1;
7104  ++inlp2;
7105  }
7106  /* increase smallest counter */
7107  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7108  {
7109  if( row1colsidx[i1] < row2colsidx[ilp2] )
7110  ++i1;
7111  else
7112  ++ilp2;
7113  }
7114  else
7115  {
7116  if( row1colsidx[i1] < row2colsidx[inlp2] )
7117  ++i1;
7118  else
7119  ++inlp2;
7120  }
7121  }
7122 
7123  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7124  * the two rows
7125  */
7126  if( i1 < end1 )
7127  {
7128  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7129  if( ilp2 == row2->nlpcols )
7130  {
7131  i2 = inlp2;
7132  end2 = row2->len;
7133  lpcols = FALSE;
7134  }
7135  else
7136  {
7137  assert(inlp2 == row2->len);
7138 
7139  i2 = ilp2;
7140  end2 = row2->nlpcols;
7141  }
7142 
7143  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7144  while( i1 < end1 && i2 < end2 )
7145  {
7146  assert(row1->cols[i1]->index == row1colsidx[i1]);
7147  assert(row2->cols[i2]->index == row2colsidx[i2]);
7148  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7149 
7150  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7151  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7152  {
7153  scalarprod += row1->vals[i1] * row2->vals[i2];
7154  ++i1;
7155  ++i2;
7156  }
7157  /* increase smallest counter */
7158  else if( row1colsidx[i1] < row2colsidx[i2] )
7159  ++i1;
7160  else
7161  ++i2;
7162  }
7163  }
7164  }
7165 
7166  return scalarprod;
7167 }
7168 
7169 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7170 static
7172  SCIP_ROW* row1, /**< first LP row */
7173  SCIP_ROW* row2 /**< second LP row */
7174  )
7175 {
7176  int prod;
7177  int* row1colsidx;
7178  int* row2colsidx;
7179  int i1;
7180  int i2;
7181 
7182  assert(row1 != NULL);
7183  assert(row2 != NULL);
7184 
7185  /* Sort the column indices of both rows.
7186  *
7187  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7188  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7189  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7190  * for both or one of the non-LP columns for both.
7191  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7192  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7193  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7194  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7195  *
7196  * We distinguish the following cases:
7197  *
7198  * 1) both rows have no unlinked columns
7199  * -> we just check the LP partitions
7200  *
7201  * 2) exactly one row is completely unlinked, the other one is completely linked
7202  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7203  * (thus all common LP columns are regarded)
7204  *
7205  * 3) we have unlinked and LP columns in both rows
7206  * -> we need to compare four partitions at once
7207  *
7208  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7209  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7210  * other row
7211  *
7212  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7213  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7214  *
7215  * 5) both rows are completely unlinked
7216  * -> we need to compare two partitions: both complete rows
7217  */
7218  SCIProwSort(row1);
7219  assert(row1->lpcolssorted);
7220  assert(row1->nonlpcolssorted);
7221  SCIProwSort(row2);
7222  assert(row2->lpcolssorted);
7223  assert(row2->nonlpcolssorted);
7224 
7225  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7226  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7227 
7228  row1colsidx = row1->cols_index;
7229  row2colsidx = row2->cols_index;
7230 
7231 #ifndef NDEBUG
7232  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7233  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7234  {
7235  i1 = 0;
7236  i2 = row2->nlpcols;
7237  while( i1 < row1->nlpcols && i2 < row2->len )
7238  {
7239  assert(row1->cols[i1] != row2->cols[i2]);
7240  if( row1->cols[i1]->index < row2->cols[i2]->index )
7241  ++i1;
7242  else
7243  {
7244  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7245  ++i2;
7246  }
7247  }
7248  assert(i1 == row1->nlpcols || i2 == row2->len);
7249 
7250  i1 = row1->nlpcols;
7251  i2 = 0;
7252  while( i1 < row1->len && i2 < row2->nlpcols )
7253  {
7254  assert(row1->cols[i1] != row2->cols[i2]);
7255  if( row1->cols[i1]->index < row2->cols[i2]->index )
7256  ++i1;
7257  else
7258  {
7259  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7260  ++i2;
7261  }
7262  }
7263  assert(i1 == row1->len || i2 == row2->nlpcols);
7264  }
7265 #endif
7266 
7267  /* The "easy" cases 1) and 2) */
7268  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7269  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7270  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7271  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7272  {
7273  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7274  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7275 
7276  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7277  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7278  */
7279  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7280  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7281  prod = 0;
7282 
7283  /* calculate the scalar product */
7284  while( i1 >= 0 && i2 >= 0 )
7285  {
7286  assert(row1->cols[i1]->index == row1colsidx[i1]);
7287  assert(row2->cols[i2]->index == row2colsidx[i2]);
7288  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7289  if( row1colsidx[i1] < row2colsidx[i2] )
7290  --i2;
7291  else if( row1colsidx[i1] > row2colsidx[i2] )
7292  --i1;
7293  else
7294  {
7295  ++prod;
7296  --i1;
7297  --i2;
7298  }
7299  }
7300  }
7301  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7302  else
7303  {
7304  SCIP_Bool lpcols;
7305  int ilp1;
7306  int inlp1;
7307  int ilp2;
7308  int inlp2;
7309  int end1;
7310  int end2;
7311 
7312  prod = 0;
7313  ilp1 = 0;
7314  ilp2 = 0;
7315 
7316  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7317  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7318  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7319 
7320  /* handle the case of four partitions (case 3) until one partition is finished;
7321  * cases 4a), 4b), and 5) will fail the while-condition
7322  */
7323  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7324  {
7325  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7326  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7327  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7328  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7329  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7330  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7331  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7332  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7333 
7334  /* rows have the same linked LP columns */
7335  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7336  {
7337  ++prod;
7338  ++ilp1;
7339  ++ilp2;
7340  }
7341  /* LP column of row1 is the same as unlinked column of row2 */
7342  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7343  {
7344  ++prod;
7345  ++ilp1;
7346  ++inlp2;
7347  }
7348  /* unlinked column of row1 is the same as LP column of row2 */
7349  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7350  {
7351  ++prod;
7352  ++inlp1;
7353  ++ilp2;
7354  }
7355  /* two unlinked LP columns are the same */
7356  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7357  {
7358  ++prod;
7359  ++inlp1;
7360  ++inlp2;
7361  }
7362  /* increase smallest counter */
7363  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7364  {
7365  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7366  {
7367  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7368  ++ilp1;
7369  else
7370  ++ilp2;
7371  }
7372  else
7373  {
7374  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7375  ++ilp1;
7376  else
7377  ++inlp2;
7378  }
7379  }
7380  else
7381  {
7382  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7383  {
7384  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7385  ++inlp1;
7386  else
7387  ++ilp2;
7388  }
7389  else
7390  {
7391  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7392  ++inlp1;
7393  else
7394  ++inlp2;
7395  }
7396  }
7397  }
7398 
7399  /* One partition was completely handled, we just have to handle the three remaining partitions:
7400  * the remaining partition of this row and the two partitions of the other row.
7401  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7402  */
7403  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7404  {
7405  int tmpilp;
7406  int tmpinlp;
7407 
7408  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7409 
7410  SCIPswapPointers((void**) &row1, (void**) &row2);
7411  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7412  tmpilp = ilp1;
7413  tmpinlp = inlp1;
7414  ilp1 = ilp2;
7415  inlp1 = inlp2;
7416  ilp2 = tmpilp;
7417  inlp2 = tmpinlp;
7418  }
7419 
7420  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7421  * -> this merges cases 4a) and 4b)
7422  */
7423  if( ilp1 == row1->nlpcols )
7424  {
7425  i1 = inlp1;
7426  end1 = row1->len;
7427  lpcols = FALSE;
7428  }
7429  else
7430  {
7431  assert(inlp1 == row1->len);
7432 
7433  i1 = ilp1;
7434  end1 = row1->nlpcols;
7435  lpcols = TRUE;
7436  }
7437 
7438  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7439  * case 5) will fail the while-condition
7440  */
7441  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7442  {
7443  assert(row1->cols[i1]->index == row1colsidx[i1]);
7444  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7445  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7446  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7447  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7448 
7449  /* current column in row 1 is the same as the current LP column in row 2 */
7450  if( row1colsidx[i1] == row2colsidx[ilp2] )
7451  {
7452  ++prod;
7453  ++i1;
7454  ++ilp2;
7455  }
7456  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7457  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7458  {
7459  ++prod;
7460  ++i1;
7461  ++inlp2;
7462  }
7463  /* increase smallest counter */
7464  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7465  {
7466  if( row1colsidx[i1] < row2colsidx[ilp2] )
7467  ++i1;
7468  else
7469  ++ilp2;
7470  }
7471  else
7472  {
7473  if( row1colsidx[i1] < row2colsidx[inlp2] )
7474  ++i1;
7475  else
7476  ++inlp2;
7477  }
7478  }
7479 
7480  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7481  * the two rows
7482  */
7483  if( i1 < end1 )
7484  {
7485  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7486  if( ilp2 == row2->nlpcols )
7487  {
7488  i2 = inlp2;
7489  end2 = row2->len;
7490  lpcols = FALSE;
7491  }
7492  else
7493  {
7494  assert(inlp2 == row2->len);
7495 
7496  i2 = ilp2;
7497  end2 = row2->nlpcols;
7498  }
7499 
7500  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7501  while( i1 < end1 && i2 < end2 )
7502  {
7503  assert(row1->cols[i1]->index == row1colsidx[i1]);
7504  assert(row2->cols[i2]->index == row2colsidx[i2]);
7505  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7506 
7507  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7508  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7509  {
7510  ++prod;
7511  ++i1;
7512  ++i2;
7513  }
7514  /* increase smallest counter */
7515  else if( row1colsidx[i1] < row2colsidx[i2] )
7516  ++i1;
7517  else
7518  ++i2;
7519  }
7520  }
7521  }
7522 
7523  return prod;
7524 }
7525 
7526 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7527  * p = |v*w|/(|v|*|w|);
7528  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7529  */
7531  SCIP_ROW* row1, /**< first LP row */
7532  SCIP_ROW* row2, /**< second LP row */
7533  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7534  )
7535 {
7536  SCIP_Real parallelism;
7537  SCIP_Real scalarprod;
7538 
7539  switch( orthofunc )
7540  {
7541  case 'e':
7542  scalarprod = SCIProwGetScalarProduct(row1, row2);
7543  if( scalarprod == 0.0 )
7544  {
7545  parallelism = 0.0;
7546  break;
7547  }
7548 
7549  if( SCIProwGetNorm(row1) == 0.0 )
7550  {
7551  /* In theory, this should not happen if the scalarproduct is not zero
7552  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7553  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7554  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7555  */
7556  int i;
7557  for( i = 0; i < row1->len; ++i )
7558  if( row1->cols[i]->lppos >= 0 )
7559  row1->sqrnorm += SQR(row1->vals[i]);
7560  assert(SCIProwGetNorm(row1) != 0.0);
7561  }
7562 
7563  if( SCIProwGetNorm(row2) == 0.0 )
7564  {
7565  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7566  int i;
7567  for( i = 0; i < row2->len; ++i )
7568  if( row2->cols[i]->lppos >= 0 )
7569  row2->sqrnorm += SQR(row2->vals[i]);
7570  assert(SCIProwGetNorm(row2) != 0.0);
7571  }
7572 
7573  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7574  break;
7575 
7576  case 'd':
7577  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7578  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7579  break;
7580 
7581  default:
7582  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7583  SCIPABORT();
7584  parallelism = 0.0; /*lint !e527*/
7585  }
7586 
7587  return parallelism;
7588 }
7589 
7590 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7591  * o = 1 - |v*w|/(|v|*|w|);
7592  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7593  */
7595  SCIP_ROW* row1, /**< first LP row */
7596  SCIP_ROW* row2, /**< second LP row */
7597  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7598  )
7599 {
7600  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7601 }
7602 
7603 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7604  * function, if the value is 0, it is orthogonal to the objective function
7605  */
7607  SCIP_ROW* row, /**< LP row */
7608  SCIP_SET* set, /**< global SCIP settings */
7609  SCIP_LP* lp /**< current LP data */
7610  )
7611 {
7612  SCIP_Real prod;
7613  SCIP_Real parallelism;
7614 
7615  assert(row != NULL);
7616  assert(lp != NULL);
7617 
7618  if( lp->objsqrnormunreliable )
7619  SCIPlpRecalculateObjSqrNorm(set, lp);
7620 
7621  assert(!lp->objsqrnormunreliable);
7622  assert(lp->objsqrnorm >= 0.0);
7623 
7624  checkRowSqrnorm(row);
7625  checkRowObjprod(row);
7626 
7627  prod = row->sqrnorm * lp->objsqrnorm;
7628 
7629  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7630  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7631  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7632  parallelism = MIN(parallelism, 1.0);
7633  parallelism = MAX(parallelism, 0.0);
7634 
7635  return parallelism;
7636 }
7637 
7638 /** includes event handler with given data in row's event filter */
7640  SCIP_ROW* row, /**< row */
7641  BMS_BLKMEM* blkmem, /**< block memory */
7642  SCIP_SET* set, /**< global SCIP settings */
7643  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7644  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7645  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7646  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7647  )
7648 {
7649  assert(row != NULL);
7650  assert(row->eventfilter != NULL);
7651  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7652  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7653 
7654  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7655  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7656 
7657  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7658 
7659  return SCIP_OKAY;
7660 }
7661 
7662 /** deletes event handler with given data from row's event filter */
7664  SCIP_ROW* row, /**< row */
7665  BMS_BLKMEM* blkmem, /**< block memory */
7666  SCIP_SET* set, /**< global SCIP settings */
7667  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7668  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7669  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7670  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7671  )
7672 {
7673  assert(row != NULL);
7674  assert(row->eventfilter != NULL);
7675 
7676  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7677 
7678  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7679 
7680  return SCIP_OKAY;
7681 }
7682 
7683 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7685  SCIP_ROW* row, /**< LP row */
7686  SCIP_STAT* stat /**< problem statistics */
7687  )
7688 {
7689  assert(row != NULL);
7690  assert(stat != NULL);
7691  assert(stat->nnodes > 0);
7692 
7693  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7694  row->obsoletenode = stat->nnodes;
7695 }
7696 
7697 /*
7698  * LP solver data update
7699  */
7700 
7701 /** resets column data to represent a column not in the LP solver */
7702 static
7704  SCIP_COL* col /**< column to be marked deleted */
7705  )
7706 {
7707  assert(col != NULL);
7708 
7709  col->lpipos = -1;
7710  col->primsol = 0.0;
7711  col->redcost = SCIP_INVALID;
7712  col->farkascoef = SCIP_INVALID;
7713  col->sbdown = SCIP_INVALID;
7714  col->sbup = SCIP_INVALID;
7715  col->sbdownvalid = FALSE;
7716  col->sbupvalid = FALSE;
7717  col->validredcostlp = -1;
7718  col->validfarkaslp = -1;
7719  col->sbitlim = -1;
7720  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7721 }
7722 
7723 /** applies all cached column removals to the LP solver */
7724 static
7726  SCIP_LP* lp /**< current LP data */
7727  )
7728 {
7729  assert(lp != NULL);
7730  assert(lp->lpifirstchgcol <= lp->nlpicols);
7731  assert(lp->lpifirstchgcol <= lp->ncols);
7732 
7733  /* find the first column to change */
7734  while( lp->lpifirstchgcol < lp->nlpicols
7735  && lp->lpifirstchgcol < lp->ncols
7736  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7737  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7738  {
7739  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7740  lp->lpifirstchgcol++;
7741  }
7742 
7743  /* shrink LP to the part which didn't change */
7744  if( lp->lpifirstchgcol < lp->nlpicols )
7745  {
7746  int i;
7747 
7748  assert(!lp->diving);
7749  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7750  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7751  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7752  {
7753  markColDeleted(lp->lpicols[i]);
7754  }
7755  lp->nlpicols = lp->lpifirstchgcol;
7756  lp->flushdeletedcols = TRUE;
7757  lp->updateintegrality = TRUE;
7758 
7759  /* mark the LP unsolved */
7760  lp->solved = FALSE;
7761  lp->primalfeasible = FALSE;
7762  lp->primalchecked = FALSE;
7763  lp->lpobjval = SCIP_INVALID;
7765  }
7766  assert(lp->nlpicols == lp->lpifirstchgcol);
7767 
7768  return SCIP_OKAY;
7769 }
7770 
7771 /** computes for the given column the lower and upper bound that should be flushed into the LP
7772  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7773  * the bounds are explicitly added to the LP in any case
7774  */
7775 static
7777  SCIP_LP* lp, /**< current LP data */
7778  SCIP_SET* set, /**< global SCIP settings */
7779  SCIP_COL* col, /**< column to compute bounds for */
7780  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7781  SCIP_Real* lb, /**< pointer to store the new lower bound */
7782  SCIP_Real* ub /**< pointer to store the new upper bound */
7783  )
7784 {
7785  assert(lp != NULL);
7786  assert(set != NULL);
7787  assert(col != NULL);
7788  assert(lb != NULL);
7789  assert(ub != NULL);
7790 
7791  /* get the correct new lower bound:
7792  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7793  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7794  */
7795  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7796  (*lb) = -lpiinf;
7797  else
7798  (*lb) = col->lb;
7799  /* get the correct new upper bound:
7800  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7801  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7802  */
7803  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7804  (*ub) = lpiinf;
7805  else
7806  (*ub) = col->ub;
7807 }
7808 
7809 /** applies all cached column additions to the LP solver */
7810 static
7812  SCIP_LP* lp, /**< current LP data */
7813  BMS_BLKMEM* blkmem, /**< block memory */
7814  SCIP_SET* set, /**< global SCIP settings */
7815  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7816  )
7817 {
7818  SCIP_Real* obj;
7819  SCIP_Real* lb;
7820  SCIP_Real* ub;
7821  int* beg;
7822  int* ind;
7823  SCIP_Real* val;
7824  char** name;
7825  SCIP_COL* col;
7826  SCIP_Real lpiinf;
7827  int c;
7828  int pos;
7829  int nnonz;
7830  int naddcols;
7831  int naddcoefs;
7832  int i;
7833  int lpipos;
7834 
7835  assert(lp != NULL);
7836  assert(lp->lpifirstchgcol == lp->nlpicols);
7837  assert(blkmem != NULL);
7838  assert(set != NULL);
7839 
7840  /* if there are no columns to add, we are ready */
7841  if( lp->ncols == lp->nlpicols )
7842  return SCIP_OKAY;
7843 
7844  /* add the additional columns */
7845  assert(!lp->diving);
7846  assert(lp->ncols > lp->nlpicols);
7847  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
7848 
7849  /* get the solver's infinity value */
7850  lpiinf = SCIPlpiInfinity(lp->lpi);
7851 
7852  /* count the (maximal) number of added coefficients, calculate the number of added columns */
7853  naddcols = lp->ncols - lp->nlpicols;
7854  naddcoefs = 0;
7855  for( c = lp->nlpicols; c < lp->ncols; ++c )
7856  naddcoefs += lp->cols[c]->len;
7857  assert(naddcols > 0);
7858 
7859  /* get temporary memory for changes */
7860  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
7861  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
7862  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
7863  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
7864  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
7865  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
7866  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
7867 
7868  /* fill temporary memory with column data */
7869  nnonz = 0;
7870  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
7871  {
7872  col = lp->cols[c];
7873  assert(col != NULL);
7874  assert(col->var != NULL);
7875  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
7876  assert(SCIPvarGetCol(col->var) == col);
7877  assert(col->lppos == c);
7878  assert(nnonz + col->nlprows <= naddcoefs);
7879 
7880  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
7881  debugColPrint(set, col);
7882 
7883  /* Because the column becomes a member of the LP solver, it now can take values
7884  * different from zero. That means, we have to include the column in the corresponding
7885  * row vectors.
7886  */
7887  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
7888 
7889  lp->lpicols[c] = col;
7890  col->lpipos = c;
7891  col->primsol = SCIP_INVALID;
7892  col->redcost = SCIP_INVALID;
7893  col->farkascoef = SCIP_INVALID;
7894  col->sbdown = SCIP_INVALID;
7895  col->sbup = SCIP_INVALID;
7896  col->sbdownvalid = FALSE;
7897  col->sbupvalid = FALSE;
7898  col->validredcostlp = -1;
7899  col->validfarkaslp = -1;
7900  col->sbitlim = -1;
7901  col->objchanged = FALSE;
7902  col->lbchanged = FALSE;
7903  col->ubchanged = FALSE;
7904  col->coefchanged = FALSE;
7905  obj[pos] = col->obj;
7906 
7907  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
7908  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
7909 
7910  beg[pos] = nnonz;
7911  name[pos] = (char*)SCIPvarGetName(col->var);
7912 
7913  col->flushedobj = obj[pos];
7914  col->flushedlb = lb[pos];
7915  col->flushedub = ub[pos];
7916 
7917  for( i = 0; i < col->nlprows; ++i )
7918  {
7919  assert(col->rows[i] != NULL);
7920  lpipos = col->rows[i]->lpipos;
7921  if( lpipos >= 0 )
7922  {
7923  assert(lpipos < lp->nrows);
7924  assert(nnonz < naddcoefs);
7925  ind[nnonz] = lpipos;
7926  val[nnonz] = col->vals[i];
7927  nnonz++;
7928  }
7929  }
7930 #ifndef NDEBUG
7931  for( i = col->nlprows; i < col->len; ++i )
7932  {
7933  assert(col->rows[i] != NULL);
7934  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
7935  }
7936 #endif
7937  }
7938 
7939  /* call LP interface */
7940  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
7941  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
7942  lp->nlpicols = lp->ncols;
7943  lp->lpifirstchgcol = lp->nlpicols;
7944 
7945  /* free temporary memory */
7946  SCIPsetFreeBufferArray(set, &name);
7947  SCIPsetFreeBufferArray(set, &val);
7948  SCIPsetFreeBufferArray(set, &ind);
7949  SCIPsetFreeBufferArray(set, &beg);
7950  SCIPsetFreeBufferArray(set, &ub);
7951  SCIPsetFreeBufferArray(set, &lb);
7952  SCIPsetFreeBufferArray(set, &obj);
7953 
7954  lp->flushaddedcols = TRUE;
7955  lp->updateintegrality = TRUE;
7956 
7957  /* mark the LP unsolved */
7958  lp->solved = FALSE;
7959  lp->dualfeasible = FALSE;
7960  lp->dualchecked = FALSE;
7961  lp->lpobjval = SCIP_INVALID;
7963 
7964  return SCIP_OKAY;
7965 }
7966 
7967 /** resets row data to represent a row not in the LP solver */
7968 static
7970  SCIP_ROW* row /**< row to be marked deleted */
7971  )
7972 {
7973  assert(row != NULL);
7974 
7975  row->lpipos = -1;
7976  row->dualsol = 0.0;
7977  row->activity = SCIP_INVALID;
7978  row->dualfarkas = 0.0;
7979  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7980  row->validactivitylp = -1;
7981 }
7982 
7983 /** applies all cached row removals to the LP solver */
7984 static
7986  SCIP_LP* lp, /**< current LP data */
7987  BMS_BLKMEM* blkmem, /**< block memory */
7988  SCIP_SET* set /**< global SCIP settings */
7989  )
7990 {
7991  assert(lp != NULL);
7992  assert(lp->lpifirstchgrow <= lp->nlpirows);
7993  assert(lp->lpifirstchgrow <= lp->nrows);
7994 
7995  /* find the first row to change */
7996  while( lp->lpifirstchgrow < lp->nlpirows
7997  && lp->lpifirstchgrow < lp->nrows
7998  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
7999  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8000  {
8001  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8002  lp->lpifirstchgrow++;
8003  }
8004 
8005  /* shrink LP to the part which didn't change */
8006  if( lp->lpifirstchgrow < lp->nlpirows )
8007  {
8008  int i;
8009 
8010  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8011  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8012  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8013  {
8014  markRowDeleted(lp->lpirows[i]);
8015  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8016  }
8017  lp->nlpirows = lp->lpifirstchgrow;
8018  lp->flushdeletedrows = TRUE;
8019 
8020  /* mark the LP unsolved */
8021  lp->solved = FALSE;
8022  lp->dualfeasible = FALSE;
8023  lp->dualchecked = FALSE;
8024  lp->lpobjval = SCIP_INVALID;
8026  }
8027  assert(lp->nlpirows == lp->lpifirstchgrow);
8028 
8029  return SCIP_OKAY;
8030 }
8031 
8032 /** applies all cached row additions and removals to the LP solver */
8033 static
8035  SCIP_LP* lp, /**< current LP data */
8036  BMS_BLKMEM* blkmem, /**< block memory */
8037  SCIP_SET* set, /**< global SCIP settings */
8038  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8039  )
8040 {
8041  SCIP_Real* lhs;
8042  SCIP_Real* rhs;
8043  int* beg;
8044  int* ind;
8045  SCIP_Real* val;
8046  char** name;
8047  SCIP_ROW* row;
8048  SCIP_Real lpiinf;
8049  int r;
8050  int pos;
8051  int nnonz;
8052  int naddrows;
8053  int naddcoefs;
8054  int i;
8055  int lpipos;
8056 
8057  assert(lp != NULL);
8058  assert(lp->lpifirstchgrow == lp->nlpirows);
8059  assert(blkmem != NULL);
8060 
8061  /* if there are no rows to add, we are ready */
8062  if( lp->nrows == lp->nlpirows )
8063  return SCIP_OKAY;
8064 
8065  /* add the additional rows */
8066  assert(lp->nrows > lp->nlpirows);
8067  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8068 
8069  /* get the solver's infinity value */
8070  lpiinf = SCIPlpiInfinity(lp->lpi);
8071 
8072  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8073  naddrows = lp->nrows - lp->nlpirows;
8074  naddcoefs = 0;
8075  for( r = lp->nlpirows; r < lp->nrows; ++r )
8076  naddcoefs += lp->rows[r]->len;
8077  assert(naddrows > 0);
8078 
8079  /* get temporary memory for changes */
8080  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8081  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8082  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8083  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8084  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8085  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8086 
8087  /* fill temporary memory with row data */
8088  nnonz = 0;
8089  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8090  {
8091  row = lp->rows[r];
8092  assert(row != NULL);
8093  assert(row->lppos == r);
8094  assert(nnonz + row->nlpcols <= naddcoefs);
8095 
8096  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8097  debugRowPrint(set, row);
8098 
8099  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8100  * different from zero. That means, we have to include the row in the corresponding
8101  * column vectors.
8102  */
8103  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8104 
8105  SCIProwCapture(row);
8106  lp->lpirows[r] = row;
8107  row->lpipos = r;
8108  row->dualsol = SCIP_INVALID;
8109  row->activity = SCIP_INVALID;
8110  row->dualfarkas = SCIP_INVALID;
8111  row->validactivitylp = -1;
8112  row->lhschanged = FALSE;
8113  row->rhschanged = FALSE;
8114  row->coefchanged = FALSE;
8115  if( SCIPsetIsInfinity(set, -row->lhs) )
8116  lhs[pos] = -lpiinf;
8117  else
8118  lhs[pos] = row->lhs - row->constant;
8119  if( SCIPsetIsInfinity(set, row->rhs) )
8120  rhs[pos] = lpiinf;
8121  else
8122  rhs[pos] = row->rhs - row->constant;
8123  beg[pos] = nnonz;
8124  name[pos] = row->name;
8125 
8126  row->flushedlhs = lhs[pos];
8127  row->flushedrhs = rhs[pos];
8128 
8129  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8130  for( i = 0; i < row->nlpcols; ++i )
8131  {
8132  assert(row->cols[i] != NULL);
8133  lpipos = row->cols[i]->lpipos;
8134  if( lpipos >= 0 )
8135  {
8136  assert(lpipos < lp->ncols);
8137  assert(nnonz < naddcoefs);
8138  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8139  ind[nnonz] = lpipos;
8140  val[nnonz] = row->vals[i];
8141  nnonz++;
8142  }
8143  }
8144  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8145 #ifndef NDEBUG
8146  for( i = row->nlpcols; i < row->len; ++i )
8147  {
8148  assert(row->cols[i] != NULL);
8149  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8150  }
8151 #endif
8152  }
8153 
8154  /* call LP interface */
8155  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8156  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8157  lp->nlpirows = lp->nrows;
8158  lp->lpifirstchgrow = lp->nlpirows;
8159 
8160  /* free temporary memory */
8161  SCIPsetFreeBufferArray(set, &name);
8162  SCIPsetFreeBufferArray(set, &val);
8163  SCIPsetFreeBufferArray(set, &ind);
8164  SCIPsetFreeBufferArray(set, &beg);
8165  SCIPsetFreeBufferArray(set, &rhs);
8166  SCIPsetFreeBufferArray(set, &lhs);
8167 
8168  lp->flushaddedrows = TRUE;
8169 
8170  /* mark the LP unsolved */
8171  lp->solved = FALSE;
8172  lp->primalfeasible = FALSE;
8173  lp->primalchecked = FALSE;
8174  lp->lpobjval = SCIP_INVALID;
8176 
8177  return SCIP_OKAY;
8178 }
8179 
8180 /** applies all cached column bound and objective changes to the LP */
8181 static
8183  SCIP_LP* lp, /**< current LP data */
8184  SCIP_SET* set /**< global SCIP settings */
8185  )
8186 {
8187 #ifndef NDEBUG
8188  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8189 #endif
8190  SCIP_COL* col;
8191  int* objind;
8192  int* bdind;
8193  SCIP_Real* obj;
8194  SCIP_Real* lb;
8195  SCIP_Real* ub;
8196  SCIP_Real lpiinf;
8197  int nobjchg;
8198  int nbdchg;
8199  int i;
8200 
8201  assert(lp != NULL);
8202 
8203  if( lp->nchgcols == 0 )
8204  return SCIP_OKAY;
8205 
8206  /* get the solver's infinity value */
8207  lpiinf = SCIPlpiInfinity(lp->lpi);
8208 
8209  /* get temporary memory for changes */
8210  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8211  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8212  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8213  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8214  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8215 
8216  /* collect all cached bound and objective changes */
8217  nobjchg = 0;
8218  nbdchg = 0;
8219  for( i = 0; i < lp->nchgcols; ++i )
8220  {
8221  col = lp->chgcols[i];
8222  assert(col != NULL);
8223  assert(col->var != NULL);
8224  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8225  assert(SCIPvarGetCol(col->var) == col);
8226 
8227  if( col->lpipos >= 0 )
8228  {
8229 #ifndef NDEBUG
8230  /* do not check consistency of data with LPI in case of LPI=none */
8231  if( !lpinone )
8232  {
8233  SCIP_Real lpiobj;
8234  SCIP_Real lpilb;
8235  SCIP_Real lpiub;
8236 
8237  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8238  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8239  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8240  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8241  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8242  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8243  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8244  }
8245 #endif
8246 
8247  if( col->objchanged )
8248  {
8249  SCIP_Real newobj;
8250 
8251  newobj = col->obj;
8252  if( col->flushedobj != newobj ) /*lint !e777*/
8253  {
8254  assert(nobjchg < lp->ncols);
8255  objind[nobjchg] = col->lpipos;
8256  obj[nobjchg] = newobj;
8257  nobjchg++;
8258  col->flushedobj = newobj;
8259  }
8260  col->objchanged = FALSE;
8261  }
8262 
8263  if( col->lbchanged || col->ubchanged )
8264  {
8265  SCIP_Real newlb;
8266  SCIP_Real newub;
8267 
8268  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8269  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8270 
8271  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8272  {
8273  assert(nbdchg < lp->ncols);
8274  bdind[nbdchg] = col->lpipos;
8275  lb[nbdchg] = newlb;
8276  ub[nbdchg] = newub;
8277  nbdchg++;
8278  col->flushedlb = newlb;
8279  col->flushedub = newub;
8280  }
8281  col->lbchanged = FALSE;
8282  col->ubchanged = FALSE;
8283  }
8284  }
8285  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8286  }
8287 
8288  /* change objective values in LP */
8289  if( nobjchg > 0 )
8290  {
8291  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8292  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8293 
8294  /* mark the LP unsolved */
8295  lp->solved = FALSE;
8296  lp->dualfeasible = FALSE;
8297  lp->dualchecked = FALSE;
8298  lp->lpobjval = SCIP_INVALID;
8300  }
8301 
8302  /* change bounds in LP */
8303  if( nbdchg > 0 )
8304  {
8305  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8306  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8307 
8308  /* mark the LP unsolved */
8309  lp->solved = FALSE;
8310  lp->primalfeasible = FALSE;
8311  lp->primalchecked = FALSE;
8312  lp->lpobjval = SCIP_INVALID;
8314  }
8315 
8316  lp->nchgcols = 0;
8317 
8318  /* free temporary memory */
8319  SCIPsetFreeBufferArray(set, &ub);
8320  SCIPsetFreeBufferArray(set, &lb);
8321  SCIPsetFreeBufferArray(set, &bdind);
8322  SCIPsetFreeBufferArray(set, &obj);
8323  SCIPsetFreeBufferArray(set, &objind);
8324 
8325  return SCIP_OKAY;
8326 }
8327 
8328 /** applies all cached row side changes to the LP */
8329 static
8331  SCIP_LP* lp, /**< current LP data */
8332  SCIP_SET* set /**< global SCIP settings */
8333  )
8334 {
8335 #ifndef NDEBUG
8336  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8337 #endif
8338  SCIP_ROW* row;
8339  int* ind;
8340  SCIP_Real* lhs;
8341  SCIP_Real* rhs;
8342  SCIP_Real lpiinf;
8343  int i;
8344  int nchg;
8345 
8346  assert(lp != NULL);
8347 
8348  if( lp->nchgrows == 0 )
8349  return SCIP_OKAY;
8350 
8351  /* get the solver's infinity value */
8352  lpiinf = SCIPlpiInfinity(lp->lpi);
8353 
8354  /* get temporary memory for changes */
8355  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8356  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8357  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8358 
8359  /* collect all cached left and right hand side changes */
8360  nchg = 0;
8361  for( i = 0; i < lp->nchgrows; ++i )
8362  {
8363  row = lp->chgrows[i];
8364  assert(row != NULL);
8365 
8366  if( row->lpipos >= 0 )
8367  {
8368 #ifndef NDEBUG
8369  /* do not check consistency of data with LPI in case of LPI=none */
8370  if( !lpinone )
8371  {
8372  SCIP_Real lpilhs;
8373  SCIP_Real lpirhs;
8374 
8375  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8376  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8377  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8378  }
8379 #endif
8380  if( row->lhschanged || row->rhschanged )
8381  {
8382  SCIP_Real newlhs;
8383  SCIP_Real newrhs;
8384 
8385  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8386  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8387  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8388  {
8389  assert(nchg < lp->nrows);
8390  ind[nchg] = row->lpipos;
8391  lhs[nchg] = newlhs;
8392  rhs[nchg] = newrhs;
8393  nchg++;
8394  row->flushedlhs = newlhs;
8395  row->flushedrhs = newrhs;
8396  }
8397  row->lhschanged = FALSE;
8398  row->rhschanged = FALSE;
8399  }
8400  }
8401  }
8402 
8403  /* change left and right hand sides in LP */
8404  if( nchg > 0 )
8405  {
8406  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8407  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8408 
8409  /* mark the LP unsolved */
8410  lp->solved = FALSE;
8411  lp->primalfeasible = FALSE;
8412  lp->primalchecked = FALSE;
8413  lp->lpobjval = SCIP_INVALID;
8415  }
8416 
8417  lp->nchgrows = 0;
8418 
8419  /* free temporary memory */
8420  SCIPsetFreeBufferArray(set, &rhs);
8421  SCIPsetFreeBufferArray(set, &lhs);
8422  SCIPsetFreeBufferArray(set, &ind);
8423 
8424  return SCIP_OKAY;
8425 }
8426 
8427 /** copy integrality information to the LP */
8428 static
8430  SCIP_LP* lp, /**< current LP data */
8431  SCIP_SET* set /**< global SCIP settings */
8432  )
8433 {
8434  int i;
8435  int nintegers;
8436  int* integerInfo;
8437  SCIP_VAR* var;
8438 
8439  assert(lp != NULL);
8440 
8441  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8442 
8443  /* count total number of integralities */
8444  nintegers = 0;
8445 
8446  for( i = 0; i < lp->ncols; ++i )
8447  {
8448  var = SCIPcolGetVar(lp->cols[i]);
8449  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8450  {
8451  integerInfo[i] = 1;
8452  ++nintegers;
8453  }
8454  else
8455  integerInfo[i] = 0;
8456  }
8457 
8458  /* only pass integrality information if integer variables are present */
8459  if( nintegers > 0 )
8460  {
8461  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8462  }
8463  else
8464  {
8466  }
8467 
8468  SCIPsetFreeBufferArray(set, &integerInfo);
8469 
8470  /* mark integralities to be updated */
8471  lp->updateintegrality = FALSE;
8472 
8473  return SCIP_OKAY;
8474 }
8475 
8476 /** applies all cached changes to the LP solver */
8478  SCIP_LP* lp, /**< current LP data */
8479  BMS_BLKMEM* blkmem, /**< block memory */
8480  SCIP_SET* set, /**< global SCIP settings */
8481  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8482  )
8483 {
8484  assert(lp != NULL);
8485  assert(blkmem != NULL);
8486 
8487  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",
8488  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8489 
8490  if( !lp->flushed )
8491  {
8492  lp->flushdeletedcols = FALSE;
8493  lp->flushaddedcols = FALSE;
8494  lp->flushdeletedrows = FALSE;
8495  lp->flushaddedrows = FALSE;
8496 
8497  SCIP_CALL( lpFlushDelCols(lp) );
8498  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8499  SCIP_CALL( lpFlushChgCols(lp, set) );
8500  SCIP_CALL( lpFlushChgRows(lp, set) );
8501  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8502  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8503 
8504  lp->flushed = TRUE;
8505 
8506  checkLinks(lp);
8507  }
8508 
8509  /* if the cutoff bound was changed in between, we want to re-optimize the LP even if nothing else has changed */
8510  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 ) /*lint !e777*/
8511  lp->solved = FALSE;
8512 
8513  assert(lp->nlpicols == lp->ncols);
8514  assert(lp->lpifirstchgcol == lp->nlpicols);
8515  assert(lp->nlpirows == lp->nrows);
8516  assert(lp->lpifirstchgrow == lp->nlpirows);
8517  assert(lp->nchgcols == 0);
8518  assert(lp->nchgrows == 0);
8519 #ifndef NDEBUG
8520  {
8521  int ncols;
8522  int nrows;
8523 
8524  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8525  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8526  assert(ncols == lp->ncols);
8527  assert(nrows == lp->nrows);
8528  }
8529 #endif
8530 
8531  return SCIP_OKAY;
8532 }
8533 
8534 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8536  SCIP_LP* lp, /**< current LP data */
8537  SCIP_SET* set /**< global SCIP settings */
8538  )
8539 {
8540 #ifndef NDEBUG
8541  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8542 #endif
8543  int i;
8544 
8545  assert(lp != NULL);
8546 
8547 #ifndef NDEBUG
8548  /* check, if there are really no column or row deletions or coefficient changes left */
8549  while( lp->lpifirstchgcol < lp->nlpicols
8550  && lp->lpifirstchgcol < lp->ncols
8551  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8552  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8553  {
8554  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8555  lp->lpifirstchgcol++;
8556  }
8557  assert(lp->nlpicols == lp->lpifirstchgcol);
8558 
8559  while( lp->lpifirstchgrow < lp->nlpirows
8560  && lp->lpifirstchgrow < lp->nrows
8561  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8562  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8563  {
8564  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8565  lp->lpifirstchgrow++;
8566  }
8567  assert(lp->nlpirows == lp->lpifirstchgrow);
8568 #endif
8569 
8570  lp->lpifirstchgcol = lp->nlpicols;
8571  lp->lpifirstchgrow = lp->nlpirows;
8572 
8573  /* check, if there are really no column or row additions left */
8574  assert(lp->ncols == lp->nlpicols);
8575  assert(lp->nrows == lp->nlpirows);
8576 
8577  /* mark the changed columns to be unchanged, and check, if this is really correct */
8578  for( i = 0; i < lp->nchgcols; ++i )
8579  {
8580  SCIP_COL* col;
8581 
8582  col = lp->chgcols[i];
8583  assert(col != NULL);
8584  assert(col->var != NULL);
8585  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8586  assert(SCIPvarGetCol(col->var) == col);
8587 
8588  if( col->lpipos >= 0 )
8589  {
8590 #ifndef NDEBUG
8591  /* do not check consistency of data with LPI in case of LPI=none */
8592  if( !lpinone )
8593  {
8594  SCIP_Real lpiobj;
8595  SCIP_Real lpilb;
8596  SCIP_Real lpiub;
8597 
8598  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8599  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8600  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8601  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8602  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8603  assert(col->flushedobj == col->obj); /*lint !e777*/
8604  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8605  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8606  }
8607 #endif
8608  col->objchanged = FALSE;
8609  col->lbchanged = FALSE;
8610  col->ubchanged = FALSE;
8611  }
8612  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8613  }
8614  lp->nchgcols = 0;
8615 
8616  /* mark the changed rows to be unchanged, and check, if this is really correct */
8617  for( i = 0; i < lp->nchgrows; ++i )
8618  {
8619  SCIP_ROW* row;
8620 
8621  row = lp->chgrows[i];
8622  assert(row != NULL);
8623 
8624  if( row->lpipos >= 0 )
8625  {
8626 #ifndef NDEBUG
8627  /* do not check consistency of data with LPI in case of LPI=none */
8628  if( !lpinone )
8629  {
8630  SCIP_Real lpilhs;
8631  SCIP_Real lpirhs;
8632 
8633  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8634  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8635  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8636  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8637  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8638  }
8639 #endif
8640  row->lhschanged = FALSE;
8641  row->rhschanged = FALSE;
8642  }
8643  }
8644  lp->nchgrows = 0;
8645 
8646  /* mark the LP to be flushed */
8647  lp->flushed = TRUE;
8648 
8649  checkLinks(lp);
8650 
8651  return SCIP_OKAY;
8652 }
8653 
8654 
8655 
8656 
8657 /*
8658  * LP methods
8659  */
8660 
8661 /** updates link data after addition of column */
8662 static
8664  SCIP_COL* col, /**< LP column */
8665  SCIP_SET* set /**< global SCIP settings */
8666  )
8667 {
8668  SCIP_ROW* row;
8669  int i;
8670  int pos;
8671 
8672  assert(col != NULL);
8673  assert(col->lppos >= 0);
8674 
8675  /* update column arrays of all linked rows */
8676  for( i = 0; i < col->len; ++i )
8677  {
8678  pos = col->linkpos[i];
8679  if( pos >= 0 )
8680  {
8681  row = col->rows[i];
8682  assert(row != NULL);
8683  assert(row->linkpos[pos] == i);
8684  assert(row->cols[pos] == col);
8685  assert(row->nlpcols <= pos && pos < row->len);
8686 
8687  row->nlpcols++;
8688  rowSwapCoefs(row, pos, row->nlpcols-1);
8689  assert(row->cols[row->nlpcols-1] == col);
8690 
8691  /* if no swap was necessary, mark lpcols to be unsorted */
8692  if( pos == row->nlpcols-1 )
8693  row->lpcolssorted = FALSE;
8694 
8695  /* update norms */
8696  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8697  }
8698  }
8699 }
8700 
8701 /** updates link data after addition of row */
8702 static
8704  SCIP_ROW* row /**< LP row */
8705  )
8706 {
8707  SCIP_COL* col;
8708  int i;
8709  int pos;
8710 
8711  assert(row != NULL);
8712  assert(row->lppos >= 0);
8713 
8714  /* update row arrays of all linked columns */
8715  for( i = 0; i < row->len; ++i )
8716  {
8717  pos = row->linkpos[i];
8718  if( pos >= 0 )
8719  {
8720  col = row->cols[i];
8721  assert(col != NULL);
8722  assert(col->linkpos[pos] == i);
8723  assert(col->rows[pos] == row);
8724  assert(col->nlprows <= pos && pos < col->len);
8725 
8726  col->nlprows++;
8727  colSwapCoefs(col, pos, col->nlprows-1);
8728 
8729  /* if no swap was necessary, mark lprows to be unsorted */
8730  if( pos == col->nlprows-1 )
8731  col->lprowssorted = FALSE;
8732  }
8733  }
8734 }
8735 
8736 /** updates link data after removal of column */
8737 static
8739  SCIP_COL* col, /**< LP column */
8740  SCIP_SET* set /**< global SCIP settings */
8741  )
8742 {
8743  SCIP_ROW* row;
8744  int i;
8745  int pos;
8746 
8747  assert(col != NULL);
8748  assert(col->lppos == -1);
8749 
8750  /* update column arrays of all linked rows */
8751  for( i = 0; i < col->len; ++i )
8752  {
8753  pos = col->linkpos[i];
8754  if( pos >= 0 )
8755  {
8756  row = col->rows[i];
8757  assert(row != NULL);
8758  assert(row->linkpos[pos] == i);
8759  assert(row->cols[pos] == col);
8760  assert(0 <= pos && pos < row->nlpcols);
8761 
8762  /* update norms */
8763  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8764 
8765  row->nlpcols--;
8766  rowSwapCoefs(row, pos, row->nlpcols);
8767 
8768  /* if no swap was necessary, mark nonlpcols to be unsorted */
8769  if( pos == row->nlpcols )
8770  row->nonlpcolssorted = FALSE;
8771  }
8772  }
8773 }
8774 
8775 /** updates link data after removal of row */
8776 static
8778  SCIP_ROW* row /**< LP row */
8779  )
8780 {
8781  SCIP_COL* col;
8782  int i;
8783  int pos;
8784 
8785  assert(row != NULL);
8786  assert(row->lppos == -1);
8787 
8788  /* update row arrays of all linked columns */
8789  for( i = 0; i < row->len; ++i )
8790  {
8791  pos = row->linkpos[i];
8792  if( pos >= 0 )
8793  {
8794  col = row->cols[i];
8795  assert(col != NULL);
8796  assert(0 <= pos && pos < col->nlprows);
8797  assert(col->linkpos[pos] == i);
8798  assert(col->rows[pos] == row);
8799 
8800  col->nlprows--;
8801  colSwapCoefs(col, pos, col->nlprows);
8802 
8803  /* if no swap was necessary, mark lprows to be unsorted */
8804  if( pos == col->nlprows )
8805  col->nonlprowssorted = FALSE;
8806  }
8807  }
8808 }
8809 
8810 static
8812  SCIP_LP* lp, /**< LP data object */
8813  int initsize /**< initial size of the arrays */
8814  )
8815 {
8816  assert(lp != NULL);
8817  assert(lp->divechgsides == NULL);
8818  assert(lp->divechgsidetypes == NULL);
8819  assert(lp->divechgrows == NULL);
8820  assert(lp->ndivechgsides == 0);
8821  assert(lp->divechgsidessize == 0);
8822  assert(initsize > 0);
8823 
8824  lp->divechgsidessize = initsize;
8828 
8829  return SCIP_OKAY;
8830 }
8831 
8832 static
8834  SCIP_LP* lp, /**< LP data object */
8835  int minsize, /**< minimal number of elements */
8836  SCIP_Real growfact /**< growing factor */
8837  )
8838 {
8839  assert(lp != NULL);
8840  assert(lp->divechgsides != NULL);
8841  assert(lp->divechgsidetypes != NULL);
8842  assert(lp->divechgrows != NULL);
8843  assert(lp->ndivechgsides > 0);
8844  assert(lp->divechgsidessize > 0);
8845  assert(minsize > 0);
8846 
8847  if( minsize <= lp->divechgsidessize )
8848  return SCIP_OKAY;
8849 
8850  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
8854 
8855  return SCIP_OKAY;
8856 }
8857 
8858 static
8860  SCIP_LP* lp /**< LP data object */
8861  )
8862 {
8863  assert(lp != NULL);
8864  assert(lp->divechgsides != NULL);
8865  assert(lp->divechgsidetypes != NULL);
8866  assert(lp->divechgrows != NULL);
8867  assert(lp->ndivechgsides == 0);
8868  assert(lp->divechgsidessize > 0);
8869 
8873  lp->divechgsidessize = 0;
8874 }
8875 
8876 #define DIVESTACKINITSIZE 100
8877 
8878 /** creates empty LP data object */
8880  SCIP_LP** lp, /**< pointer to LP data object */
8881  SCIP_SET* set, /**< global SCIP settings */
8882  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
8883  SCIP_STAT* stat, /**< problem statistics */
8884  const char* name /**< problem name */
8885  )
8886 {
8887  SCIP_Bool success;
8888 
8889  assert(lp != NULL);
8890  assert(set != NULL);
8891  assert(stat != NULL);
8892  assert(name != NULL);
8893 
8894  SCIP_ALLOC( BMSallocMemory(lp) );
8895 
8896  /* open LP Solver interface */
8897  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
8898 
8899  (*lp)->lpicols = NULL;
8900  (*lp)->lpirows = NULL;
8901  (*lp)->chgcols = NULL;
8902  (*lp)->chgrows = NULL;
8903  (*lp)->cols = NULL;
8904  (*lp)->lazycols = NULL;
8905  (*lp)->rows = NULL;
8906  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
8907  (*lp)->lpobjval = 0.0;
8908  (*lp)->glbpseudoobjval = 0.0;
8909  (*lp)->relglbpseudoobjval = 0.0;
8910  (*lp)->glbpseudoobjvalid = TRUE;
8911  (*lp)->glbpseudoobjvalinf = 0;
8912  (*lp)->pseudoobjval = 0.0;
8913  (*lp)->relpseudoobjval = 0.0;
8914  (*lp)->pseudoobjvalid = TRUE;
8915  (*lp)->pseudoobjvalinf = 0;
8916  (*lp)->looseobjval = 0.0;
8917  (*lp)->rellooseobjval = 0.0;
8918  (*lp)->looseobjvalid = TRUE;
8919  (*lp)->looseobjvalinf = 0;
8920  (*lp)->nloosevars = 0;
8921  (*lp)->rootlpobjval = SCIP_INVALID;
8922  (*lp)->rootlooseobjval = SCIP_INVALID;
8923  (*lp)->cutoffbound = SCIPsetInfinity(set);
8924  (*lp)->objsqrnorm = 0.0;
8925  (*lp)->objsumnorm = 0.0;
8926  (*lp)->lpicolssize = 0;
8927  (*lp)->nlpicols = 0;
8928  (*lp)->lpirowssize = 0;
8929  (*lp)->nlpirows = 0;
8930  (*lp)->lpifirstchgcol = 0;
8931  (*lp)->lpifirstchgrow = 0;
8932  (*lp)->colssize = 0;
8933  (*lp)->ncols = 0;
8934  (*lp)->lazycolssize = 0;
8935  (*lp)->nlazycols = 0;
8936  (*lp)->rowssize = 0;
8937  (*lp)->nrows = 0;
8938  (*lp)->chgcolssize = 0;
8939  (*lp)->nchgcols = 0;
8940  (*lp)->chgrowssize = 0;
8941  (*lp)->nchgrows = 0;
8942  (*lp)->firstnewcol = 0;
8943  (*lp)->firstnewrow = 0;
8944  (*lp)->nremovablecols = 0;
8945  (*lp)->nremovablerows = 0;
8946  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
8947  (*lp)->validfarkaslp = -1;
8948  (*lp)->objsqrnormunreliable = FALSE;
8949  (*lp)->flushdeletedcols = FALSE;
8950  (*lp)->flushaddedcols = FALSE;
8951  (*lp)->flushdeletedrows = FALSE;
8952  (*lp)->flushaddedrows = FALSE;
8953  (*lp)->updateintegrality = TRUE;
8954  (*lp)->flushed = TRUE;
8955  (*lp)->solved = TRUE;
8956  (*lp)->primalfeasible = TRUE;
8957  (*lp)->primalchecked = TRUE;
8958  (*lp)->dualfeasible = TRUE;
8959  (*lp)->dualchecked = TRUE;
8960  (*lp)->solisbasic = FALSE;
8961  (*lp)->rootlpisrelax = TRUE;
8962  (*lp)->isrelax = TRUE;
8963  (*lp)->installing = FALSE;
8964  (*lp)->strongbranching = FALSE;
8965  (*lp)->strongbranchprobing = FALSE;
8966  (*lp)->probing = FALSE;
8967  (*lp)->diving = FALSE;
8968  (*lp)->divingobjchg = FALSE;
8969  (*lp)->divinglazyapplied = FALSE;
8970  (*lp)->divelpistate = NULL;
8971  (*lp)->divelpwasprimfeas = TRUE;
8972  (*lp)->divelpwasprimchecked = TRUE;
8973  (*lp)->divelpwasdualfeas = TRUE;
8974  (*lp)->divelpwasdualchecked = TRUE;
8975  (*lp)->divechgsides = NULL;
8976  (*lp)->divechgsidetypes = NULL;
8977  (*lp)->divechgrows = NULL;
8978  (*lp)->ndivechgsides = 0;
8979  (*lp)->divechgsidessize = 0;
8980  (*lp)->ndivingrows = 0;
8981  (*lp)->divinglpiitlim = INT_MAX;
8982  (*lp)->resolvelperror = FALSE;
8983  (*lp)->divenolddomchgs = 0;
8984  (*lp)->adjustlpval = FALSE;
8985  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
8986  (*lp)->lpifeastol = SCIPsetLpfeastol(set);
8987  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
8988  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
8989  (*lp)->lpifromscratch = FALSE;
8990  (*lp)->lpifastmip = set->lp_fastmip;
8991  (*lp)->lpiscaling = set->lp_scaling;
8992  (*lp)->lpipresolving = set->lp_presolving;
8993  (*lp)->lpilpinfo = set->disp_lpinfo;
8994  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
8995  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
8996  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
8997  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
8998  (*lp)->lpiitlim = INT_MAX;
8999  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9000  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9001  (*lp)->lpithreads = set->lp_threads;
9002  (*lp)->lpitiming = (int) set->time_clocktype;
9003  (*lp)->lpirandomseed = set->random_randomseed;
9004  (*lp)->storedsolvals = NULL;
9005 
9006  /* allocate arrays for diving */
9008 
9009  /* set default parameters in LP solver */
9010  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9011  if( !success )
9012  {
9013  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9014  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9016  }
9017  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9018  (*lp)->lpihasfeastol = success;
9019  if( !success )
9020  {
9021  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9022  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9024  }
9025  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9026  (*lp)->lpihasdualfeastol = success;
9027  if( !success )
9028  {
9029  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9030  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9032  }
9033  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9034  (*lp)->lpihasbarrierconvtol = success;
9035  if( !success )
9036  {
9037  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9038  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9040  }
9041  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9042  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9043  (*lp)->lpihasfastmip = success;
9044  if( !success )
9045  {
9046  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9047  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9049  }
9050  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9051  (*lp)->lpihasscaling = success;
9052  if( !success )
9053  {
9054  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9055  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9057  }
9058  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9059  (*lp)->lpihaspresolving = success;
9060  if( !success )
9061  {
9062  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9063  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9065  }
9066  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9067  if( !success )
9068  {
9069  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9070  "LP Solver <%s>: clock type cannot be set\n",
9072  }
9073  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9074  if( !success )
9075  {
9076  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9077  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9079  }
9080  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9081  if( !success )
9082  {
9083  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9084  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9086  }
9087  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9088  if( !success )
9089  {
9090  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9091  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9093  }
9094  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9095  (*lp)->lpihasrowrep = success;
9096  if( !success )
9097  {
9098  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9099  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9101  }
9102  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9103  (*lp)->lpihaspolishing = success;
9104  if( !success )
9105  {
9106  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9107  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9109  }
9110  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9111  (*lp)->lpihasrefactor = success;
9112  if( !success )
9113  {
9114  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9115  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9117  }
9118  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9119  if( !success )
9120  {
9121  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9122  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9124  }
9125  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9126  if( !success )
9127  {
9128  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9129  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9131  }
9132  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9133  if( (*lp)->lpirandomseed != 0 )
9134  {
9135  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9136  if( !success )
9137  {
9138  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9139  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9141  }
9142  }
9143 
9144  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9145  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9146  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9147  {
9148  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9149  return SCIP_PARAMETERWRONGVAL;
9150  }
9151 
9152  return SCIP_OKAY;
9153 }
9154 
9155 /** frees LP data object */
9157  SCIP_LP** lp, /**< pointer to LP data object */
9158  BMS_BLKMEM* blkmem, /**< block memory */
9159  SCIP_SET* set, /**< global SCIP settings */
9160  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9161  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9162  )
9163 {
9164  int i;
9165 
9166  assert(lp != NULL);
9167  assert(*lp != NULL);
9168 
9169  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9170 
9171  freeDiveChgSideArrays(*lp);
9172 
9173  /* release LPI rows */
9174  for( i = 0; i < (*lp)->nlpirows; ++i )
9175  {
9176  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9177  }
9178 
9179  if( (*lp)->lpi != NULL )
9180  {
9181  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9182  }
9183 
9184  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9185  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9186  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9187  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9188  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9189  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9190  BMSfreeMemoryArrayNull(&(*lp)->cols);
9191  BMSfreeMemoryArrayNull(&(*lp)->rows);
9192  BMSfreeMemory(lp);
9193 
9194  return SCIP_OKAY;
9195 }
9196 
9197 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9198  * changes to the LP solver
9199  */
9201  SCIP_LP* lp, /**< LP data */
9202  BMS_BLKMEM* blkmem, /**< block memory */
9203  SCIP_SET* set, /**< global SCIP settings */
9204  SCIP_STAT* stat, /**< problem statistics */
9205  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9206  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9207  )
9208 {
9209  assert(stat != NULL);
9210 
9211  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9212  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9213 
9214  /* mark the empty LP to be solved */
9216  lp->lpobjval = 0.0;
9217  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9218  lp->validfarkaslp = -1;
9219  lp->solved = TRUE;
9220  lp->primalfeasible = TRUE;
9221  lp->primalchecked = TRUE;
9222  lp->dualfeasible = TRUE;
9223  lp->dualchecked = TRUE;
9224  lp->solisbasic = FALSE;
9226 
9227  return SCIP_OKAY;
9228 }
9229 
9230 /** adds a column to the LP */
9232  SCIP_LP* lp, /**< LP data */
9233  SCIP_SET* set, /**< global SCIP settings */
9234  SCIP_COL* col, /**< LP column */
9235  int depth /**< depth in the tree where the column addition is performed */
9236  )
9237 {
9238  assert(lp != NULL);
9239  assert(!lp->diving);
9240  assert(col != NULL);
9241  assert(col->len == 0 || col->rows != NULL);
9242  assert(col->lppos == -1);
9243  assert(col->var != NULL);
9244  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9245  assert(SCIPvarGetCol(col->var) == col);
9246  assert(SCIPvarIsIntegral(col->var) == col->integral);
9247 
9248  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9249 #ifdef SCIP_DEBUG
9250  {
9251  int i;
9252  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9253  for( i = 0; i < col->len; ++i )
9254  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9255  SCIPsetDebugMsgPrint(set, "\n");
9256  }
9257 #endif
9258 
9259  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9260  lp->cols[lp->ncols] = col;
9261  col->lppos = lp->ncols;
9262  col->lpdepth = depth;
9263  col->age = 0;
9264  lp->ncols++;
9265  if( col->removable )
9266  lp->nremovablecols++;
9267 
9268  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9269  {
9270  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9271  lp->lazycols[lp->nlazycols] = col;
9272  lp->nlazycols++;
9273  }
9274 
9275  /* mark the current LP unflushed */
9276  lp->flushed = FALSE;
9277 
9278  /* update column arrays of all linked rows */
9279  colUpdateAddLP(col, set);
9280 
9281  /* update the objective function vector norms */
9282  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9283 
9284  checkLinks(lp);
9285 
9286  return SCIP_OKAY;
9287 }
9288 
9289 /** adds a row to the LP and captures it */
9291  SCIP_LP* lp, /**< LP data */
9292  BMS_BLKMEM* blkmem, /**< block memory buffers */
9293  SCIP_SET* set, /**< global SCIP settings */
9294  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9295  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9296  SCIP_ROW* row, /**< LP row */
9297  int depth /**< depth in the tree where the row addition is performed */
9298  )
9299 {
9300  assert(lp != NULL);
9301  assert(row != NULL);
9302  assert(row->len == 0 || row->cols != NULL);
9303  assert(row->lppos == -1);
9304 
9305  SCIProwCapture(row);
9306  SCIProwLock(row);
9307 
9308  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9309 #ifdef SCIP_DEBUG
9310  {
9311  int i;
9312  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9313  for( i = 0; i < row->len; ++i )
9314  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9315  if( !SCIPsetIsZero(set, row->constant) )
9316  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9317  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9318  }
9319 #endif
9320 
9321  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9322  lp->rows[lp->nrows] = row;
9323  row->lppos = lp->nrows;
9324  row->lpdepth = depth;
9325  row->age = 0;
9326  lp->nrows++;
9327  if( row->removable )
9328  lp->nremovablerows++;
9329 
9330  /* mark the current LP unflushed */
9331  lp->flushed = FALSE;
9332 
9333  /* update row arrays of all linked columns */
9334  rowUpdateAddLP(row);
9335 
9336  checkLinks(lp);
9337 
9338  rowCalcNorms(row, set);
9339 
9340  /* check, if row addition to LP events are tracked
9341  * if so, issue ROWADDEDLP event
9342  */
9343  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9344  {
9345  SCIP_EVENT* event;
9346 
9347  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9348  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9349  }
9350 
9351  return SCIP_OKAY;
9352 }
9353 
9354 
9355 #ifndef NDEBUG
9356 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9357  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9358  * the lazycols array
9359  */
9360 static
9362  SCIP_LP* lp, /**< LP data */
9363  SCIP_SET* set /**< global SCIP settings */
9364  )
9365 {
9366  SCIP_Bool contained;
9367  int c;
9368  int i;
9369 
9370  assert(lp != NULL);
9371 
9372  /* check if each column in the lazy column array has a counter part in the column array */
9373  for( i = 0; i < lp->nlazycols; ++i )
9374  {
9375  /* check if each lazy column has at least on lazy bound */
9376  assert(lp->lazycols[i] != NULL);
9377  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9378 
9379  contained = FALSE;
9380  for( c = 0; c < lp->ncols; ++c )
9381  {
9382  if( lp->lazycols[i] == lp->cols[c] )
9383  {
9384  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9385  contained = TRUE;
9386  }
9387  }
9388  assert(contained);
9389  }
9390 
9391  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9392  * array */
9393  for( c = 0; c < lp->ncols; ++c )
9394  {
9395  contained = FALSE;
9396  assert(lp->cols[c] != NULL);
9397 
9398  for( i = 0; i < lp->nlazycols; ++i )
9399  {
9400  if( lp->lazycols[i] == lp->cols[c] )
9401  {
9402  contained = TRUE;
9403  }
9404  }
9405 
9406  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9407  }
9408 }
9409 #else
9410 #define checkLazyColArray(lp, set) /**/
9411 #endif
9412 
9413 /** removes all columns after the given number of cols from the LP */
9415  SCIP_LP* lp, /**< LP data */
9416  SCIP_SET* set, /**< global SCIP settings */
9417  int newncols /**< new number of columns in the LP */
9418  )
9419 {
9420  SCIP_COL* col;
9421  int c;
9422 
9423  assert(lp != NULL);
9424 
9425  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9426  assert(0 <= newncols);
9427  assert(newncols <= lp->ncols);
9428 
9429  if( newncols < lp->ncols )
9430  {
9431  assert(!lp->diving);
9432 
9433  for( c = lp->ncols-1; c >= newncols; --c )
9434  {
9435  col = lp->cols[c];
9436  assert(col != NULL);
9437  assert(col->len == 0 || col->rows != NULL);
9438  assert(col->var != NULL);
9439  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9440  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9441  assert(col->lppos == c);
9442 
9443  /* mark column to be removed from the LP */
9444  col->lppos = -1;
9445  col->lpdepth = -1;
9446  lp->ncols--;
9447 
9448  /* count removable columns */
9449  if( col->removable )
9450  lp->nremovablecols--;
9451 
9452  /* update column arrays of all linked rows */
9453  colUpdateDelLP(col, set);
9454 
9455  /* update the objective function vector norms */
9456  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9457  }
9458  assert(lp->ncols == newncols);
9459  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9460 
9461  /* remove columns which are deleted from the lazy column array */
9462  c = 0;
9463  while( c < lp->nlazycols )
9464  {
9465  if( lp->lazycols[c]->lppos < 0 )
9466  {
9467  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9468  lp->nlazycols--;
9469  }
9470  else
9471  c++;
9472  }
9473 
9474  /* mark the current LP unflushed */
9475  lp->flushed = FALSE;
9476 
9477  checkLazyColArray(lp, set);
9478  checkLinks(lp);
9479  }
9480  assert(lp->nremovablecols <= lp->ncols);
9481 
9482  return SCIP_OKAY;
9483 }
9484 
9485 /** removes and releases all rows after the given number of rows from the LP */
9487  SCIP_LP* lp, /**< LP data */
9488  BMS_BLKMEM* blkmem, /**< block memory */
9489  SCIP_SET* set, /**< global SCIP settings */
9490  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9491  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9492  int newnrows /**< new number of rows in the LP */
9493  )
9494 {
9495  SCIP_ROW* row;
9496  int r;
9497 
9498  assert(lp != NULL);
9499  assert(0 <= newnrows && newnrows <= lp->nrows);
9500 
9501  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9502  if( newnrows < lp->nrows )
9503  {
9504  for( r = lp->nrows-1; r >= newnrows; --r )
9505  {
9506  row = lp->rows[r];
9507  assert(row != NULL);
9508  assert(row->len == 0 || row->cols != NULL);
9509  assert(row->lppos == r);
9510 
9511  /* mark row to be removed from the LP */
9512  row->lppos = -1;
9513  row->lpdepth = -1;
9514  lp->nrows--;
9515 
9516  /* count removable rows */
9517  if( row->removable )
9518  lp->nremovablerows--;
9519 
9520  /* update row arrays of all linked columns */
9521  rowUpdateDelLP(row);
9522 
9523  SCIProwUnlock(lp->rows[r]);
9524 
9525  /* check, if row deletion events are tracked
9526  * if so, issue ROWDELETEDLP event
9527  */
9528  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9529  {
9530  SCIP_EVENT* event;
9531 
9532  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9533  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9534  }
9535 
9536  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9537  }
9538  assert(lp->nrows == newnrows);
9539  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9540 
9541  /* mark the current LP unflushed */
9542  lp->flushed = FALSE;
9543 
9544  checkLinks(lp);
9545  }
9546  assert(lp->nremovablerows <= lp->nrows);
9547 
9548  return SCIP_OKAY;
9549 }
9550 
9551 /** removes all columns and rows from LP, releases all rows */
9553  SCIP_LP* lp, /**< LP data */
9554  BMS_BLKMEM* blkmem, /**< block memory */
9555  SCIP_SET* set, /**< global SCIP settings */
9556  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9557  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9558  )
9559 {
9560  assert(lp != NULL);
9561  assert(!lp->diving);
9562 
9563  SCIPsetDebugMsg(set, "clearing LP\n");
9564  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9565  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9566 
9567  return SCIP_OKAY;
9568 }
9569 
9570 /** remembers number of columns and rows to track the newly added ones */
9572  SCIP_LP* lp /**< current LP data */
9573  )
9574 {
9575  assert(lp != NULL);
9576  assert(!lp->diving);
9577 
9578  lp->firstnewrow = lp->nrows;
9579  lp->firstnewcol = lp->ncols;
9580 }
9581 
9582 /** sets the remembered number of columns and rows to the given values */
9584  SCIP_LP* lp, /**< current LP data */
9585  int nrows, /**< number of rows to set the size marker to */
9586  int ncols /**< number of columns to set the size marker to */
9587  )
9588 {
9589  assert(lp != NULL);
9590  assert(!lp->diving);
9591 
9592  lp->firstnewrow = nrows;
9593  lp->firstnewcol = ncols;
9594 }
9595 
9596 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9598  SCIP_LP* lp, /**< LP data */
9599  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9600  )
9601 {
9602  assert(lp != NULL);
9603  assert(lp->flushed);
9604  assert(lp->solved);
9605  assert(lp->solisbasic);
9606  assert(basisind != NULL);
9607 
9608  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9609 
9610  return SCIP_OKAY;
9611 }
9612 
9613 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9615  SCIP_LP* lp, /**< LP data */
9616  int* cstat, /**< array to store column basis status, or NULL */
9617  int* rstat /**< array to store row basis status, or NULL */
9618  )
9619 {
9620  assert(lp != NULL);
9621  assert(lp->flushed);
9622  assert(lp->solved);
9623  assert(lp->solisbasic);
9624 
9625  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9626 
9627  return SCIP_OKAY;
9628 }
9629 
9630 /** gets a row from the inverse basis matrix B^-1 */
9632  SCIP_LP* lp, /**< LP data */
9633  int r, /**< row number */
9634  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9635  int* inds, /**< array to store the non-zero indices, or NULL */
9636  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9637  * (-1: if we do not store sparsity informations) */
9638  )
9639 {
9640  assert(lp != NULL);
9641  assert(lp->flushed);
9642  assert(lp->solved);
9643  assert(lp->solisbasic);
9644  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9645  assert(coef != NULL);
9646 
9647  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9648 
9649  return SCIP_OKAY;
9650 }
9651 
9652 /** gets a column from the inverse basis matrix B^-1 */
9654  SCIP_LP* lp, /**< LP data */
9655  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9656  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9657  * to get the array which links the B^-1 column numbers to the row and
9658  * column numbers of the LP! c must be between 0 and nrows-1, since the
9659  * basis has the size nrows * nrows */
9660  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9661  int* inds, /**< array to store the non-zero indices, or NULL */
9662  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9663  * (-1: if we do not store sparsity informations) */
9664  )
9665 {
9666  assert(lp != NULL);
9667  assert(lp->flushed);
9668  assert(lp->solved);
9669  assert(lp->solisbasic);
9670  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9671  assert(coef != NULL);
9672 
9673  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9674 
9675  return SCIP_OKAY;
9676 }
9677 
9678 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9680  SCIP_LP* lp, /**< LP data */
9681  int r, /**< row number */
9682  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9683  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9684  int* inds, /**< array to store the non-zero indices, or NULL */
9685  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9686  * (-1: if we do not store sparsity informations) */
9687  )
9688 {
9689  assert(lp != NULL);
9690  assert(lp->flushed);
9691  assert(lp->solved);
9692  assert(lp->solisbasic);
9693  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9694  assert(coef != NULL);
9695 
9696  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9697 
9698  return SCIP_OKAY;
9699 }
9700 
9701 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9702  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9703  */
9705  SCIP_LP* lp, /**< LP data */
9706  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9707  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9708  int* inds, /**< array to store the non-zero indices, or NULL */
9709  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9710  * (-1: if we do not store sparsity informations) */
9711  )
9712 {
9713  assert(lp != NULL);
9714  assert(lp->flushed);
9715  assert(lp->solved);
9716  assert(lp->solisbasic);
9717  assert(0 <= c && c < lp->ncols);
9718  assert(coef != NULL);
9719 
9720  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9721 
9722  return SCIP_OKAY;
9723 }
9724 
9725 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9726  * LP row are swapped in the summation
9727  */
9729  SCIP_LP* lp, /**< LP data */
9730  SCIP_SET* set, /**< global SCIP settings */
9731  SCIP_PROB* prob, /**< problem data */
9732  SCIP_Real* weights, /**< row weights in row summation */
9733  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9734  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9735  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9736  )
9737 {
9738  SCIP_ROW* row;
9739  int r;
9740  int i;
9741  int idx;
9742  SCIP_Bool lhsinfinite;
9743  SCIP_Bool rhsinfinite;
9744 
9745  assert(lp != NULL);
9746  assert(prob != NULL);
9747  assert(weights != NULL);
9748  assert(sumcoef != NULL);
9749  assert(sumlhs != NULL);
9750  assert(sumrhs != NULL);
9751 
9752  /**@todo test, if a column based summation is faster */
9753 
9754  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9755  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9756  *sumlhs = 0.0;
9757  *sumrhs = 0.0;
9758  lhsinfinite = FALSE;
9759  rhsinfinite = FALSE;
9760  for( r = 0; r < lp->nrows; ++r )
9761  {
9762  if( !SCIPsetIsZero(set, weights[r]) )
9763  {
9764  row = lp->rows[r];
9765  assert(row != NULL);
9766  assert(row->len == 0 || row->cols != NULL);
9767  assert(row->len == 0 || row->cols_index != NULL);
9768  assert(row->len == 0 || row->vals != NULL);
9769 
9770  /* add the row coefficients to the sum */
9771  for( i = 0; i < row->len; ++i )
9772  {
9773  assert(row->cols[i] != NULL);
9774  assert(row->cols[i]->var != NULL);
9775  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9776  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9777  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9778  idx = row->cols[i]->var_probindex;
9779  assert(0 <= idx && idx < prob->nvars);
9780  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9781  }
9782 
9783  /* add the row sides to the sum, depending on the sign of the weight */
9784  if( weights[r] > 0.0 )
9785  {
9786  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9787  if( !lhsinfinite )
9788  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9789  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9790  if( !rhsinfinite )
9791  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9792  }
9793  else
9794  {
9795  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9796  if( !lhsinfinite )
9797  (*sumlhs) += weights[r] * (row->rhs - row->constant);
9798  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9799  if( !rhsinfinite )
9800  (*sumrhs) += weights[r] * (row->lhs - row->constant);
9801  }
9802  }
9803  }
9804 
9805  if( lhsinfinite )
9806  *sumlhs = -SCIPsetInfinity(set);
9807  if( rhsinfinite )
9808  *sumrhs = SCIPsetInfinity(set);
9809 
9810  return SCIP_OKAY;
9811 }
9812 
9813 /** stores LP state (like basis information) into LP state object */
9815  SCIP_LP* lp, /**< LP data */
9816  BMS_BLKMEM* blkmem, /**< block memory */
9817  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9818  )
9819 {
9820  assert(lp != NULL);
9821  assert(lp->flushed);
9822  assert(lp->solved);
9823  assert(blkmem != NULL);
9824  assert(lpistate != NULL);
9825 
9826  /* check whether there is no lp */
9827  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9828  *lpistate = NULL;
9829  else
9830  {
9831  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
9832  }
9833 
9834  return SCIP_OKAY;
9835 }
9836 
9837 /** loads LP state (like basis information) into solver */
9839  SCIP_LP* lp, /**< LP data */
9840  BMS_BLKMEM* blkmem, /**< block memory */
9841  SCIP_SET* set, /**< global SCIP settings */
9842  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9843  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
9844  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
9845  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
9846  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
9847  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
9848  )
9849 {
9850  assert(lp != NULL);
9851  assert(blkmem != NULL);
9852 
9853  /* flush changes to the LP solver */
9854  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9855  assert(lp->flushed);
9856 
9857  if( lp->solved && lp->solisbasic )
9858  return SCIP_OKAY;
9859 
9860  /* set LPI state in the LP solver */
9861  if( lpistate == NULL )
9862  lp->solisbasic = FALSE;
9863  else
9864  {
9865  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
9866  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
9867  }
9868  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
9869  * flushed and solved, also, e.g., when we hit the iteration limit
9870  */
9871  lp->primalfeasible = wasprimfeas;
9872  lp->primalchecked = wasprimchecked;
9873  lp->dualfeasible = wasdualfeas;
9874  lp->dualchecked = wasdualchecked;
9875 
9876  return SCIP_OKAY;
9877 }
9878 
9879 /** frees LP state information */
9881  SCIP_LP* lp, /**< LP data */
9882  BMS_BLKMEM* blkmem, /**< block memory */
9883  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9884  )
9885 {
9886  assert(lp != NULL);
9887 
9888  if( *lpistate != NULL )
9889  {
9890  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
9891  }
9892 
9893  return SCIP_OKAY;
9894 }
9895 
9896 /** stores pricing norms into LP norms object */
9898  SCIP_LP* lp, /**< LP data */
9899  BMS_BLKMEM* blkmem, /**< block memory */
9900  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9901  )
9902 {
9903  assert(lp != NULL);
9904  assert(lp->flushed);
9905  assert(lp->solved);
9906  assert(blkmem != NULL);
9907  assert(lpinorms != NULL);
9908 
9909  /* check whether there is no lp */
9910  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9911  *lpinorms = NULL;
9912  else
9913  {
9914  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
9915  }
9916 
9917  return SCIP_OKAY;
9918 }
9919 
9920 /** loads pricing norms from LP norms object into solver */
9922  SCIP_LP* lp, /**< LP data */
9923  BMS_BLKMEM* blkmem, /**< block memory */
9924  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
9925  )
9926 {
9927  assert(lp != NULL);
9928  assert(blkmem != NULL);
9929  assert(lp->flushed);
9930 
9931  /* set LPI norms in the LP solver */
9932  if( lpinorms != NULL )
9933  {
9934  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
9935  }
9936 
9937  return SCIP_OKAY;
9938 }
9939 
9940 /** frees pricing norms information */
9942  SCIP_LP* lp, /**< LP data */
9943  BMS_BLKMEM* blkmem, /**< block memory */
9944  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9945  )
9946 {
9947  assert(lp != NULL);
9948 
9949  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
9950 
9951  return SCIP_OKAY;
9952 }
9953 
9954 /** return the current cutoff bound of the lp */
9956  SCIP_LP* lp /**< current LP data */
9957  )
9958 {
9959  assert(lp != NULL);
9960 
9961  return lp->cutoffbound;
9962 }
9963 
9964 /** sets the upper objective limit of the LP solver */
9966  SCIP_LP* lp, /**< current LP data */
9967  SCIP_SET* set, /**< global SCIP settings */
9968  SCIP_PROB* prob, /**< problem data */
9969  SCIP_Real cutoffbound /**< new upper objective limit */
9970  )
9971 {
9972  assert(lp != NULL);
9973 
9974  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
9975 
9976  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
9977  * in SCIPendDive())
9978  */
9979  if( SCIPlpDivingObjChanged(lp) )
9980  {
9981  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
9982  return SCIP_OKAY;
9983  }
9984 
9985  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
9986  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
9987  {
9988  /* mark the current solution invalid */
9989  lp->solved = FALSE;
9990  lp->lpobjval = SCIP_INVALID;
9992  }
9993  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
9994  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
9995  */
9997  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
9998  {
9999  assert(lp->flushed);
10000  assert(lp->solved);
10002  }
10003 
10004  lp->cutoffbound = cutoffbound;
10005 
10006  return SCIP_OKAY;
10007 }
10008 
10009 /** returns the name of the given LP algorithm */
10010 static
10011 const char* lpalgoName(
10012  SCIP_LPALGO lpalgo /**< LP algorithm */
10013  )
10014 {
10015  switch( lpalgo )
10016  {
10018  return "primal simplex";
10020  return "dual simplex";
10021  case SCIP_LPALGO_BARRIER:
10022  return "barrier";
10024  return "barrier/crossover";
10025  default:
10026  SCIPerrorMessage("invalid LP algorithm\n");
10027  SCIPABORT();
10028  return "invalid"; /*lint !e527*/
10029  }
10030 }
10031 
10032 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10033 static
10035  SCIP_LP* lp, /**< current LP data */
10036  SCIP_SET* set, /**< global SCIP settings */
10037  SCIP_STAT* stat, /**< problem statistics */
10038  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10039  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10040  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10041  )
10042 {
10043  SCIP_Real timedelta;
10044  SCIP_RETCODE retcode;
10045  int iterations;
10046 
10047  assert(lp != NULL);
10048  assert(lp->flushed);
10049  assert(set != NULL);
10050  assert(stat != NULL);
10051  assert(lperror != NULL);
10052 
10053  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",
10054  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10055 
10056  *lperror = FALSE;
10057 
10058 #if 0 /* for debugging: write all root node LP's */
10059  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10060  {
10061  char fname[SCIP_MAXSTRLEN];
10062  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10063  SCIP_CALL( SCIPlpWrite(lp, fname) );
10064  SCIPsetDebugMsg("wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10065  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10066  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10067  }
10068 #endif
10069 
10070  /* start timing */
10071  if( lp->diving || lp->probing )
10072  {
10073  if( lp->strongbranchprobing )
10074  SCIPclockStart(stat->strongbranchtime, set);
10075  else
10076  SCIPclockStart(stat->divinglptime, set);
10077 
10078  timedelta = 0.0; /* unused for diving or probing */
10079  }
10080  else
10081  {
10082  SCIPclockStart(stat->primallptime, set);
10083  timedelta = -SCIPclockGetTime(stat->primallptime);
10084  }
10085 
10086  /* call primal simplex */
10087  retcode = SCIPlpiSolvePrimal(lp->lpi);
10088  if( retcode == SCIP_LPERROR )
10089  {
10090  *lperror = TRUE;
10091  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10092  }
10093  else
10094  {
10095  SCIP_CALL( retcode );
10096  }
10098  lp->solisbasic = TRUE;
10099 
10100  /* stop timing */
10101  if( lp->diving || lp->probing )
10102  {
10103  if( lp->strongbranchprobing )
10104  SCIPclockStop(stat->strongbranchtime, set);
10105  else
10106  SCIPclockStop(stat->divinglptime, set);
10107  }
10108  else
10109  {
10110  timedelta += SCIPclockGetTime(stat->primallptime);
10111  SCIPclockStop(stat->primallptime, set);
10112  }
10113 
10114  /* count number of iterations */
10115  SCIPstatIncrement(stat, set, lpcount);
10116  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10117  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10118  {
10119  if( !lp->strongbranchprobing )
10120  {
10121  SCIPstatIncrement(stat, set, nlps);
10122  SCIPstatAdd( stat, set, nlpiterations, iterations );
10123  }
10124  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10125  {
10126  SCIPstatIncrement(stat, set, nprimalresolvelps );
10127  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10128  }
10129  if( lp->diving || lp->probing )
10130  {
10131  if( lp->strongbranchprobing )
10132  {
10133  SCIPstatIncrement(stat, set, nsbdivinglps);
10134  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10135  }
10136  else
10137  {
10138  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10139  SCIPstatIncrement(stat, set, ndivinglps);
10140  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10141  }
10142  }
10143  else
10144  {
10145  SCIPstatIncrement(stat, set, nprimallps);
10146  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10147  }
10148  }
10149  else
10150  {
10151  if ( ! lp->diving && ! lp->probing )
10152  {
10153  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10154  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10155  }
10156 
10157  if ( keepsol && !(*lperror) )
10158  {
10159  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10160  if( lp->validsollp == stat->lpcount-1 )
10161  lp->validsollp = stat->lpcount;
10162  if( lp->validfarkaslp == stat->lpcount-1 )
10163  lp->validfarkaslp = stat->lpcount;
10164  }
10165  }
10166 
10167  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10168  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10169 
10170  return SCIP_OKAY;
10171 }
10172 
10173 /** calls LPI to perform dual simplex, measures time and counts iterations */
10174 static
10176  SCIP_LP* lp, /**< current LP data */
10177  SCIP_SET* set, /**< global SCIP settings */
10178  SCIP_STAT* stat, /**< problem statistics */
10179  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10180  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10181  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10182  )
10183 {
10184  SCIP_Real timedelta;
10185  SCIP_RETCODE retcode;
10186  int iterations;
10187 
10188  assert(lp != NULL);
10189  assert(lp->flushed);
10190  assert(set != NULL);
10191  assert(stat != NULL);
10192  assert(lperror != NULL);
10193 
10194  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",
10195  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10196 
10197  *lperror = FALSE;
10198 
10199 #if 0 /* for debugging: write all root node LP's */
10200  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10201  {
10202  char fname[SCIP_MAXSTRLEN];
10203  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10204  SCIP_CALL( SCIPlpWrite(lp, fname) );
10205  SCIPsetDebugMsg("wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10206  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10207  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10208  }
10209 #endif
10210 
10211  /* start timing */
10212  if( lp->diving || lp->probing )
10213  {
10214  if( lp->strongbranchprobing )
10215  SCIPclockStart(stat->strongbranchtime, set);
10216  else
10217  SCIPclockStart(stat->divinglptime, set);
10218 
10219  timedelta = 0.0; /* unused for diving or probing */
10220  }
10221  else
10222  {
10223  SCIPclockStart(stat->duallptime, set);
10224  timedelta = -SCIPclockGetTime(stat->duallptime);
10225  }
10226 
10227  /* call dual simplex */
10228  retcode = SCIPlpiSolveDual(lp->lpi);
10229  if( retcode == SCIP_LPERROR )
10230  {
10231  *lperror = TRUE;
10232  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10233  }
10234  else
10235  {
10236  SCIP_CALL( retcode );
10237  }
10239  lp->solisbasic = TRUE;
10240 
10241  /* stop timing */
10242  if( lp->diving || lp->probing )
10243  {
10244  if( lp->strongbranchprobing )
10245  SCIPclockStop(stat->strongbranchtime, set);
10246  else
10247  SCIPclockStop(stat->divinglptime, set);
10248  }
10249  else
10250  {
10251  timedelta += SCIPclockGetTime(stat->duallptime);
10252  SCIPclockStop(stat->duallptime, set);
10253  }
10254 
10255  /* count number of iterations */
10256  SCIPstatIncrement(stat, set, lpcount);
10257  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10258  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10259  {
10260  if( !lp->strongbranchprobing )
10261  {
10262  SCIPstatIncrement(stat, set, nlps);
10263  SCIPstatAdd(stat, set, nlpiterations, iterations);
10264  }
10265  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10266  {
10267  SCIPstatIncrement(stat, set, ndualresolvelps);
10268  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10269  }
10270  if( lp->diving || lp->probing )
10271  {
10272  if( lp->strongbranchprobing )
10273  {
10274  SCIPstatIncrement(stat, set, nsbdivinglps);
10275  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10276  }
10277  else
10278  {
10279  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10280  SCIPstatIncrement(stat, set, ndivinglps);
10281  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10282  }
10283  }
10284  else
10285  {
10286  SCIPstatIncrement(stat, set, nduallps);
10287  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10288  }
10289  }
10290  else
10291  {
10292  if ( ! lp->diving && ! lp->probing )
10293  {
10294  SCIPstatIncrement(stat, set, ndualzeroitlps);
10295  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10296  }
10297 
10298  if( keepsol && !(*lperror) )
10299  {
10300  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10301  if( lp->validsollp == stat->lpcount-1 )
10302  lp->validsollp = stat->lpcount;
10303  if( lp->validfarkaslp == stat->lpcount-1 )
10304  lp->validfarkaslp = stat->lpcount;
10305  }
10306  }
10307 
10308  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10309  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10310 
10311  return SCIP_OKAY;
10312 }
10313 
10314 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10315  *
10316  * We follow the approach of the following paper to find a lexicographically minimal optimal
10317  * solution:
10318  *
10319  * Zanette, Fischetti, Balas@n
10320  * Can pure cutting plane algorithms work?@n
10321  * IPCO 2008, Bertinoro, Italy.
10322  *
10323  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10324  * heuristic, i.e., we limit the number of components which are minimized.
10325  *
10326  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10327  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10328  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10329  * pivots that will not change the objective are allowed afterwards.
10330  *
10331  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10332  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10333  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10334  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10335  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10336  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10337  * reduced cost. We then choose the next variable and iterate.
10338  *
10339  * We stop the process once we do not find candidates or have performed a maximum number of
10340  * iterations.
10341  *
10342  * @todo Does this really produce a lexicographically minimal solution?
10343  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10344  * guarantee that these variables will not be changed in later stages? We can fix these variables
10345  * to their lower bound, but this destroys the basis.
10346  * @todo Should we use lexicographical minimization in diving/probing or not?
10347  */
10348 static
10350  SCIP_LP* lp, /**< current LP data */
10351  SCIP_SET* set, /**< global SCIP settings */
10352  SCIP_STAT* stat, /**< problem statistics */
10353  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10354  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10355  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10356  )
10357 {
10358  SCIP_Real timedelta;
10359  SCIP_RETCODE retcode;
10360  int totalIterations;
10361  int lexIterations;
10362  int iterations;
10363  int rounds;
10364 
10365  assert(lp != NULL);
10366  assert(lp->flushed);
10367  assert(set != NULL);
10368  assert(stat != NULL);
10369  assert(lperror != NULL);
10370 
10371  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",
10372  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10373 
10374  *lperror = FALSE;
10375 
10376  /* start timing */
10377  if( lp->diving || lp->probing )
10378  {
10379  if( lp->strongbranchprobing )
10380  SCIPclockStart(stat->strongbranchtime, set);
10381  else
10382  SCIPclockStart(stat->divinglptime, set);
10383 
10384  timedelta = 0.0; /* unused for diving or probing */
10385  }
10386  else
10387  {
10388  SCIPclockStart(stat->duallptime, set);
10389  timedelta = -SCIPclockGetTime(stat->duallptime);
10390  }
10391 
10392  /* call dual simplex for first lp */
10393  retcode = SCIPlpiSolveDual(lp->lpi);
10394  if( retcode == SCIP_LPERROR )
10395  {
10396  *lperror = TRUE;
10397  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10398  }
10399  else
10400  {
10401  SCIP_CALL( retcode );
10402  }
10403  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10404  totalIterations = iterations;
10405 
10406  /* stop timing */
10407  if( lp->diving || lp->probing )
10408  {
10409  if( lp->strongbranchprobing )
10410  SCIPclockStop(stat->strongbranchtime, set);
10411  else
10412  SCIPclockStop(stat->divinglptime, set);
10413  }
10414  else
10415  {
10416  timedelta += SCIPclockGetTime(stat->duallptime);
10417  SCIPclockStop(stat->duallptime, set);
10418  }
10419 
10420  /* count number of iterations */
10421  SCIPstatIncrement(stat, set, lpcount);
10422  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10423  {
10424  if( lp->strongbranchprobing )
10425  {
10426  SCIPstatAdd(stat, set, nlpiterations, iterations);
10427  }
10428  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10429  {
10430  SCIPstatIncrement(stat, set, ndualresolvelps);
10431  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10432  }
10433  if( lp->diving || lp->probing )
10434  {
10435  if( lp->strongbranchprobing )
10436  {
10437  SCIPstatIncrement(stat, set, nsbdivinglps);
10438  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10439  }
10440  else
10441  {
10442  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10443  SCIPstatIncrement(stat, set, ndivinglps);
10444  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10445  }
10446  }
10447  else
10448  {
10449  SCIPstatIncrement(stat, set, nduallps);
10450  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10451  }
10452  }
10453  else
10454  {
10455  if ( ! lp->diving && ! lp->probing )
10456  {
10457  SCIPstatIncrement(stat, set, ndualzeroitlps);
10458  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10459  }
10460  }
10461  lexIterations = 0;
10462 
10463  /* search for lexicographically minimal optimal solution */
10464  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10465  {
10466  SCIP_Bool chooseBasic;
10467  SCIP_Real* primsol;
10468  SCIP_Real* dualsol;
10469  SCIP_Real* redcost;
10470  int* cstat;
10471  int* rstat;
10472  SCIP_Real* newobj;
10473  SCIP_Real* newlb;
10474  SCIP_Real* newub;
10475  SCIP_Real* newlhs;
10476  SCIP_Real* newrhs;
10477  SCIP_Real* oldlb;
10478  SCIP_Real* oldub;
10479  SCIP_Real* oldlhs;
10480  SCIP_Real* oldrhs;
10481  SCIP_Real* oldobj;
10482  SCIP_Bool* fixedc;
10483  SCIP_Bool* fixedr;
10484  int* indcol;
10485  int* indrow;
10486  int* indallcol;
10487  int* indallrow;
10488  int nDualDeg;
10489  int r, c;
10490  int cntcol;
10491  int cntrow;
10492  int nruns;
10493  int pos;
10494 
10495  chooseBasic = set->lp_lexdualbasic;
10496 
10497  /* start timing */
10498  SCIPclockStart(stat->lexduallptime, set);
10499 
10500  /* get all solution information */
10501  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10502  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10503  if( chooseBasic )
10504  {
10505  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10506  }
10507  else
10508  primsol = NULL;
10509 
10510  /* get basic and nonbasic information */
10511  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10512  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10513 
10514  /* save bounds, lhs/rhs, and objective */
10515  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10516  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10517  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10518  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10519  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10520  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10521  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10522  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10523 
10524  /* get storage for several arrays */
10525  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10526  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10527  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10528 
10529  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10530  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10531  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10532 
10533  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10534  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10535 
10536  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10537  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10538 
10539  /* initialize: set objective to 0, get fixed variables */
10540  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10541  for( c = 0; c < lp->nlpicols; ++c )
10542  {
10543  newobj[c] = 0.0;
10544  indallcol[c] = c;
10545  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10546  fixedc[c] = TRUE;
10547  else
10548  fixedc[c] = FALSE;
10549  }
10550 
10551  /* initialize: get fixed slack variables */
10552  for( r = 0; r < lp->nlpirows; ++r )
10553  {
10554  indallrow[r] = r;
10555  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10556  fixedr[r] = TRUE;
10557  else
10558  fixedr[r] = FALSE;
10559  }
10560 
10561 #ifdef DEBUG_LEXDUAL
10562  {
10563  int j;
10564 
10565  if( !chooseBasic )
10566  {
10567  assert(primsol == NULL);
10568  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10569  }
10570  assert(primsol != NULL);
10571  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10572  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10573 
10574  for( j = 0; j < lp->nlpicols; ++j )
10575  {
10576  if( fixedc[j] )
10577  {
10578  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10579  }
10580  else
10581  {
10582  char type;
10583  switch( (SCIP_BASESTAT) cstat[j] )
10584  {
10585  case SCIP_BASESTAT_LOWER:
10586  type = 'l';
10587  break;
10588  case SCIP_BASESTAT_UPPER:
10589  type = 'u';
10590  break;
10591  case SCIP_BASESTAT_ZERO:
10592  type = 'z';
10593  break;
10594  case SCIP_BASESTAT_BASIC:
10595  type = 'b';
10596  break;
10597  default:
10598  type = '?';
10599  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10600  SCIPABORT();
10601  }
10602  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10603  }
10604  }
10605  SCIPsetDebugMsg(set, "\n\n");
10606 
10607  if( !chooseBasic )
10608  {
10609  SCIPsetFreeBufferArray(set, &primsol);
10610  assert(primsol == NULL);
10611  }
10612  }
10613 #endif
10614 
10615  /* perform lexicographic rounds */
10616  pos = -1;
10617  nruns = 0;
10618  rounds = 0;
10619  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10620  do
10621  {
10622  int oldpos;
10623 
10624  /* get current solution */
10625  if( chooseBasic )
10626  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10627  else
10628  {
10629  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10630  assert(primsol == NULL);
10631  }
10632 
10633  /* get current basis */
10634  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10635 
10636  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10637  nDualDeg = 0;
10638  cntcol = 0;
10639  oldpos = pos;
10640  pos = -1;
10641  for( c = 0; c < lp->nlpicols; ++c )
10642  {
10643  if( !fixedc[c] )
10644  {
10645  /* check whether variable is in basis */
10646  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10647  {
10648  /* store first candidate */
10649  if( pos == -1 && c > oldpos )
10650  {
10651  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10652  pos = c;
10653  }
10654  }
10655  else
10656  {
10657  /* reduced cost == 0 -> possible candidate */
10658  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10659  {
10660  ++nDualDeg;
10661  /* only if we have not yet found a candidate */
10662  if( pos == -1 && c > oldpos )
10663  {
10664  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10665  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10666  {
10667  newlb[cntcol] = oldlb[c];
10668  newub[cntcol] = oldlb[c];
10669  indcol[cntcol++] = c;
10670  fixedc[c] = TRUE;
10671  }
10672  else /* found a non-fixed candidate */
10673  {
10674  if( !chooseBasic )
10675  pos = c;
10676  }
10677  }
10678  }
10679  else
10680  {
10681  /* nonzero reduced cost -> variable can be fixed */
10682  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10683  {
10684  newlb[cntcol] = oldlb[c];
10685  newub[cntcol] = oldlb[c];
10686  }
10687  else
10688  {
10689  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10690  {
10691  newlb[cntcol] = oldub[c];
10692  newub[cntcol] = oldub[c];
10693  }
10694  else
10695  {
10696  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10697  newlb[cntcol] = 0.0;
10698  newub[cntcol] = 0.0;
10699  }
10700  }
10701  indcol[cntcol++] = c;
10702  fixedc[c] = TRUE;
10703  }
10704  }
10705  }
10706  }
10707 
10708  /* check rows */
10709  cntrow = 0;
10710  for( r = 0; r < lp->nlpirows; ++r )
10711  {
10712  if( !fixedr[r] )
10713  {
10714  /* consider only nonbasic rows */
10715  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
10716  {
10717  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
10718  if( SCIPsetIsFeasZero(set, dualsol[r]) )
10719  ++nDualDeg;
10720  else
10721  {
10722  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
10723  {
10724  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
10725  newlhs[cntrow] = oldlhs[r];
10726  newrhs[cntrow] = oldlhs[r];
10727  }
10728  else
10729  {
10730  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
10731  newlhs[cntrow] = oldrhs[r];
10732  newrhs[cntrow] = oldrhs[r];
10733  }
10734  indrow[cntrow++] = r;
10735  fixedr[r] = TRUE;
10736  }
10737  }
10738  }
10739  }
10740 
10741  if( nDualDeg > 0 && pos >= 0 )
10742  {
10743  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
10744 
10745  /* change objective */
10746  if( nruns == 0 )
10747  {
10748  /* set objective to appropriate unit vector for first run */
10749  newobj[pos] = 1.0;
10750  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
10751  }
10752  else
10753  {
10754  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
10755  SCIP_Real obj = 1.0;
10756  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
10757  }
10758 
10759  /* fix variables */
10760  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
10761  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
10762 
10763  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
10764  retcode = SCIPlpiSolvePrimal(lp->lpi);
10765  if( retcode == SCIP_LPERROR )
10766  {
10767  *lperror = TRUE;
10768  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10769  }
10770  else
10771  {
10772  SCIP_CALL( retcode );
10773  }
10774  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10775  lexIterations += iterations;
10776 
10777 #ifdef DEBUG_LEXDUAL
10778  if( iterations > 0 )
10779  {
10780  int j;
10781 
10782  if( !chooseBasic )
10783  {
10784  assert(primsol == NULL);
10785  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10786  }
10787  assert(primsol != NULL);
10788  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10789 
10790  for( j = 0; j < lp->nlpicols; ++j )
10791  {
10792  if( fixedc[j] )
10793  {
10794  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10795  }
10796  else
10797  {
10798  char cstart = '[';
10799  char cend = ']';
10800  char type;
10801 
10802  if(j == pos)
10803  {
10804  cstart = '*';
10805  cend = '*';
10806  }
10807 
10808  switch( (SCIP_BASESTAT) cstat[j] )
10809  {
10810  case SCIP_BASESTAT_LOWER:
10811  type = 'l';
10812  break;
10813  case SCIP_BASESTAT_UPPER:
10814  type = 'u';
10815  break;
10816  case SCIP_BASESTAT_ZERO:
10817  type = 'z';
10818  break;
10819  case SCIP_BASESTAT_BASIC:
10820  type = 'b';
10821  break;
10822  default:
10823  type = '?';
10824  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
10825  SCIPABORT();
10826  }
10827  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
10828  }
10829  }
10830  SCIPsetDebugMsg(set, "\n\n");
10831 
10832  if( !chooseBasic )
10833  {
10834  SCIPsetFreeBufferArray(set, &primsol);
10835  assert(primsol == NULL);
10836  }
10837  }
10838 #endif
10839 
10840  /* count only as round if iterations have been performed */
10841  if( iterations > 0 )
10842  ++rounds;
10843  ++nruns;
10844  }
10845  }
10846  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
10847 
10848  /* reset bounds, lhs/rhs, and obj */
10849  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
10850  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
10851  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
10852 
10853  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
10854  retcode = SCIPlpiSolveDual(lp->lpi);
10855  if( retcode == SCIP_LPERROR )
10856  {
10857  *lperror = TRUE;
10858  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10859  }
10860  else
10861  {
10862  SCIP_CALL( retcode );
10863  }
10864  assert(SCIPlpiIsOptimal(lp->lpi));
10865  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10866  lexIterations += iterations;
10867 
10868  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
10869 
10870  /* count number of iterations */
10871  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
10872  SCIPstatIncrement(stat, set, nlps);
10873 
10874  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10875  {
10876  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
10877  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10878  {
10879  SCIPstatIncrement(stat, set, nlexdualresolvelps);
10880  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
10881  }
10882  SCIPstatIncrement(stat, set, nlexduallps);
10883  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
10884 
10885  totalIterations += lexIterations;
10886  }
10887 
10888  /* free space */
10889  SCIPsetFreeBufferArray(set, &newobj);
10890 
10891  SCIPsetFreeBufferArray(set, &fixedr);
10892  SCIPsetFreeBufferArray(set, &fixedc);
10893 
10894  SCIPsetFreeBufferArray(set, &indallrow);
10895  SCIPsetFreeBufferArray(set, &indallcol);
10896 
10897  SCIPsetFreeBufferArray(set, &indrow);
10898  SCIPsetFreeBufferArray(set, &newrhs);
10899  SCIPsetFreeBufferArray(set, &newlhs);
10900 
10901  SCIPsetFreeBufferArray(set, &indcol);
10902  SCIPsetFreeBufferArray(set, &newub);
10903  SCIPsetFreeBufferArray(set, &newlb);
10904 
10905  SCIPsetFreeBufferArray(set, &oldobj);
10906  SCIPsetFreeBufferArray(set, &oldrhs);
10907  SCIPsetFreeBufferArray(set, &oldlhs);
10908  SCIPsetFreeBufferArray(set, &oldub);
10909  SCIPsetFreeBufferArray(set, &oldlb);
10910 
10911  SCIPsetFreeBufferArray(set, &rstat);
10912  SCIPsetFreeBufferArray(set, &cstat);
10913 
10914  SCIPsetFreeBufferArray(set, &redcost);
10915  SCIPsetFreeBufferArray(set, &dualsol);
10916  if( chooseBasic )
10917  SCIPsetFreeBufferArray(set, &primsol);
10918 
10919  /* stop timing */
10920  SCIPclockStop(stat->lexduallptime, set);
10921 
10922  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10923  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10924  }
10926  lp->solisbasic = TRUE;
10927 
10928  if( totalIterations > 0 && !lp->strongbranchprobing )
10929  SCIPstatIncrement(stat, set, nlps);
10930  else
10931  {
10932  if( keepsol && !(*lperror) )
10933  {
10934  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10935  if( lp->validsollp == stat->lpcount-1 )
10936  lp->validsollp = stat->lpcount;
10937  if( lp->validfarkaslp == stat->lpcount-1 )
10938  lp->validfarkaslp = stat->lpcount;
10939  }
10940  }
10941 
10942  return SCIP_OKAY;
10943 }
10944 
10945 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
10946 static
10948  SCIP_LP* lp, /**< current LP data */
10949  SCIP_SET* set, /**< global SCIP settings */
10950  SCIP_STAT* stat, /**< problem statistics */
10951  SCIP_Bool crossover, /**< should crossover be performed? */
10952  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10953  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10954  )
10955 {
10956  SCIP_Real timedelta;
10957  SCIP_RETCODE retcode;
10958  int iterations;
10959 
10960  assert(lp != NULL);
10961  assert(lp->flushed);
10962  assert(set != NULL);
10963  assert(stat != NULL);
10964  assert(lperror != NULL);
10965 
10966  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",
10967  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
10968  stat->nbarrierlps, stat->ndivinglps);
10969 
10970  *lperror = FALSE;
10971 
10972 #if 0 /* for debugging: write all root node LP's */
10973  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10974  {
10975  char fname[SCIP_MAXSTRLEN];
10976  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10977  SCIP_CALL( SCIPlpWrite(lp, fname) );
10978  SCIPsetDebugMsg("wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10979  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
10980  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10981  }
10982 #endif
10983 
10984  /* start timing */
10985  if( lp->diving || lp->probing )
10986  {
10987  if( lp->strongbranchprobing )
10988  SCIPclockStart(stat->strongbranchtime, set);
10989  else
10990  SCIPclockStart(stat->divinglptime, set);
10991 
10992  timedelta = 0.0; /* unused for diving or probing */
10993  }
10994  else
10995  {
10996  SCIPclockStart(stat->barrierlptime, set);
10997  timedelta = -SCIPclockGetTime(stat->duallptime);
10998  }
10999 
11000  /* call barrier algorithm */
11001  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11002  if( retcode == SCIP_LPERROR )
11003  {
11004  *lperror = TRUE;
11005  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11006  }
11007  else
11008  {
11009  SCIP_CALL( retcode );
11010  }
11012  lp->solisbasic = crossover;
11013 
11014  /* stop timing */
11015  if( lp->diving || lp->probing )
11016  {
11017  if( lp->strongbranchprobing )
11018  SCIPclockStop(stat->strongbranchtime, set);
11019  else
11020  SCIPclockStop(stat->divinglptime, set);
11021  }
11022  else
11023  {
11024  SCIPclockStop(stat->barrierlptime, set);
11025  timedelta = -SCIPclockGetTime(stat->duallptime);
11026  }
11027 
11028  /* count number of iterations */
11029  SCIPstatIncrement(stat, set, lpcount);
11030  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11031  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11032  {
11033  if( !lp->strongbranchprobing )
11034  {
11035  SCIPstatIncrement(stat, set, nlps);
11036  SCIPstatAdd(stat, set, nlpiterations, iterations);
11037  }
11038  if( lp->diving || lp->probing )
11039  {
11040  if( lp->strongbranchprobing )
11041  {
11042  SCIPstatIncrement(stat, set, nsbdivinglps);
11043  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11044  }
11045  else
11046  {
11047  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11048  SCIPstatIncrement(stat, set, ndivinglps);
11049  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11050  }
11051  }
11052  else
11053  {
11054  SCIPstatIncrement(stat, set, nbarrierlps);
11055  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11056  }
11057  }
11058  else
11059  {
11060  if ( ! lp->diving && ! lp->probing )
11061  {
11062  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11063  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11064  }
11065 
11066  if( keepsol && !(*lperror) )
11067  {
11068  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11069  if( lp->validsollp == stat->lpcount-1 )
11070  lp->validsollp = stat->lpcount;
11071  if( lp->validfarkaslp == stat->lpcount-1 )
11072  lp->validfarkaslp = stat->lpcount;
11073  }
11074  }
11075 
11076  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11077  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11078 
11079  return SCIP_OKAY;
11080 }
11081 
11082 /** solves the LP with the given algorithm */
11083 static
11085  SCIP_LP* lp, /**< current LP data */
11086  SCIP_SET* set, /**< global SCIP settings */
11087  SCIP_STAT* stat, /**< problem statistics */
11088  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11089  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11090  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11091  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11092  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11093  )
11094 {
11095  SCIP_Real lptimelimit;
11096  SCIP_Bool success;
11097 
11098  assert(lp != NULL);
11099  assert(lp->flushed);
11100  assert(lperror != NULL);
11101 
11102  /* check if a time limit is set, and set time limit for LP solver accordingly */
11103  lptimelimit = SCIPlpiInfinity(lp->lpi);
11104  if( set->istimelimitfinite )
11105  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11106 
11107  success = FALSE;
11108  if( lptimelimit > 0.0 )
11109  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11110 
11111  if( lptimelimit <= 0.0 || !success )
11112  {
11113  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11114  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11115  *timelimit = TRUE;
11116  return SCIP_OKAY;
11117  }
11118  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %f seconds\n", lpalgoName(lpalgo), lptimelimit);
11119 
11120  /* call appropriate LP algorithm */
11121  switch( lpalgo )
11122  {
11124  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, lperror) );
11125  break;
11126 
11128  /* run dual lexicographic simplex if required */
11129  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11130  {
11131  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11132  }
11133  else
11134  {
11135  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11136  }
11137  break;
11138 
11139  case SCIP_LPALGO_BARRIER:
11140  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11141  break;
11142 
11144  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11145  break;
11146 
11147  default:
11148  SCIPerrorMessage("invalid LP algorithm\n");
11149  return SCIP_INVALIDDATA;
11150  }
11151 
11152  if( !(*lperror) )
11153  {
11154  /* check for primal and dual feasibility */
11156 
11157  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11158  }
11159 
11160  return SCIP_OKAY;
11161 }
11162 
11163 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11164  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11165  */
11166 #define MAXNUMTROUBLELPMSGS 10
11167 
11168 /** prints message about numerical trouble
11169  *
11170  * If message has verblevel at most high and display/verblevel is not full,
11171  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11172  * were printed before in the current run.
11173  */
11174 static
11176  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11177  SCIP_SET* set, /**< global SCIP settings */
11178  SCIP_STAT* stat, /**< problem statistics */
11179  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11180  const char* formatstr, /**< message format string */
11181  ... /**< arguments to format string */
11182  )
11183 {
11184  va_list ap;
11185 
11186  assert(verblevel > SCIP_VERBLEVEL_NONE);
11187  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11188  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11189 
11190  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11191  {
11192  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11193  {
11194  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11196  return;
11197 
11198  /* increase count on messages with verblevel high */
11199  ++stat->nnumtroublelpmsgs ;
11200  }
11201 
11202  /* if messages wouldn't be printed, then return already */
11203  if( verblevel > set->disp_verblevel )
11204  return;
11205  }
11206 
11207  /* print common begin of message */
11208  SCIPmessagePrintInfo(messagehdlr,
11209  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11210  stat->nnodes, stat->nlps);
11211 
11212  /* print individual part of message */
11213  va_start(ap, formatstr); /*lint !e838*/
11214  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11215  va_end(ap);
11216 
11217  /* warn that further messages will be suppressed */
11218  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11219  {
11220  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11221  }
11222 
11223  /* print closing new-line */
11224  SCIPmessagePrintInfo(messagehdlr, "\n");
11225 }
11226 
11227 #define FEASTOLTIGHTFAC 0.001
11228 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11229 static
11231  SCIP_LP* lp, /**< current LP data */
11232  SCIP_SET* set, /**< global SCIP settings */
11233  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11234  SCIP_STAT* stat, /**< problem statistics */
11235  SCIP_PROB* prob, /**< problem data */
11236  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11237  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11238  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11239  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11240  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11241  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11242  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11243  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11244  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11245  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11246  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11247  )
11248 {
11249  SCIP_Bool success;
11250  SCIP_Bool success2;
11251  SCIP_Bool success3;
11252  SCIP_Bool simplex;
11253  SCIP_Bool itlimishard;
11254  SCIP_Bool usepolishing;
11255 
11256  assert(lp != NULL);
11257  assert(lp->flushed);
11258  assert(set != NULL);
11259  assert(stat != NULL);
11260  assert(lperror != NULL);
11261  assert(timelimit != NULL);
11262 
11263  *lperror = FALSE;
11264 
11265  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11266  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11267  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11268  * SCIP_LP such that we can return a primal ray
11269  */
11270  if( lp->looseobjvalinf > 0 )
11271  {
11272  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11273  return SCIP_ERROR;
11274  }
11275 
11276  /* check, whether we solve with a simplex algorithm */
11277  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11278 
11279  /* check whether the iteration limit is a hard one */
11280  itlimishard = (itlim == harditlim);
11281 
11282  /* check whether solution polishing should be used */
11283  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11284  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11285  {
11286  usepolishing = TRUE;
11287  if( lp->updateintegrality )
11288  {
11289  SCIP_CALL( lpCopyIntegrality(lp, set) );
11290  }
11291  }
11292  else
11293  usepolishing = FALSE;
11294 
11295  /* solve with given settings (usually fast but imprecise) */
11296  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11297  {
11298  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound) );
11299  }
11300  else
11301  {
11302  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) );
11303  }
11304  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11305  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * SCIPsetLpfeastol(set) : SCIPsetLpfeastol(set), &success) );
11306  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11307  &success) );
11308  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11309  : SCIPsetBarrierconvtol(set), &success) );
11310  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11311  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11312  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11313  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11314  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11315  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11316  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11317  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11318  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11319  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11320  SCIP_CALL( lpSetRandomseed(lp, SCIPsetInitializeRandomSeed(set, set->random_randomseed), &success) );
11321  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11322  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11323  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11324  resolve = FALSE; /* only the first solve should be counted as resolving call */
11325 
11326  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11327  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11328  return SCIP_OKAY;
11329  else if( !set->lp_checkstability )
11330  {
11331  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11332  if( success )
11333  {
11334  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11335  return SCIP_OKAY;
11336  }
11337  }
11338 
11339  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11340  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11341  */
11342 
11343  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11344  * do this only if the iteration limit was not exceeded in the last LP solving call
11345  */
11346  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11347  {
11348  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11349  if( success )
11350  {
11351  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11352  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11353 
11354  /* check for stability */
11355  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11356  return SCIP_OKAY;
11357  else if( !set->lp_checkstability )
11358  {
11359  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11360  if( success )
11361  {
11362  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11363  return SCIP_OKAY;
11364  }
11365  }
11366  }
11367  }
11368 
11369  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11370  * and go directly to solving the LP from scratch
11371  */
11372  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11373  {
11374  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11375  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11376  if( success )
11377  {
11378  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling", lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11379  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11380 
11381  /* check for stability */
11382  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11383  return SCIP_OKAY;
11384  else if( !set->lp_checkstability )
11385  {
11386  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11387  if( success )
11388  {
11389  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11390  return SCIP_OKAY;
11391  }
11392  }
11393 
11394  /* reset scaling */
11395  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11396  assert(success);
11397  }
11398  }
11399 
11400  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11401  * and go directly to solving the LP from scratch
11402  */
11403  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11404  {
11405  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11406  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11407  if( success )
11408  {
11409  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11410  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11411  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11412 
11413  /* check for stability */
11414  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11415  return SCIP_OKAY;
11416  else if( !set->lp_checkstability )
11417  {
11418  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11419  if( success )
11420  {
11421  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11422  return SCIP_OKAY;
11423  }
11424  }
11425 
11426  /* reset presolving */
11427  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11428  assert(success);
11429  }
11430  }
11431 
11432  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11433  * do this only if the iteration limit was not exceeded in the last LP solving call
11434  */
11435  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11436  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11437  {
11438  success = FALSE;
11439  if( !tightprimfeastol )
11440  {
11441  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11442  }
11443 
11444  success2 = FALSE;
11445  if( !tightdualfeastol )
11446  {
11448  }
11449 
11450  success3 = FALSE;
11451  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11452  {
11454  }
11455 
11456  if( success || success2 || success3 )
11457  {
11458  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance", lpalgoName(lpalgo));
11459  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11460 
11461  /* check for stability */
11462  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11463  return SCIP_OKAY;
11464  else if( !set->lp_checkstability )
11465  {
11466  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11467  if( success )
11468  {
11469  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11470  return SCIP_OKAY;
11471  }
11472  }
11473 
11474  /* reset feasibility tolerance */
11475  if( !tightprimfeastol )
11476  {
11477  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11478  }
11479  if( !tightdualfeastol )
11480  {
11481  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11482  }
11483  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11484  {
11485  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11486  }
11487  }
11488  }
11489 
11490  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11491  * the given iteration limit might be a soft one to restrict resolving calls only */
11492  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11493 
11494  /* if not already done, solve again from scratch */
11495  if( !fromscratch && simplex )
11496  {
11497  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11498  if( success )
11499  {
11500  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11501  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11502 
11503  /* check for stability */
11504  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11505  return SCIP_OKAY;
11506  else if( !set->lp_checkstability )
11507  {
11508  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11509  if( success )
11510  {
11511  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11512  return SCIP_OKAY;
11513  }
11514  }
11515  }
11516  }
11517 
11518  /* solve again, use other simplex this time */
11519  if( simplex )
11520  {
11522  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11523  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11524 
11525  /* check for stability */
11526  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11527  return SCIP_OKAY;
11528  else if( !set->lp_checkstability )
11529  {
11530  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11531  if( success )
11532  {
11533  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11534  return SCIP_OKAY;
11535  }
11536  }
11537 
11538  /* solve again with opposite scaling and other simplex */
11539  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11540  if( success )
11541  {
11542  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11543  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11544  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11545 
11546  /* check for stability */
11547  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11548  return SCIP_OKAY;
11549  else if( !set->lp_checkstability )
11550  {
11551  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11552  if( success )
11553  {
11554  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11555  return SCIP_OKAY;
11556  }
11557  }
11558 
11559  /* reset scaling */
11560  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11561  assert(success);
11562  }
11563 
11564  /* solve again with opposite presolving and other simplex */
11565  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11566  if( success )
11567  {
11568  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11569  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11570  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11571 
11572  /* check for stability */
11573  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11574  return SCIP_OKAY;
11575  else if( !set->lp_checkstability )
11576  {
11577  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11578  if( success )
11579  {
11580  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11581  return SCIP_OKAY;
11582  }
11583  }
11584 
11585  /* reset presolving */
11586  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11587  assert(success);
11588  }
11589 
11590  /* solve again with tighter feasibility tolerance, use other simplex this time */
11591  if( !tightprimfeastol || !tightdualfeastol )
11592  {
11593  success = FALSE;
11594  if( !tightprimfeastol )
11595  {
11596  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11597  }
11598 
11599  success2 = FALSE;
11600  if( !tightdualfeastol )
11601  {
11603  }
11604 
11605  if( success || success2 )
11606  {
11607  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance", lpalgoName(lpalgo));
11608  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11609 
11610  /* check for stability */
11611  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11612  return SCIP_OKAY;
11613  else if( !set->lp_checkstability )
11614  {
11615  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11616  if( success )
11617  {
11618  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11619  return SCIP_OKAY;
11620  }
11621  }
11622 
11623  /* reset feasibility tolerance */
11624  if( !tightprimfeastol )
11625  {
11626  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11627  }
11628  if( !tightdualfeastol )
11629  {
11630  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11631  }
11632  }
11633  }
11634  }
11635 
11636  /* nothing worked -- exit with an LPERROR */
11637  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11638  *lperror = TRUE;
11639 
11640  return SCIP_OKAY;
11641 }
11642 
11643 /** adjust the LP objective value if its greater/less than +/- SCIPsetInfinity() */
11644 static
11646  SCIP_LP* lp, /**< current LP data */
11647  SCIP_SET* set, /**< global SCIP settings */
11648  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11649  )
11650 {
11651  assert(lp != NULL);
11652  assert(set != NULL);
11653 
11654  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11655  {
11656  if( !lp->adjustlpval )
11657  {
11658  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11659  lp->adjustlpval = TRUE;
11660  }
11661  lp->lpobjval = SCIPsetInfinity(set);
11662  }
11663  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11664  {
11665  if( !lp->adjustlpval )
11666  {
11667  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11668  lp->adjustlpval = TRUE;
11669  }
11670  lp->lpobjval = -SCIPsetInfinity(set);
11671  }
11672 }
11673 
11674 /** solves the LP with the given algorithm and evaluates return status */
11675 static
11677  SCIP_LP* lp, /**< current LP data */
11678  SCIP_SET* set, /**< global SCIP settings */
11679  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11680  SCIP_STAT* stat, /**< problem statistics */
11681  SCIP_PROB* prob, /**< problem data */
11682  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11683  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11684  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11685  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11686  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11687  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11688  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11689  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11690  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11691  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11692  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11693  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11694  )
11695 {
11696  SCIP_Bool solvedprimal;
11697  SCIP_Bool solveddual;
11698  SCIP_Bool timelimit;
11699  int itlim;
11700 
11701  assert(lp != NULL);
11702  assert(lp->flushed);
11703  assert(set != NULL);
11704  assert(stat != NULL);
11705  assert(lperror != NULL);
11706 
11707  checkLinks(lp);
11708 
11709  solvedprimal = FALSE;
11710  solveddual = FALSE;
11711  timelimit = FALSE;
11712 
11713  /* select the basic iteration limit depending on whether this is a resolving call or not */
11714  itlim = ( resolve ? resolveitlim : harditlim );
11715 
11716  SOLVEAGAIN:
11717  /* call simplex */
11718  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11719  keepsol, &timelimit, lperror) );
11720  resolve = FALSE; /* only the first solve should be counted as resolving call */
11721  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11722  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11723 
11724  /* check, if an error occurred */
11725  if( *lperror )
11726  {
11727  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11728  lp->solved = FALSE;
11730  return SCIP_OKAY;
11731  }
11732 
11733  /* check, if a time limit was exceeded */
11734  if( timelimit )
11735  {
11736  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11737  lp->solved = TRUE;
11739  lp->lpobjval = -SCIPsetInfinity(set);
11740  return SCIP_OKAY;
11741  }
11742 
11743  /* only one should return true */
11744  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11746 
11747  /* evaluate solution status */
11748  if( SCIPlpiIsOptimal(lp->lpi) )
11749  {
11750  assert(lp->primalfeasible);
11751  assert(lp->dualfeasible);
11753  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11754  adjustLPobjval(lp, set, messagehdlr);
11755 
11756  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
11757  {
11758  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11759  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
11761  lp->lpobjval = SCIPsetInfinity(set);
11762  }
11763  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11764  * reached if the LP objective value is greater than the cutoff bound
11765  */
11767  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11768  }
11769  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11770  {
11771  assert(!lpCutoffDisabled(set));
11773  lp->lpobjval = SCIPsetInfinity(set);
11774  }
11775  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11776  {
11777  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11778  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11779  {
11780  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11781  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11782  goto SOLVEAGAIN;
11783  }
11785  lp->lpobjval = SCIPsetInfinity(set);
11786  }
11787  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11788  {
11789  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11790  if( needprimalray && !SCIPlpiHasPrimalRay(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11791  {
11792  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11793  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11794  goto SOLVEAGAIN;
11795  }
11797  lp->lpobjval = -SCIPsetInfinity(set);
11798  }
11799  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11800  {
11801  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11802  adjustLPobjval(lp, set, messagehdlr);
11804  }
11805  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11806  {
11807  lp->lpobjval = -SCIPsetInfinity(set);
11809  }
11810  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11811  {
11812  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11813  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11814  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11815  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11816  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11817  goto SOLVEAGAIN;
11818  }
11819  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11820  {
11821  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11822  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11823  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11824  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11825  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11826  goto SOLVEAGAIN;
11827  }
11828  else
11829  {
11830  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
11831  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
11833  return SCIP_LPERROR;
11834  }
11835 
11836  lp->solved = TRUE;
11837 
11838  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
11841 
11842  return SCIP_OKAY;
11843 }
11844 
11845 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
11846 static
11848  SCIP_LP* lp, /**< current LP data */
11849  BMS_BLKMEM* blkmem, /**< block memory */
11850  SCIP_SET* set, /**< global SCIP settings */
11851  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11852  SCIP_STAT* stat, /**< problem statistics */
11853  SCIP_PROB* prob, /**< problem data */
11854  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11855  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11856  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11857  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11858  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11859  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11860  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11861  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11862  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11863  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11864  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11865  )
11866 {
11867  SCIP_Bool resolve;
11868  char algo;
11869 
11870  assert(lp != NULL);
11871  assert(set != NULL);
11872  assert(lperror != NULL);
11873 
11874  /* flush changes to the LP solver */
11875  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
11876  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
11877 
11878  /* select LP algorithm to apply */
11879  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
11880  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
11881 
11882  switch( algo )
11883  {
11884  case 's':
11885  /* select simplex method */
11886  if( lp->dualfeasible || !lp->primalfeasible )
11887  {
11888  SCIPsetDebugMsg(set, "solving dual LP\n");
11889  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11890  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11891  }
11892  else
11893  {
11894  SCIPsetDebugMsg(set, "solving primal LP\n");
11895  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11896  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11897  }
11898  break;
11899 
11900  case 'p':
11901  SCIPsetDebugMsg(set, "solving primal LP\n");
11902  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11903  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11904  break;
11905 
11906  case 'd':
11907  SCIPsetDebugMsg(set, "solving dual LP\n");
11908  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11909  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11910  break;
11911 
11912  case 'b':
11913  SCIPsetDebugMsg(set, "solving barrier LP\n");
11914  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
11915  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11916  break;
11917 
11918  case 'c':
11919  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
11920  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
11921  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11922  break;
11923 
11924  default:
11925  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
11926  return SCIP_PARAMETERWRONGVAL;
11927  }
11928  assert(!(*lperror) || !lp->solved);
11929 
11930  return SCIP_OKAY;
11931 }
11932 
11933 #ifndef NDEBUG
11934 /** checks if the lazy bounds are valid */
11935 static
11937  SCIP_LP* lp, /**< LP data */
11938  SCIP_SET* set /**< global SCIP settings */
11939  )
11940 {
11941  SCIP_COL* col;
11942  int c;
11943 
11944  assert(lp->flushed);
11945 
11946  for( c = 0; c < lp->nlazycols; ++c )
11947  {
11948  col = lp->lazycols[c];
11949 
11950  /* in case lazy bounds are given, check that the primal solution satisfies them */
11951  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
11952  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
11953  }
11954 }
11955 #else
11956 #define checkLazyBounds(lp, set) /**/
11957 #endif
11958 
11959 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
11960  * diving
11961  */
11962 static
11964  SCIP_LP* lp, /**< LP data */
11965  SCIP_SET* set /**< global SCIP settings */
11966  )
11967 {
11968  SCIP_COL* col;
11969  int c;
11970 
11971  assert(lp->nlazycols > 0);
11972 
11973  /* return, if we are in diving, and bounds were already applied
11974  * or if we are not in diving and bounds were not applied
11975  */
11976  if( lp->diving == lp->divinglazyapplied )
11977  return SCIP_OKAY;
11978 
11979  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
11980  lp->diving, lp->divinglazyapplied);
11981 
11982  for( c = 0; c < lp->nlazycols; ++c )
11983  {
11984  col = lp->lazycols[c];
11985 
11986  /* if the column has a lazy lower bound, mark its lower bounds as changed */
11987  if( !SCIPsetIsInfinity(set, -col->lazylb) )
11988  {
11989  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
11990  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
11991  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11992 
11993  /* insert column in the chgcols list (if not already there) */
11994  SCIP_CALL( insertColChgcols(col, set, lp) );
11995 
11996  /* mark bound change in the column */
11997  col->lbchanged = TRUE;
11998  }
11999 
12000  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12001  if( !SCIPsetIsInfinity(set, col->lazyub) )
12002  {
12003  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
12004  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12005  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12006 
12007  /* insert column in the chgcols list (if not already there) */
12008  SCIP_CALL( insertColChgcols(col, set, lp) );
12009 
12010  /* mark bound change in the column */
12011  col->ubchanged = TRUE;
12012  }
12013  }
12014 
12015  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12016  * if not, we just removed them
12017  */
12018  lp->divinglazyapplied = lp->diving;
12019 
12020  return SCIP_OKAY;
12021 }
12022 
12023 /** returns the iteration limit for an LP resolving call */
12024 static
12026  SCIP_SET* set, /**< global SCIP settings */
12027  SCIP_STAT* stat, /**< dynamic problem statistics */
12028  int itlim /**< hard iteration limit */
12029  )
12030 {
12031  /* no limit set or average not yet reliable */
12032  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12033  return itlim;
12034  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12035  if( itlim == -1 )
12036  itlim = INT_MAX;
12037  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12038  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12039  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12040 }
12041 
12042 
12043 
12044 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12046  SCIP_LP* lp, /**< LP data */
12047  SCIP_SET* set, /**< global SCIP settings */
12048  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12049  BMS_BLKMEM* blkmem, /**< block memory buffers */
12050  SCIP_STAT* stat, /**< problem statistics */
12051  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12052  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12053  SCIP_PROB* prob, /**< problem data */
12054  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12055  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12056  * (limit is computed within the method w.r.t. the average LP iterations) */
12057  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12058  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12059  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12060  )
12061 {
12062  SCIP_RETCODE retcode;
12063  SCIP_Bool needprimalray;
12064  SCIP_Bool needdualray;
12065  int harditlim;
12066  int resolveitlim;
12067 
12068  assert(lp != NULL);
12069  assert(prob != NULL);
12070  assert(prob->nvars >= lp->ncols);
12071  assert(lperror != NULL);
12072 
12073  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12074  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12075 
12076  retcode = SCIP_OKAY;
12077  *lperror = FALSE;
12078 
12079  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12080  needprimalray = TRUE;
12081  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12082  || (set->conf_enable && set->conf_useinflp != 'o'));
12083 
12084  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12085  harditlim = (int) MIN(itlim, INT_MAX);
12086  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12087  assert(harditlim == -1 || (resolveitlim <= harditlim));
12088 
12089  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12090  * or removed from the LP (diving was ended)
12091  */
12092  if( lp->nlazycols > 0 )
12093  {
12094  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12095  * first resolve LP?
12096  */
12097  SCIP_CALL( updateLazyBounds(lp, set) );
12098  assert(lp->diving == lp->divinglazyapplied);
12099  }
12100 
12101  /* flush changes to the LP solver */
12102  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12103  assert(lp->flushed);
12104 
12105  /* 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
12106  * to run again anyway, since there seems to be some time left / the time limit was increased
12107  */
12108  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12109  {
12110  SCIP_Bool* primalfeaspointer;
12111  SCIP_Bool* dualfeaspointer;
12112  SCIP_Bool primalfeasible;
12113  SCIP_Bool dualfeasible;
12114  SCIP_Bool rayfeasible;
12115  SCIP_Bool tightprimfeastol;
12116  SCIP_Bool tightdualfeastol;
12117  SCIP_Bool fromscratch;
12118  SCIP_Bool wasfromscratch;
12119  SCIP_Longint oldnlps;
12120  int fastmip;
12121 
12122  /* set initial LP solver settings */
12123  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12124  tightprimfeastol = FALSE;
12125  tightdualfeastol = FALSE;
12126  fromscratch = FALSE;
12127  primalfeasible = FALSE;
12128  dualfeasible = FALSE;
12129  wasfromscratch = (stat->nlps == 0);
12130 
12131  SOLVEAGAIN:
12132  /* solve the LP */
12133  oldnlps = stat->nlps;
12134  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12135  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12136  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12137  assert(!(*lperror) || !lp->solved);
12138 
12139  /* check for error */
12140  if( *lperror )
12141  {
12142  retcode = SCIP_OKAY;
12143  goto TERMINATE;
12144  }
12145 
12146  /* evaluate solution status */
12147  switch( SCIPlpGetSolstat(lp) )
12148  {
12150  /* get LP solution and possibly check the solution's feasibility again */
12151  if( set->lp_checkprimfeas )
12152  {
12153  primalfeaspointer = &primalfeasible;
12154  lp->primalchecked = TRUE;
12155  }
12156  else
12157  {
12158  /* believe in the primal feasibility of the LP solution */
12159  primalfeasible = TRUE;
12160  primalfeaspointer = NULL;
12161  lp->primalchecked = FALSE;
12162  }
12163  if( set->lp_checkdualfeas )
12164  {
12165  dualfeaspointer = &dualfeasible;
12166  lp->dualchecked = TRUE;
12167  }
12168  else
12169  {
12170  /* believe in the dual feasibility of the LP solution */
12171  dualfeasible = TRUE;
12172  dualfeaspointer = NULL;
12173  lp->dualchecked = FALSE;
12174  }
12175 
12176  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12177 
12178  /* in debug mode, check that lazy bounds (if present) are not violated */
12179  checkLazyBounds(lp, set);
12180 
12181  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12182  {
12183  /* update ages and remove obsolete columns and rows from LP */
12184  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12185  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12186  {
12187  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12188  }
12189 
12190  if( !lp->solved )
12191  {
12192  /* resolve LP after removing obsolete columns and rows */
12193  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12194  aging = FALSE; /* to prevent infinite loops */
12195  goto SOLVEAGAIN;
12196  }
12197  }
12198  if( !primalfeasible || !dualfeasible )
12199  {
12201 
12202  if( (fastmip > 0) && simplex )
12203  {
12204  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12205  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12206  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12207  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12208  fastmip = 0;
12209  goto SOLVEAGAIN;
12210  }
12211  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12212  {
12213  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12214  * tolerance
12215  */
12216  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12217  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12218  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12219  tightprimfeastol = tightprimfeastol || !primalfeasible;
12220  tightdualfeastol = tightdualfeastol || !dualfeasible;
12221  goto SOLVEAGAIN;
12222  }
12223  else if( !fromscratch && !wasfromscratch && simplex )
12224  {
12225  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12226  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12227  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12228  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12229  fromscratch = TRUE;
12230  goto SOLVEAGAIN;
12231  }
12232  else
12233  {
12234  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12235  lp->solved = FALSE;
12237  *lperror = TRUE;
12238  }
12239  }
12240  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12241  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12242  lp->lpsolstat, lp->cutoffbound);
12243  break;
12244 
12246  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12247  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12248  {
12249  if( SCIPlpiHasDualRay(lp->lpi) )
12250  {
12251  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12252  }
12253  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12254  * with the primal simplex due to numerical problems) - treat this case like an LP error
12255  */
12256  else
12257  {
12258  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12259  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12260  lp->solved = FALSE;
12262  *lperror = TRUE;
12263  }
12264  }
12265  break;
12266 
12268  if( set->lp_checkprimfeas )
12269  {
12270  /* get unbounded LP solution and check the solution's feasibility again */
12271  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12272 
12273  lp->primalchecked = TRUE;
12274  }
12275  else
12276  {
12277  /* get unbounded LP solution believing in the feasibility of the LP solution */
12278  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12279 
12280  primalfeasible = TRUE;
12281  rayfeasible = TRUE;
12282  lp->primalchecked = FALSE;
12283  }
12284 
12285  /* in debug mode, check that lazy bounds (if present) are not violated */
12286  checkLazyBounds(lp, set);
12287 
12288  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12289  primalfeasible, rayfeasible);
12290 
12291  if( !primalfeasible || !rayfeasible )
12292  {
12294 
12295  if( (fastmip > 0) && simplex )
12296  {
12297  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12298  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12299  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12300  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12301  fastmip = 0;
12302  goto SOLVEAGAIN;
12303  }
12304  else if( !tightprimfeastol )
12305  {
12306  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12307  * tolerance
12308  */
12309  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12310  "(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",
12311  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12312  tightprimfeastol = TRUE;
12313  goto SOLVEAGAIN;
12314  }
12315  else if( !fromscratch && simplex )
12316  {
12317  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12318  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12319  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12320  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12321  fromscratch = TRUE;
12322  goto SOLVEAGAIN;
12323  }
12324  else
12325  {
12326  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12327  * forget about the LP at this node and mark it to be unsolved
12328  */
12329  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12330  lp->solved = FALSE;
12332  *lperror = TRUE;
12333  }
12334  }
12335 
12336  break;
12337 
12339  assert(!lpCutoffDisabled(set));
12340  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12341  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12342  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12343  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12344  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12345  * FASTMIP and solve again.
12346  */
12347  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12348  {
12349  SCIP_LPI* lpi;
12350  SCIP_Real objval;
12351 
12352  lpi = SCIPlpGetLPI(lp);
12353 
12354  assert(lpi != NULL);
12355  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12356  * the assert by using !SCIPsetIsFeasNegative()
12357  */
12358  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12359 
12360  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12361 
12362  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12363  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12364  {
12365  SCIP_Real tmpcutoff;
12366  char tmppricingchar;
12367  SCIP_LPSOLSTAT solstat;
12368 
12369  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12370 
12371  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12372  fromscratch = FALSE;
12373 
12374  /* temporarily disable cutoffbound, which also disables the objective limit */
12375  tmpcutoff = lp->cutoffbound;
12376  lp->cutoffbound = SCIPlpiInfinity(lpi);
12377 
12378  /* set lp pricing strategy to steepest edge */
12379  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12380  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12381 
12382  /* resolve LP with an iteration limit of 1 */
12383  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12384  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12385 
12386  /* reinstall old cutoff bound and lp pricing strategy */
12387  lp->cutoffbound = tmpcutoff;
12388  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12389 
12390  /* get objective value */
12391  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12392 
12393  /* get solution status for the lp */
12394  solstat = SCIPlpGetSolstat(lp);
12395  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12396 
12397  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12398  {
12399  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12400  }
12401 
12402  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12403  fastmip = 0;
12404 
12405  /* the solution is still not exceeding the objective limit and the solving process
12406  * was stopped due to time or iteration limit, solve again with fastmip turned off
12407  */
12408  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12409  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12410  {
12411  assert(!(*lperror));
12412 
12413  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12414  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12415 
12416  /* get objective value */
12417  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12418 
12419  /* get solution status for the lp */
12420  solstat = SCIPlpGetSolstat(lp);
12421 
12422  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12423  }
12424 
12425  /* check for lp errors */
12426  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12427  {
12428  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12429  lp->solved = FALSE;
12431 
12432  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12433  goto TERMINATE;
12434  }
12435 
12436  lp->solved = TRUE;
12437 
12438  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12439  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12440  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12441  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12442  {
12443  /* get LP solution and possibly check the solution's feasibility again */
12444  if( set->lp_checkprimfeas )
12445  {
12446  primalfeaspointer = &primalfeasible;
12447  lp->primalchecked = TRUE;
12448  }
12449  else
12450  {
12451  /* believe in the primal feasibility of the LP solution */
12452  primalfeasible = TRUE;
12453  primalfeaspointer = NULL;
12454  lp->primalchecked = FALSE;
12455  }
12456  if( set->lp_checkdualfeas )
12457  {
12458  dualfeaspointer = &dualfeasible;
12459  lp->dualchecked = TRUE;
12460  }
12461  else
12462  {
12463  /* believe in the dual feasibility of the LP solution */
12464  dualfeasible = TRUE;
12465  dualfeaspointer = NULL;
12466  lp->dualchecked = FALSE;
12467  }
12468 
12469  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12470 
12471  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12472  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12473  {
12474  checkLazyBounds(lp, set);
12475  }
12476 
12477  /* if objective value is larger than the cutoff bound, set solution status to objective
12478  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12479  * this was already done in the lpSolve() method
12480  */
12481  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12482  {
12484  lp->lpobjval = SCIPsetInfinity(set);
12485  }
12486 
12487  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12488  * the cutoffbound; mark the LP to be unsolved
12489  */
12490  if( !primalfeasible || !dualfeasible
12491  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12492  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12493  {
12494  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12495  lp->solved = FALSE;
12497  *lperror = TRUE;
12498  }
12499 
12500  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12501  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12502  lp->lpsolstat, lp->cutoffbound);
12503  }
12504  /* infeasible solution */
12505  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12506  {
12507  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12508  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12509  }
12510  /* unbounded solution */
12511  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12512  {
12513  if( set->lp_checkprimfeas )
12514  {
12515  /* get unbounded LP solution and check the solution's feasibility again */
12516  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12517 
12518  lp->primalchecked = TRUE;
12519  }
12520  else
12521  {
12522  /* get unbounded LP solution believing in its feasibility */
12523  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12524 
12525  primalfeasible = TRUE;
12526  rayfeasible = TRUE;
12527  lp->primalchecked = FALSE;
12528  }
12529 
12530  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12531 
12532  /* in debug mode, check that lazy bounds (if present) are not violated */
12533  checkLazyBounds(lp, set);
12534 
12535  if( !primalfeasible || !rayfeasible )
12536  {
12537  /* unbounded solution is infeasible (this can happen due to numerical problems):
12538  * forget about the LP at this node and mark it to be unsolved
12539 
12540  * @todo: like in the default LP solving evaluation, solve without fastmip,
12541  * with tighter feasibility tolerance and from scratch
12542  */
12543  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12544  lp->solved = FALSE;
12546  *lperror = TRUE;
12547  }
12548 
12549  }
12550 
12551  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12552  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12554  }
12555  else
12556  {
12557  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12558  }
12559  }
12560  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12561  {
12562  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12563  }
12564  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12565  break;
12566 
12568  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12569  break;
12570 
12572  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12573 
12574  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12575  stat->nclockskipsleft = 0;
12576  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12577  {
12578  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12579  "you might consider switching the clock type of SCIP\n");
12580  stat->status = SCIP_STATUS_TIMELIMIT;
12581  }
12582  break;
12583 
12584  case SCIP_LPSOLSTAT_ERROR:
12586  SCIPerrorMessage("error in LP solver\n");
12587  retcode = SCIP_LPERROR;
12588  goto TERMINATE;
12589 
12590  default:
12591  SCIPerrorMessage("unknown LP solution status\n");
12592  retcode = SCIP_ERROR;
12593  goto TERMINATE;
12594  }
12595  }
12596  assert(!(*lperror) || !lp->solved);
12597 
12598  TERMINATE:
12599  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12600  * may happen that we continue to solve from scratch during strong branching */
12601  if( lp->lpifromscratch )
12602  {
12603  SCIP_Bool success;
12604  (void) lpSetFromscratch(lp, FALSE, &success);
12605  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12606  }
12607 
12608  return retcode;
12609 }
12610 
12611 /** gets solution status of current LP */
12613  SCIP_LP* lp /**< current LP data */
12614  )
12615 {
12616  assert(lp != NULL);
12617  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12618 
12619  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12620 }
12621 
12622 /** gets objective value of current LP
12623  *
12624  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12625  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12626  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12627  */
12629  SCIP_LP* lp, /**< current LP data */
12630  SCIP_SET* set, /**< global SCIP settings */
12631  SCIP_PROB* prob /**< problem data */
12632  )
12633 {
12634  assert(lp != NULL);
12635  assert(lp->solved);
12636  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12637  assert(set != NULL);
12638 
12639  if( !lp->flushed )
12640  return SCIP_INVALID;
12641  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12642  return lp->lpobjval;
12643  else if( lp->looseobjvalinf > 0 )
12644  return -SCIPsetInfinity(set);
12645  else
12646  {
12647  /* recalculate the loose objective value, if needed */
12648  if( !lp->looseobjvalid )
12649  recomputeLooseObjectiveValue(lp, set, prob);
12650 
12651  return lp->lpobjval + lp->looseobjval;
12652  }
12653 }
12654 
12655 /** gets part of objective value of current LP that results from COLUMN variables only */
12657  SCIP_LP* lp /**< current LP data */
12658  )
12659 {
12660  assert(lp != NULL);
12661  assert(lp->solved);
12662 
12663  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12664 }
12665 
12666 /** gets part of objective value of current LP that results from LOOSE variables only */
12668  SCIP_LP* lp, /**< current LP data */
12669  SCIP_SET* set, /**< global SCIP settings */
12670  SCIP_PROB* prob /**< problem data */
12671  )
12672 {
12673  assert(lp != NULL);
12674  assert(lp->solved);
12675  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12676  assert(set != NULL);
12677 
12678  if( !lp->flushed )
12679  return SCIP_INVALID;
12680  else if( lp->looseobjvalinf > 0 )
12681  return -SCIPsetInfinity(set);
12682  else
12683  return getFiniteLooseObjval(lp, set, prob);
12684 }
12685 
12686 /** remembers the current LP objective value as root solution value */
12688  SCIP_LP* lp, /**< current LP data */
12689  SCIP_SET* set, /**< global SCIP settings */
12690  SCIP_PROB* prob /**< problem data */
12691  )
12692 {
12693  assert(lp != NULL);
12694 
12696  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12697 }
12698 
12699 /** invalidates the root LP solution value */
12701  SCIP_LP* lp /**< current LP data */
12702  )
12703 {
12704  assert(lp != NULL);
12705 
12706  lp->rootlpobjval = SCIP_INVALID;
12708 }
12709 
12710 /** recomputes local and global pseudo objective values */
12712  SCIP_LP* lp, /**< current LP data */
12713  SCIP_SET* set, /**< global SCIP settings */
12714  SCIP_PROB* prob /**< problem data */
12715  )
12716 {
12717  SCIP_VAR** vars;
12718  int nvars;
12719  int v;
12720 
12721  assert(lp != NULL);
12722  assert(set != NULL);
12723  assert(prob != NULL);
12724 
12725  vars = prob->vars;
12726  nvars = prob->nvars;
12727 
12728  lp->glbpseudoobjvalinf = 0;
12729  lp->glbpseudoobjval = 0.0;
12730 
12731  lp->pseudoobjvalinf = 0;
12732  lp->pseudoobjval = 0.0;
12733 
12734  for( v = 0; v < nvars; ++v )
12735  {
12736  SCIP_Real obj = SCIPvarGetObj(vars[v]);
12737 
12738  if( SCIPsetIsPositive(set, obj) )
12739  {
12740  /* update the global pseudo objective value */
12741  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
12742  ++(lp->glbpseudoobjvalinf);
12743  else
12744  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
12745 
12746  /* update the local pseudo objective value */
12747  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
12748  ++(lp->pseudoobjvalinf);
12749  else
12750  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
12751  }
12752 
12753  if( SCIPsetIsNegative(set, obj) )
12754  {
12755  /* update the global pseudo objective value */
12756  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
12757  ++(lp->glbpseudoobjvalinf);
12758  else
12759  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
12760 
12761  /* update the local pseudo objective value */
12762  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
12763  ++(lp->pseudoobjvalinf);
12764  else
12765  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
12766  }
12767  }
12768 
12769  /* the recomputed values are reliable */
12771  lp->glbpseudoobjvalid = TRUE;
12772  lp->relpseudoobjval = lp->pseudoobjval;
12773  lp->pseudoobjvalid = TRUE;
12774 }
12775 
12776 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
12777  * global bound
12778  */
12780  SCIP_LP* lp, /**< current LP data */
12781  SCIP_SET* set, /**< global SCIP settings */
12782  SCIP_PROB* prob /**< problem data */
12783  )
12784 {
12785  assert(lp != NULL);
12786  assert(lp->glbpseudoobjvalinf >= 0);
12787  assert(set != NULL);
12788 
12789  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
12790  return -SCIPsetInfinity(set);
12791  else
12792  {
12793  /* recalculate the global pseudo solution value, if needed */
12794  if( !lp->glbpseudoobjvalid )
12795  recomputeGlbPseudoObjectiveValue(lp, set, prob);
12796 
12797  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
12798  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
12799  return -SCIPsetInfinity(set);
12800 
12801  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
12802  return SCIPsetInfinity(set);
12803 
12804  return lp->glbpseudoobjval;
12805  }
12806 }
12807 
12808 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
12809  * objective function) local bound
12810  */
12812  SCIP_LP* lp, /**< current LP data */
12813  SCIP_SET* set, /**< global SCIP settings */
12814  SCIP_PROB* prob /**< problem data */
12815  )
12816 {
12817  assert(lp != NULL);
12818  assert(lp->pseudoobjvalinf >= 0);
12819  assert(set != NULL);
12820 
12821  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12822  return -SCIPsetInfinity(set);
12823  else
12824  {
12825  /* recalculate the pseudo solution value, if needed */
12826  if( !lp->pseudoobjvalid )
12827  recomputePseudoObjectiveValue(lp, set, prob);
12828 
12829  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
12830  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
12831  return -SCIPsetInfinity(set);
12832 
12833  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
12834  return SCIPsetInfinity(set);
12835 
12836  return lp->pseudoobjval;
12837  }
12838 }
12839 
12840 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
12842  SCIP_LP* lp, /**< current LP data */
12843  SCIP_SET* set, /**< global SCIP settings */
12844  SCIP_PROB* prob, /**< problem data */
12845  SCIP_VAR* var, /**< problem variable */
12846  SCIP_Real oldbound, /**< old value for bound */
12847  SCIP_Real newbound, /**< new value for bound */
12848  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12849  )
12850 {
12851  SCIP_Real pseudoobjval;
12852  int pseudoobjvalinf;
12853  SCIP_Real obj;
12854 
12855  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
12856  pseudoobjvalinf = lp->pseudoobjvalinf;
12857  obj = SCIPvarGetObj(var);
12858  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12859  {
12860  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12861  pseudoobjvalinf--;
12862  else
12863  pseudoobjval -= oldbound * obj;
12864  assert(pseudoobjvalinf >= 0);
12865  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12866  pseudoobjvalinf++;
12867  else
12868  pseudoobjval += newbound * obj;
12869  }
12870  assert(pseudoobjvalinf >= 0);
12871 
12872  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12873  return -SCIPsetInfinity(set);
12874  else
12875  return pseudoobjval;
12876 }
12877 
12878 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
12879  * perform calculations with interval arithmetic to get an exact lower bound
12880  */
12882  SCIP_LP* lp, /**< current LP data */
12883  SCIP_SET* set, /**< global SCIP settings */
12884  SCIP_VAR* var, /**< problem variable */
12885  SCIP_Real oldbound, /**< old value for bound */
12886  SCIP_Real newbound, /**< new value for bound */
12887  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12888  )
12889 {
12890  SCIP_Real pseudoobjval;
12891  int pseudoobjvalinf;
12892  SCIP_Real obj;
12893 
12894  assert(lp->pseudoobjvalid);
12895 
12896  pseudoobjval = lp->pseudoobjval;
12897  pseudoobjvalinf = lp->pseudoobjvalinf;
12898  obj = SCIPvarGetObj(var);
12899  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12900  {
12901  SCIP_INTERVAL objint;
12902  SCIP_INTERVAL bd;
12903  SCIP_INTERVAL prod;
12904  SCIP_INTERVAL psval;
12905 
12906  SCIPintervalSet(&psval, pseudoobjval);
12907  SCIPintervalSet(&objint, SCIPvarGetObj(var));
12908 
12909  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12910  pseudoobjvalinf--;
12911  else
12912  {
12913  SCIPintervalSet(&bd, oldbound);
12914  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12915  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
12916  }
12917  assert(pseudoobjvalinf >= 0);
12918  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12919  pseudoobjvalinf++;
12920  else
12921  {
12922  SCIPintervalSet(&bd, newbound);
12923  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12924  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
12925  }
12926 
12927  pseudoobjval = SCIPintervalGetInf(psval);
12928  }
12929  assert(pseudoobjvalinf >= 0);
12930 
12931  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12932  return -SCIPsetInfinity(set);
12933  else
12934  return pseudoobjval;
12935 }
12936 
12937 /** compute the objective delta due the new objective coefficient */
12938 static
12940  SCIP_SET* set, /**< global SCIP settings */
12941  SCIP_Real oldobj, /**< old objective value of variable */
12942  SCIP_Real newobj, /**< new objective value of variable */
12943  SCIP_Real lb, /**< lower bound of variable */
12944  SCIP_Real ub, /**< upper bound of variable */
12945  SCIP_Real* deltaval, /**< pointer to store the delta value */
12946  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12947  )
12948 {
12949  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
12950  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
12951  assert(!SCIPsetIsInfinity(set, lb));
12952  assert(!SCIPsetIsInfinity(set, -ub));
12953  assert(!SCIPsetIsEQ(set, oldobj, newobj));
12954 
12955  (*deltaval) = 0.0;
12956  (*deltainf) = 0;
12957 
12958  if( SCIPsetIsPositive(set, oldobj) )
12959  {
12960  /* sign of objective did not change */
12961  if( SCIPsetIsPositive(set, newobj) )
12962  {
12963  /* if the bound is finite, calculate the deltaval */
12964  if( !SCIPsetIsInfinity(set, -lb) )
12965  (*deltaval) = lb * (newobj - oldobj);
12966  }
12967  /* sign of objective did change, so the best bound does change */
12968  else if( SCIPsetIsNegative(set, newobj) )
12969  {
12970  if( SCIPsetIsInfinity(set, -lb) )
12971  {
12972  /* old best bound was infinite while new one is not */
12973  if( !SCIPsetIsInfinity(set, ub) )
12974  {
12975  (*deltainf) = -1;
12976  (*deltaval) = ub * newobj;
12977  }
12978  }
12979  else
12980  {
12981  /* new best bound is infinite while old one was not */
12982  if( SCIPsetIsInfinity(set, ub) )
12983  {
12984  (*deltainf) = 1;
12985  (*deltaval) = -lb * oldobj;
12986  }
12987  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12988  else
12989  {
12990  (*deltaval) = (ub * newobj) - (lb * oldobj);
12991  }
12992  }
12993  }
12994  /* new objective is 0.0 */
12995  else
12996  {
12997  if( SCIPsetIsInfinity(set, -lb) )
12998  (*deltainf) = -1;
12999  else
13000  (*deltaval) = -lb * oldobj;
13001  }
13002 
13003  }
13004  else if( SCIPsetIsNegative(set, oldobj) )
13005  {
13006  /* sign of objective did not change */
13007  if( SCIPsetIsNegative(set, newobj) )
13008  {
13009  /* if the bound is finite, calculate the deltaval */
13010  if( !SCIPsetIsInfinity(set, ub) )
13011  (*deltaval) = ub * (newobj - oldobj);
13012  }
13013  /* sign of objective did change, so the best bound does change */
13014  else if( SCIPsetIsPositive(set, newobj) )
13015  {
13016  if( SCIPsetIsInfinity(set, ub) )
13017  {
13018  /* old best bound was infinite while new one is not */
13019  if( !SCIPsetIsInfinity(set, -lb) )
13020  {
13021  (*deltainf) = -1;
13022  (*deltaval) = lb * newobj;
13023  }
13024  }
13025  else
13026  {
13027  /* new best bound is infinite while old one was not */
13028  if( SCIPsetIsInfinity(set, -lb) )
13029  {
13030  (*deltainf) = 1;
13031  (*deltaval) = -ub * oldobj;
13032  }
13033  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13034  else
13035  {
13036  (*deltaval) = (lb * newobj) - (ub * oldobj);
13037  }
13038  }
13039  }
13040  /* new objective is 0.0 */
13041  else
13042  {
13043  if( SCIPsetIsInfinity(set, ub) )
13044  (*deltainf) = -1;
13045  else
13046  (*deltaval) = -ub * oldobj;
13047  }
13048  }
13049  /* old objective was 0.0 */
13050  else
13051  {
13052  if( SCIPsetIsNegative(set, newobj) )
13053  {
13054  if( SCIPsetIsInfinity(set, ub) )
13055  (*deltainf) = 1;
13056  else
13057  (*deltaval) = ub * newobj;
13058  }
13059  else if( SCIPsetIsPositive(set, newobj) )
13060  {
13061  if( SCIPsetIsInfinity(set, -lb) )
13062  (*deltainf) = 1;
13063  else
13064  (*deltaval) = lb * newobj;
13065  }
13066  }
13067 }
13068 
13069 /** compute the objective delta due the new lower bound */
13070 static
13072  SCIP_SET* set, /**< global SCIP settings */
13073  SCIP_Real obj, /**< objective value of variable */
13074  SCIP_Real oldlb, /**< old lower bound of variable */
13075  SCIP_Real newlb, /**< new lower bound of variable */
13076  SCIP_Real* deltaval, /**< pointer to store the delta value */
13077  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13078  )
13079 {
13080  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13081  assert(!SCIPsetIsInfinity(set, oldlb));
13082  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13083  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13084 
13085  if( SCIPsetIsInfinity(set, -oldlb) )
13086  {
13087  if( !SCIPsetIsInfinity(set, newlb) )
13088  {
13089  (*deltainf) = -1;
13090  (*deltaval) = newlb * obj;
13091  }
13092  else
13093  {
13094  (*deltainf) = 0;
13095  (*deltaval) = 0.0;
13096  }
13097  }
13098  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13099  {
13100  (*deltainf) = 1;
13101  (*deltaval) = -oldlb * obj;
13102  }
13103  else
13104  {
13105  (*deltainf) = 0;
13106  (*deltaval) = obj * (newlb - oldlb);
13107  }
13108 }
13109 
13110 /** compute the objective delta due the new upper bound */
13111 static
13113  SCIP_SET* set, /**< global SCIP settings */
13114  SCIP_Real obj, /**< objective value of variable */
13115  SCIP_Real oldub, /**< old upper bound of variable */
13116  SCIP_Real newub, /**< new upper bound of variable */
13117  SCIP_Real* deltaval, /**< pointer to store the delta value */
13118  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13119  )
13120 {
13121  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13122  assert(!SCIPsetIsInfinity(set, -oldub));
13123  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13124  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13125 
13126  if( SCIPsetIsInfinity(set, oldub) )
13127  {
13128  if( !SCIPsetIsInfinity(set, -newub) )
13129  {
13130  (*deltainf) = -1;
13131  (*deltaval) = newub * obj;
13132  }
13133  else
13134  {
13135  (*deltainf) = 0;
13136  (*deltaval) = 0.0;
13137  }
13138  }
13139  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13140  {
13141  (*deltainf) = 1;
13142  (*deltaval) = -oldub * obj;
13143  }
13144  else
13145  {
13146  (*deltainf) = 0;
13147  (*deltaval) = obj * (newub - oldub);
13148  }
13149 }
13150 
13151 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13152 static
13154  SCIP_LP* lp, /**< current LP data */
13155  SCIP_SET* set, /**< global SCIP settings */
13156  SCIP_VAR* var, /**< problem variable that changed */
13157  SCIP_Real deltaval, /**< delta value in the objective function */
13158  int deltainf, /**< delta value for the number of variables with infinite best bound */
13159  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13160  SCIP_Bool loose, /**< should the loose objective value be updated? */
13161  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13162  )
13163 {
13164  assert(lp != NULL);
13165  assert(lp->looseobjvalinf >= 0);
13166  assert(lp->pseudoobjvalinf >= 0);
13167  assert(lp->glbpseudoobjvalinf >= 0);
13168 
13169  /* update the pseudo objective value */
13170  if( local )
13171  {
13172  lp->pseudoobjvalinf += deltainf;
13173  if( lp->pseudoobjvalid )
13174  {
13175  lp->pseudoobjval += deltaval;
13176 
13177  /* if the absolute value was increased, this is regarded as reliable,
13178  * otherwise, we check whether we can still trust the updated value
13179  */
13180  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13181  lp->relpseudoobjval = lp->pseudoobjval;
13182  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13183  lp->pseudoobjvalid = FALSE;
13184  }
13185 
13186  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13188  loose = TRUE;
13189  }
13190  /* update the loose objective value */
13191  if( loose )
13192  {
13193  lp->looseobjvalinf += deltainf;
13194 
13195  if( deltaval != 0.0 && lp->looseobjvalid )
13196  {
13197  lp->looseobjval += deltaval;
13198 
13199  /* if the absolute value was increased, this is regarded as reliable,
13200  * otherwise, we check whether we can still trust the updated value
13201  */
13202  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13203  lp->rellooseobjval = lp->looseobjval;
13204  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13205  lp->looseobjvalid = FALSE;
13206  }
13207  }
13208  /* update the root pseudo objective values */
13209  if( global )
13210  {
13211  lp->glbpseudoobjvalinf += deltainf;
13212  if( lp->glbpseudoobjvalid )
13213  {
13214  lp->glbpseudoobjval += deltaval;
13215 
13216  /* if the absolute value was increased, this is regarded as reliable,
13217  * otherwise, we check whether we can still trust the updated value
13218  */
13222  lp->glbpseudoobjvalid = FALSE;
13223  }
13224  }
13225 
13226  assert(lp->looseobjvalinf >= 0);
13227  assert(lp->pseudoobjvalinf >= 0);
13228  assert(lp->glbpseudoobjvalinf >= 0);
13229 }
13230 
13231 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13232  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13233  */
13234 static
13236  SCIP_LP* lp, /**< current LP data */
13237  SCIP_SET* set, /**< global SCIP settings */
13238  SCIP_VAR* var, /**< problem variable that changed */
13239  SCIP_Real oldobj, /**< old objective value of variable */
13240  SCIP_Real oldlb, /**< old objective value of variable */
13241  SCIP_Real oldub, /**< old objective value of variable */
13242  SCIP_Real newobj, /**< new objective value of variable */
13243  SCIP_Real newlb, /**< new objective value of variable */
13244  SCIP_Real newub /**< new objective value of variable */
13245  )
13246 {
13247  SCIP_INTERVAL deltaval;
13248  SCIP_INTERVAL bd;
13249  SCIP_INTERVAL obj;
13250  SCIP_INTERVAL prod;
13251  SCIP_INTERVAL psval;
13252  int deltainf;
13253 
13254  assert(lp != NULL);
13255  assert(lp->pseudoobjvalinf >= 0);
13256  assert(lp->looseobjvalinf >= 0);
13257  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13258  assert(!SCIPsetIsInfinity(set, oldlb));
13259  assert(!SCIPsetIsInfinity(set, -oldub));
13260  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13261  assert(!SCIPsetIsInfinity(set, newlb));
13262  assert(!SCIPsetIsInfinity(set, -newub));
13263  assert(var != NULL);
13264 
13266  {
13267  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13268  return SCIP_INVALIDDATA;
13269  }
13270 
13271  assert(SCIPvarGetProbindex(var) >= 0);
13272 
13273  SCIPintervalSet(&deltaval, 0.0);
13274  deltainf = 0;
13275 
13276  /* subtract old pseudo objective value */
13277  if( oldobj > 0.0 )
13278  {
13279  if( SCIPsetIsInfinity(set, -oldlb) )
13280  deltainf--;
13281  else
13282  {
13283  SCIPintervalSet(&bd, oldlb);
13284  SCIPintervalSet(&obj, oldobj);
13285  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13286  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13287  }
13288  }
13289  else if( oldobj < 0.0 )
13290  {
13291  if( SCIPsetIsInfinity(set, oldub) )
13292  deltainf--;
13293  else
13294  {
13295  SCIPintervalSet(&bd, oldub);
13296  SCIPintervalSet(&obj, oldobj);
13297  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13298  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13299  }
13300  }
13301 
13302  /* add new pseudo objective value */
13303  if( newobj > 0.0 )
13304  {
13305  if( SCIPsetIsInfinity(set, -newlb) )
13306  deltainf++;
13307  else
13308  {
13309  SCIPintervalSet(&bd, newlb);
13310  SCIPintervalSet(&obj, newobj);
13311  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13312  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13313  }
13314  }
13315  else if( newobj < 0.0 )
13316  {
13317  if( SCIPsetIsInfinity(set, newub) )
13318  deltainf++;
13319  else
13320  {
13321  SCIPintervalSet(&bd, newub);
13322  SCIPintervalSet(&obj, newobj);
13323  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13324  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13325  }
13326  }
13327 
13328  /* update the pseudo and loose objective values */
13329  SCIPintervalSet(&psval, lp->pseudoobjval);
13330  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13331  lp->pseudoobjval = SCIPintervalGetInf(psval);
13332  lp->pseudoobjvalinf += deltainf;
13334  {
13335  SCIPintervalSet(&psval, lp->looseobjval);
13336  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13337  lp->looseobjval = SCIPintervalGetInf(psval);
13338  lp->looseobjvalinf += deltainf;
13339  }
13340 
13341  assert(lp->pseudoobjvalinf >= 0);
13342  assert(lp->looseobjvalinf >= 0);
13343 
13344  return SCIP_OKAY;
13345 }
13346 
13347 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13349  SCIP_LP* lp, /**< current LP data */
13350  SCIP_SET* set, /**< global SCIP settings */
13351  SCIP_VAR* var, /**< problem variable that changed */
13352  SCIP_Real oldobj, /**< old objective value of variable */
13353  SCIP_Real newobj /**< new objective value of variable */
13354  )
13355 {
13356  assert(set != NULL);
13357  assert(var != NULL);
13358 
13359  if( set->misc_exactsolve )
13360  {
13361  if( oldobj != newobj ) /*lint !e777*/
13362  {
13363  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13364  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13365  }
13366  }
13367  else
13368  {
13369  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13370  {
13371  SCIP_Real deltaval;
13372  int deltainf;
13373 
13375  assert(SCIPvarGetProbindex(var) >= 0);
13376 
13377  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13378  * domain of the variable are the same
13379  */
13380  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13381  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13382 
13383  /* compute the pseudo objective delta due the new objective coefficient */
13384  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13385 
13386  /* update the local pseudo objective value */
13387  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13388 
13389  /* compute the pseudo objective delta due the new objective coefficient */
13390  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13391 
13392  /* update the global pseudo objective value */
13393  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13394  }
13395  }
13396 
13397  return SCIP_OKAY;
13398 }
13399 
13400 
13401 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13403  SCIP_LP* lp, /**< current LP data */
13404  SCIP_SET* set, /**< global SCIP settings */
13405  SCIP_VAR* var, /**< problem variable that changed */
13406  SCIP_Real oldlb, /**< old lower bound of variable */
13407  SCIP_Real newlb /**< new lower bound of variable */
13408  )
13409 {
13410  assert(set != NULL);
13411  assert(var != NULL);
13412 
13413  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13414  {
13415  SCIP_Real deltaval;
13416  int deltainf;
13417 
13418  /* compute the pseudo objective delta due the new lower bound */
13419  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13420 
13421  /* update the root pseudo objective values */
13422  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13423 
13424  }
13425 
13426  return SCIP_OKAY;
13427 }
13428 
13429 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13431  SCIP_LP* lp, /**< current LP data */
13432  SCIP_SET* set, /**< global SCIP settings */
13433  SCIP_VAR* var, /**< problem variable that changed */
13434  SCIP_Real oldlb, /**< old lower bound of variable */
13435  SCIP_Real newlb /**< new lower bound of variable */
13436  )
13437 {
13438  assert(set != NULL);
13439  assert(var != NULL);
13440 
13441  if( set->misc_exactsolve )
13442  {
13443  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13444  {
13445  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13446  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13447  }
13448  }
13449  else
13450  {
13451  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13452  {
13453  SCIP_Real deltaval;
13454  int deltainf;
13455 
13457  assert(SCIPvarGetProbindex(var) >= 0);
13458 
13459  /* compute the pseudo objective delta due the new lower bound */
13460  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13461 
13462  /* update the pseudo and loose objective values */
13463  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13464  }
13465  }
13466 
13467  return SCIP_OKAY;
13468 }
13469 
13470 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13472  SCIP_LP* lp, /**< current LP data */
13473  SCIP_SET* set, /**< global SCIP settings */
13474  SCIP_VAR* var, /**< problem variable that changed */
13475  SCIP_Real oldub, /**< old upper bound of variable */
13476  SCIP_Real newub /**< new upper bound of variable */
13477  )
13478 {
13479  assert(set != NULL);
13480  assert(var != NULL);
13481 
13482  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13483  {
13484  SCIP_Real deltaval;
13485  int deltainf;
13486 
13487  /* compute the pseudo objective delta due the new upper bound */
13488  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13489 
13490  /* update the root pseudo objective values */
13491  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13492  }
13493 
13494  return SCIP_OKAY;
13495 }
13496 
13497 /** updates current pseudo objective value for a change in a variable's upper bound */
13499  SCIP_LP* lp, /**< current LP data */
13500  SCIP_SET* set, /**< global SCIP settings */
13501  SCIP_VAR* var, /**< problem variable that changed */
13502  SCIP_Real oldub, /**< old upper bound of variable */
13503  SCIP_Real newub /**< new upper bound of variable */
13504  )
13505 {
13506  assert(set != NULL);
13507  assert(var != NULL);
13508 
13509  if( set->misc_exactsolve )
13510  {
13511  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13512  {
13513  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13514  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13515  }
13516  }
13517  else
13518  {
13519  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13520  {
13521  SCIP_Real deltaval;
13522  int deltainf;
13523 
13525  assert(SCIPvarGetProbindex(var) >= 0);
13526 
13527  /* compute the pseudo objective delta due the new upper bound */
13528  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13529 
13530  /* update the pseudo and loose objective values */
13531  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13532  }
13533  }
13534 
13535  return SCIP_OKAY;
13536 }
13537 
13538 /** informs LP, that given variable was added to the problem */
13540  SCIP_LP* lp, /**< current LP data */
13541  SCIP_SET* set, /**< global SCIP settings */
13542  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13543  )
13544 {
13545  assert(lp != NULL);
13547  assert(SCIPvarGetProbindex(var) >= 0);
13548 
13549  /* add the variable to the loose objective value sum */
13550  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13551 
13552  /* update the loose variables counter */
13554  lp->nloosevars++;
13555 
13556  return SCIP_OKAY;
13557 }
13558 
13559 /** informs LP, that given variable is to be deleted from the problem */
13561  SCIP_LP* lp, /**< current LP data */
13562  SCIP_SET* set, /**< global SCIP settings */
13563  SCIP_VAR* var /**< variable that will be deleted from the problem */
13564  )
13565 {
13566  assert(lp != NULL);
13568  assert(SCIPvarGetProbindex(var) >= 0);
13569 
13570  /* subtract the variable from the loose objective value sum */
13571  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13572 
13573  /* update the loose variables counter */
13575  {
13576  SCIPlpDecNLoosevars(lp);
13577  }
13578 
13579  return SCIP_OKAY;
13580 }
13581 
13582 /** informs LP, that given formerly loose problem variable is now a column variable */
13583 static
13585  SCIP_LP* lp, /**< current LP data */
13586  SCIP_SET* set, /**< global SCIP settings */
13587  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13588  )
13589 {
13590  SCIP_Real obj;
13591  SCIP_Real lb;
13592  SCIP_Real ub;
13593 
13594  assert(lp != NULL);
13595  assert(lp->nloosevars > 0);
13596  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13597  assert(SCIPvarGetProbindex(var) >= 0);
13598  assert(lp->looseobjvalinf >= 0);
13599 
13600  obj = SCIPvarGetObj(var);
13601 
13602  /* update loose objective value */
13603  if( SCIPsetIsPositive(set, obj) )
13604  {
13605  lb = SCIPvarGetLbLocal(var);
13606  if( SCIPsetIsInfinity(set, -lb) )
13607  lp->looseobjvalinf--;
13608  else
13609  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13610  }
13611  else if( SCIPsetIsNegative(set, obj) )
13612  {
13613  ub = SCIPvarGetUbLocal(var);
13614  if( SCIPsetIsInfinity(set, ub) )
13615  lp->looseobjvalinf--;
13616  else
13617  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13618  }
13619 
13620  SCIPlpDecNLoosevars(lp);
13621 
13622  assert(lp->looseobjvalinf >= 0);
13623 
13624  return SCIP_OKAY;
13625 }
13626 
13627 /** informs LP, that given formerly loose problem variable is now a column variable
13628  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13629  */
13630 static
13632  SCIP_LP* lp, /**< current LP data */
13633  SCIP_SET* set, /**< global SCIP settings */
13634  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13635  )
13636 {
13637  SCIP_INTERVAL bd;
13638  SCIP_INTERVAL ob;
13639  SCIP_INTERVAL prod;
13640  SCIP_INTERVAL loose;
13641  SCIP_Real obj;
13642  SCIP_Real lb;
13643  SCIP_Real ub;
13644 
13645  assert(lp != NULL);
13646  assert(lp->nloosevars > 0);
13647  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13648  assert(SCIPvarGetProbindex(var) >= 0);
13649 
13650  obj = SCIPvarGetObj(var);
13651 
13652  SCIPintervalSet(&loose, lp->looseobjval);
13653 
13654  /* update loose objective value corresponding to the deletion of variable */
13655  if( obj > 0.0 )
13656  {
13657  lb = SCIPvarGetLbLocal(var);
13658  if( SCIPsetIsInfinity(set, -lb) )
13659  lp->looseobjvalinf--;
13660  else
13661  {
13662  SCIPintervalSet(&bd, lb);
13663  SCIPintervalSet(&ob, obj);
13664  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13665  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13666  }
13667  }
13668  else if( SCIPsetIsNegative(set, obj) )
13669  {
13670  ub = SCIPvarGetUbLocal(var);
13671  if( SCIPsetIsInfinity(set, ub) )
13672  lp->looseobjvalinf--;
13673  else
13674  {
13675  SCIPintervalSet(&bd, ub);
13676  SCIPintervalSet(&ob, obj);
13677  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13678  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13679  }
13680  }
13681  lp->nloosevars--;
13682 
13683  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13684  if( lp->nloosevars == 0 )
13685  {
13686  assert(lp->looseobjvalinf == 0);
13687  lp->looseobjval = 0.0;
13688  }
13689  else
13690  lp->looseobjval = SCIPintervalGetInf(loose);
13691 
13692  return SCIP_OKAY;
13693 }
13694 
13695 /** informs LP, that given formerly loose problem variable is now a column variable */
13697  SCIP_LP* lp, /**< current LP data */
13698  SCIP_SET* set, /**< global SCIP settings */
13699  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13700  )
13701 {
13702  assert(set != NULL);
13703 
13704  if( set->misc_exactsolve )
13705  {
13706  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13707  }
13708  else
13709  {
13710  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13711  }
13712 
13713  return SCIP_OKAY;
13714 }
13715 
13716 /** informs LP, that given formerly column problem variable is now again a loose variable */
13717 static
13719  SCIP_LP* lp, /**< current LP data */
13720  SCIP_SET* set, /**< global SCIP settings */
13721  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13722  )
13723 {
13724  SCIP_Real obj;
13725  SCIP_Real lb;
13726  SCIP_Real ub;
13727 
13728  assert(lp != NULL);
13729  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13730  assert(SCIPvarGetProbindex(var) >= 0);
13731  assert(lp->looseobjvalinf >= 0);
13732 
13733  obj = SCIPvarGetObj(var);
13734 
13735  /* update loose objective value corresponding to the addition of variable */
13736  if( SCIPsetIsPositive(set, obj) )
13737  {
13738  lb = SCIPvarGetLbLocal(var);
13739  if( SCIPsetIsInfinity(set, -lb) )
13740  lp->looseobjvalinf++;
13741  else
13742  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
13743  }
13744  else if( SCIPsetIsNegative(set, obj) )
13745  {
13746  ub = SCIPvarGetUbLocal(var);
13747  if( SCIPsetIsInfinity(set, ub) )
13748  lp->looseobjvalinf++;
13749  else
13750  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
13751  }
13752  lp->nloosevars++;
13753 
13754  assert(lp->looseobjvalinf >= 0);
13755 
13756  return SCIP_OKAY;
13757 }
13758 
13759 /** informs LP, that given formerly column problem variable is now again a loose variable
13760  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13761  */
13762 static
13764  SCIP_LP* lp, /**< current LP data */
13765  SCIP_SET* set, /**< global SCIP settings */
13766  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13767  )
13768 {
13769  SCIP_INTERVAL bd;
13770  SCIP_INTERVAL ob;
13771  SCIP_INTERVAL prod;
13772  SCIP_INTERVAL loose;
13773  SCIP_Real obj;
13774  SCIP_Real lb;
13775  SCIP_Real ub;
13776 
13777  assert(lp != NULL);
13778  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13779  assert(SCIPvarGetProbindex(var) >= 0);
13780 
13781  obj = SCIPvarGetObj(var);
13782 
13783  SCIPintervalSet(&loose, lp->looseobjval);
13784 
13785  /* update loose objective value corresponding to the deletion of variable */
13786  if( obj > 0.0 )
13787  {
13788  lb = SCIPvarGetLbLocal(var);
13789  if( SCIPsetIsInfinity(set, -lb) )
13790  lp->looseobjvalinf++;
13791  else
13792  {
13793  SCIPintervalSet(&bd, lb);
13794  SCIPintervalSet(&ob, obj);
13795  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13796  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
13797  }
13798  }
13799  else if( SCIPsetIsNegative(set, obj) )
13800  {
13801  ub = SCIPvarGetUbLocal(var);
13802  if( SCIPsetIsInfinity(set, ub) )
13803  lp->looseobjvalinf++;
13804  else
13805  {
13806  SCIPintervalSet(&bd, ub);
13807  SCIPintervalSet(&ob, obj);
13808  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13809  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
13810  }
13811  }
13812  lp->nloosevars++;
13813 
13814  lp->looseobjval = SCIPintervalGetInf(loose);
13815 
13816  return SCIP_OKAY;
13817 }
13818 
13819 /** informs LP, that given formerly column problem variable is now again a loose variable */
13821  SCIP_LP* lp, /**< current LP data */
13822  SCIP_SET* set, /**< global SCIP settings */
13823  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13824  )
13825 {
13826  assert(set != NULL);
13827 
13828  if( set->misc_exactsolve )
13829  {
13830  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
13831  }
13832  else
13833  {
13834  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
13835  }
13836 
13837  return SCIP_OKAY;
13838 }
13839 
13840 /** decrease the number of loose variables by one */
13842  SCIP_LP* lp /**< current LP data */
13843  )
13844 {
13845  assert(lp != NULL);
13846  assert(lp->nloosevars > 0);
13847 
13848  lp->nloosevars--;
13849 
13850  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13851  if( lp->nloosevars == 0 )
13852  {
13853  assert(lp->looseobjvalinf == 0);
13854  lp->looseobjval = 0.0;
13855  }
13856 }
13857 
13858 /** stores the LP solution in the columns and rows */
13860  SCIP_LP* lp, /**< current LP data */
13861  SCIP_SET* set, /**< global SCIP settings */
13862  SCIP_STAT* stat, /**< problem statistics */
13863  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
13864  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
13865  )
13866 {
13867  SCIP_COL** lpicols;
13868  SCIP_ROW** lpirows;
13869  SCIP_Real* primsol;
13870  SCIP_Real* dualsol;
13871  SCIP_Real* activity;
13872  SCIP_Real* redcost;
13873  SCIP_Real primalbound;
13874  SCIP_Real dualbound;
13875  SCIP_Bool stillprimalfeasible;
13876  SCIP_Bool stilldualfeasible;
13877  int* cstat;
13878  int* rstat;
13879  SCIP_Longint lpcount;
13880  int nlpicols;
13881  int nlpirows;
13882  int c;
13883  int r;
13884 
13885  assert(lp != NULL);
13886  assert(lp->flushed);
13887  assert(lp->solved);
13888  assert(set != NULL);
13889  assert(stat != NULL);
13890  assert(lp->validsollp <= stat->lpcount);
13891 
13892  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
13893  * corresponding flag immediately to FALSE to skip all checks
13894  */
13895  if( primalfeasible == NULL )
13896  stillprimalfeasible = FALSE;
13897  else
13898  {
13899  *primalfeasible = TRUE;
13900  stillprimalfeasible = TRUE;
13901  }
13902  if( dualfeasible == NULL )
13903  stilldualfeasible = FALSE;
13904  else
13905  {
13906  *dualfeasible = TRUE;
13907  stilldualfeasible = TRUE;
13908  }
13909 
13910  /* check if the values are already calculated */
13911  if( lp->validsollp == stat->lpcount )
13912  return SCIP_OKAY;
13913  lp->validsollp = stat->lpcount;
13914 
13915  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
13916  stat->lpcount, SCIPlpGetSolstat(lp));
13917 
13918  lpicols = lp->lpicols;
13919  lpirows = lp->lpirows;
13920  nlpicols = lp->nlpicols;
13921  nlpirows = lp->nlpirows;
13922  lpcount = stat->lpcount;
13923 
13924  /* get temporary memory */
13925  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
13926  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
13927  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
13928  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
13929  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
13930  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
13931 
13932  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
13933  if( lp->solisbasic )
13934  {
13935  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
13936  }
13937  else
13938  {
13939  BMSclearMemoryArray(cstat, nlpicols);
13940  BMSclearMemoryArray(rstat, nlpirows);
13941  }
13942 
13943  primalbound = 0.0;
13944  dualbound = 0.0;
13945 
13946  /* copy primal solution and reduced costs into columns */
13947  for( c = 0; c < nlpicols; ++c )
13948  {
13949  assert( 0 <= cstat[c] && cstat[c] < 4 );
13950  lpicols[c]->primsol = primsol[c];
13951  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
13952  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
13953  lpicols[c]->redcost = redcost[c];
13954  lpicols[c]->basisstatus = (unsigned int) cstat[c];
13955  lpicols[c]->validredcostlp = lpcount;
13956  if( stillprimalfeasible )
13957  {
13958  stillprimalfeasible =
13959  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
13960  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
13961  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
13962  }
13963  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13964  {
13965  double compslack;
13966 
13967  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13968  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
13969  * variables, which would magnify even the tiniest violation in the dual multiplier
13970  */
13971  if( stilldualfeasible )
13972  {
13973  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
13974  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13975  }
13976  if( stilldualfeasible )
13977  {
13978  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
13979  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13980  }
13981 
13982  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13983  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13984  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13985  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13986  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13987  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
13988  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
13989  dualfeasible != NULL ? stilldualfeasible : TRUE);
13990  }
13991  else
13992  {
13993  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
13994  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
13995  {
13996  lpicols[c]->redcost = 0.0;
13997  }
13998 
13999  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14000  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14001  * bounds, its reduced cost must be zero
14002  */
14003  if( stilldualfeasible
14004  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
14005  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14006  if( stilldualfeasible
14007  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
14008  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14009 
14010  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14011  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14012  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14013  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14014  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14015  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14016  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14017  dualfeasible != NULL ? stilldualfeasible : TRUE);
14018  }
14019 
14020  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14021  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14022  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14023  */
14024  if( stilldualfeasible )
14025  {
14026  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14027  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14028  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14029  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14030  }
14031  }
14032 
14033  /* copy dual solution and activities into rows */
14034  for( r = 0; r < nlpirows; ++r )
14035  {
14036  assert( 0 <= rstat[r] && rstat[r] < 4 );
14037  lpirows[r]->dualsol = dualsol[r];
14038  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14039  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14040  lpirows[r]->validactivitylp = lpcount;
14041  if( stillprimalfeasible )
14042  {
14043  stillprimalfeasible =
14044  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14045  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14046  }
14047  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14048  {
14049  double compslack;
14050 
14051  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14052  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14053  * variables, which would magnify even the tiniest violation in the dual multiplier
14054  */
14055  if( stilldualfeasible )
14056  {
14057  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14058  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14059  }
14060  if( stilldualfeasible )
14061  {
14062  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14063  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14064  }
14065 
14066  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14067  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14068  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14069  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14070  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14071  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14072  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14073  dualfeasible != NULL ? stilldualfeasible : TRUE);
14074  }
14075  else
14076  {
14077  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14078  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14079  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14080  */
14081  if( stilldualfeasible &&
14082  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
14083  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14084  if( stilldualfeasible &&
14085  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
14086  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14087 
14088  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14089  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14090  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14091  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14092  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14093  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14094  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14095  dualfeasible != NULL ? stilldualfeasible : TRUE);
14096  }
14097 
14098  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14099  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14100  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14101  */
14102  if( stilldualfeasible )
14103  {
14104  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14105  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14106  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14107  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14108  }
14109  }
14110 
14111  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14112  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14113  * infinity
14114  */
14115  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14116  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14117  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14118  {
14119  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14120  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14121  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14122  }
14123 
14124  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14125  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14126  */
14127  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14128  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14129  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14130  {
14131  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14132  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14133  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14134  }
14135 
14136  if( primalfeasible != NULL )
14137  *primalfeasible = stillprimalfeasible;
14138  if( dualfeasible != NULL )
14139  *dualfeasible = stilldualfeasible;
14140 
14141  /* free temporary memory */
14142  SCIPsetFreeBufferArray(set, &rstat);
14143  SCIPsetFreeBufferArray(set, &cstat);
14144  SCIPsetFreeBufferArray(set, &redcost);
14145  SCIPsetFreeBufferArray(set, &activity);
14146  SCIPsetFreeBufferArray(set, &dualsol);
14147  SCIPsetFreeBufferArray(set, &primsol);
14148 
14149  return SCIP_OKAY;
14150 }
14151 
14152 /** stores LP solution with infinite objective value in the columns and rows */
14154  SCIP_LP* lp, /**< current LP data */
14155  SCIP_SET* set, /**< global SCIP settings */
14156  SCIP_STAT* stat, /**< problem statistics */
14157  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14158  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14159  )
14160 {
14161  SCIP_COL** lpicols;
14162  SCIP_ROW** lpirows;
14163  SCIP_Real* primsol;
14164  SCIP_Real* activity;
14165  SCIP_Real* ray;
14166  SCIP_Real rayobjval;
14167  SCIP_Real rayscale;
14168  SCIP_Longint lpcount;
14169  int nlpicols;
14170  int nlpirows;
14171  int c;
14172  int r;
14173 
14174  assert(lp != NULL);
14175  assert(lp->flushed);
14176  assert(lp->solved);
14177  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14178  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14179  assert(set != NULL);
14180  assert(stat != NULL);
14181  assert(lp->validsollp <= stat->lpcount);
14182 
14183  if( primalfeasible != NULL )
14184  *primalfeasible = TRUE;
14185  if( rayfeasible != NULL )
14186  *rayfeasible = TRUE;
14187 
14188  /* check if the values are already calculated */
14189  if( lp->validsollp == stat->lpcount )
14190  return SCIP_OKAY;
14191 
14192  /* check if the LP solver is able to provide a primal unbounded ray */
14193  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14194  {
14195  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14196  return SCIP_LPERROR;
14197  }
14198 
14199  lp->validsollp = stat->lpcount;
14200 
14201  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14202 
14203  /* get temporary memory */
14204  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14205  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14206  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14207 
14208  /* get primal feasible point */
14209  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14210 
14211  /* get primal unbounded ray */
14212  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14213 
14214  lpicols = lp->lpicols;
14215  lpirows = lp->lpirows;
14216  nlpicols = lp->nlpicols;
14217  nlpirows = lp->nlpirows;
14218  lpcount = stat->lpcount;
14219 
14220  /* calculate the objective value decrease of the ray */
14221  rayobjval = 0.0;
14222  for( c = 0; c < nlpicols; ++c )
14223  {
14224  assert(lpicols[c] != NULL);
14225  assert(lpicols[c]->var != NULL);
14226 
14227  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14228  if( rayfeasible != NULL )
14229  *rayfeasible = *rayfeasible
14230  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -lpicols[c]->lb))
14231  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, lpicols[c]->ub));
14232 
14233  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14234  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14235  */
14236  if( primalfeasible != NULL )
14237  *primalfeasible = *primalfeasible
14238  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14239  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14240 
14241  if( !SCIPsetIsZero(set, ray[c]) )
14242  rayobjval += ray[c] * lpicols[c]->obj;
14243  }
14244 
14245  /* if the finite point is already infeasible, we do not have to add the ray */
14246  if( primalfeasible != NULL && !(*primalfeasible) )
14247  {
14248  rayscale = 0.0;
14249  }
14250  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14251  else if( rayfeasible != NULL && !(*rayfeasible) )
14252  {
14253  rayscale = 0.0;
14254  }
14255  /* due to numerical problems, the objective of the ray might be nonnegative,
14256  *
14257  * @todo How to check for negative objective value here?
14258  */
14259  else if( !SCIPsetIsNegative(set, rayobjval) )
14260  {
14261  if( rayfeasible != NULL )
14262  {
14263  *rayfeasible = FALSE;
14264  }
14265 
14266  rayscale = 0.0;
14267  }
14268  else
14269  {
14270  assert(rayobjval != 0.0);
14271 
14272  /* scale the ray, such that the resulting point has infinite objective value */
14273  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14274  assert(SCIPsetIsFeasPositive(set, rayscale));
14275 
14276  /* ensure that unbounded point does not violate the bounds of the variables */
14277  for( c = 0; c < nlpicols; ++c )
14278  {
14279  if( SCIPsetIsPositive(set, ray[c]) )
14280  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14281  else if( SCIPsetIsNegative(set, ray[c]) )
14282  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14283 
14284  assert(SCIPsetIsFeasPositive(set, rayscale));
14285  }
14286  }
14287 
14288  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14289 
14290  /* calculate the unbounded point: x' = x + rayscale * ray */
14291  for( c = 0; c < nlpicols; ++c )
14292  {
14293  if( SCIPsetIsZero(set, ray[c]) )
14294  lpicols[c]->primsol = primsol[c];
14295  else
14296  {
14297  SCIP_Real primsolval = primsol[c] + rayscale * ray[c];
14298  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14299  }
14300  lpicols[c]->redcost = SCIP_INVALID;
14301  lpicols[c]->validredcostlp = -1;
14302  }
14303 
14304  for( r = 0; r < nlpirows; ++r )
14305  {
14306  lpirows[r]->dualsol = SCIP_INVALID;
14307  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14308  lpirows[r]->validactivitylp = lpcount;
14309 
14310  /* check for feasibility of the rows */
14311  if( primalfeasible != NULL )
14312  *primalfeasible = *primalfeasible
14313  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14314  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14315  }
14316 
14317  /* free temporary memory */
14318  SCIPsetFreeBufferArray(set, &ray);
14319  SCIPsetFreeBufferArray(set, &activity);
14320  SCIPsetFreeBufferArray(set, &primsol);
14321 
14322  return SCIP_OKAY;
14323 }
14324 
14325 /** returns primal ray proving the unboundedness of the current LP */
14327  SCIP_LP* lp, /**< current LP data */
14328  SCIP_SET* set, /**< global SCIP settings */
14329  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14330  * so the size of this array should be at least number of active variables
14331  * (all entries have to be initialized to 0 before) */
14332  )
14333 {
14334  SCIP_COL** lpicols;
14335  SCIP_Real* lpiray;
14336  SCIP_VAR* var;
14337  int nlpicols;
14338  int c;
14339 
14340  assert(lp != NULL);
14341  assert(set != NULL);
14342  assert(ray != NULL);
14343  assert(lp->flushed);
14344  assert(lp->solved);
14345  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14346  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14347 
14348  /* check if the LP solver is able to provide a primal unbounded ray */
14349  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14350  {
14351  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14352  return SCIP_LPERROR;
14353  }
14354 
14355  /* get temporary memory */
14356  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14357 
14358  SCIPsetDebugMsg(set, "getting primal ray values\n");
14359 
14360  /* get primal unbounded ray */
14361  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14362 
14363  lpicols = lp->lpicols;
14364  nlpicols = lp->nlpicols;
14365 
14366  /* store the ray values of active problem variables */
14367  for( c = 0; c < nlpicols; c++ )
14368  {
14369  assert(lpicols[c] != NULL);
14370 
14371  var = lpicols[c]->var;
14372  assert(var != NULL);
14373  assert(SCIPvarGetProbindex(var) != -1);
14374  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14375  }
14376 
14377  SCIPsetFreeBufferArray(set, &lpiray);
14378 
14379  return SCIP_OKAY;
14380 }
14381 
14382 /** stores the dual Farkas multipliers for infeasibility proof in rows */
14384  SCIP_LP* lp, /**< current LP data */
14385  SCIP_SET* set, /**< global SCIP settings */
14386  SCIP_STAT* stat /**< problem statistics */
14387  )
14388 {
14389  SCIP_COL** lpicols;
14390  SCIP_ROW** lpirows;
14391  SCIP_Real* dualfarkas;
14392  int nlpicols;
14393  int nlpirows;
14394  int c;
14395  int r;
14396 
14397  assert(lp != NULL);
14398  assert(lp->flushed);
14399  assert(lp->solved);
14400  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14401  assert(set != NULL);
14402  assert(stat != NULL);
14403  assert(lp->validfarkaslp <= stat->lpcount);
14404 
14405  /* check if the values are already calculated */
14406  if( lp->validfarkaslp == stat->lpcount )
14407  return SCIP_OKAY;
14408  lp->validfarkaslp = stat->lpcount;
14409 
14410  /* get temporary memory */
14411  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14412 
14413  /* get dual Farkas infeasibility proof */
14414  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14415 
14416  lpicols = lp->lpicols;
14417  lpirows = lp->lpirows;
14418  nlpicols = lp->nlpicols;
14419  nlpirows = lp->nlpirows;
14420 
14421  /* store infeasibility proof in rows */
14422  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14423  for( r = 0; r < nlpirows; ++r )
14424  {
14425  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14426  lpirows[r]->dualfarkas = dualfarkas[r];
14427  lpirows[r]->dualsol = SCIP_INVALID;
14428  lpirows[r]->activity = 0.0;
14429  lpirows[r]->validactivitylp = -1L;
14430  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14431  }
14432 
14433  /* set columns as invalid */
14434  for( c = 0; c < nlpicols; ++c )
14435  {
14436  lpicols[c]->primsol = SCIP_INVALID;
14437  lpicols[c]->redcost = SCIP_INVALID;
14438  lpicols[c]->validredcostlp = -1L;
14439  lpicols[c]->validfarkaslp = -1L;
14440  }
14441 
14442  /* free temporary memory */
14443  SCIPsetFreeBufferArray(set, &dualfarkas);
14444 
14445  return SCIP_OKAY;
14446 }
14447 
14448 /** get number of iterations used in last LP solve */
14450  SCIP_LP* lp, /**< current LP data */
14451  int* iterations /**< pointer to store the iteration count */
14452  )
14453 {
14454  assert(lp != NULL);
14455 
14456  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14457 
14458  return SCIP_OKAY;
14459 }
14460 
14461 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14462  * resets age of non-zero columns and sharp rows
14463  */
14465  SCIP_LP* lp, /**< current LP data */
14466  SCIP_STAT* stat /**< problem statistics */
14467  )
14468 {
14469  SCIP_COL** lpicols;
14470  SCIP_ROW** lpirows;
14471  int nlpicols;
14472  int nlpirows;
14473  int c;
14474  int r;
14475 
14476  assert(lp != NULL);
14477  assert(lp->flushed);
14478  assert(lp->solved);
14479  assert(lp->nlpicols == lp->ncols);
14480  assert(lp->nlpirows == lp->nrows);
14481  assert(stat != NULL);
14482  assert(lp->validsollp == stat->lpcount);
14483 
14484  SCIPdebugMessage("updating LP ages\n");
14485 
14486  lpicols = lp->lpicols;
14487  lpirows = lp->lpirows;
14488  nlpicols = lp->nlpicols;
14489  nlpirows = lp->nlpirows;
14490 
14491  for( c = 0; c < nlpicols; ++c )
14492  {
14493  assert(lpicols[c] == lp->cols[c]);
14494  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14495  lpicols[c]->age++;
14496  else
14497  lpicols[c]->age = 0;
14498  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14499  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14500  }
14501 
14502  for( r = 0; r < nlpirows; ++r )
14503  {
14504  lpirows[r]->nlpsaftercreation++;
14505  assert(lpirows[r] == lp->rows[r]);
14506 
14507  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14508  {
14509  lpirows[r]->age++;
14510  }
14511  else
14512  {
14513  lpirows[r]->activeinlpcounter++;
14514  lpirows[r]->age = 0;
14515  }
14516  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14517  }
14518 
14519  return SCIP_OKAY;
14520 }
14521 
14522 /* deletes the marked columns from the LP and the LP interface */
14523 static
14525  SCIP_LP* lp, /**< current LP data */
14526  SCIP_SET* set, /**< global SCIP settings */
14527  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
14528  )
14529 {
14530  SCIP_COL* col;
14531  int ncols;
14532  int c;
14533 
14534  assert(lp != NULL);
14535  assert(lp->flushed);
14536  assert(lp->ncols == lp->nlpicols);
14537  assert(!lp->diving);
14538  assert(coldstat != NULL);
14539  assert(lp->nlazycols <= lp->ncols);
14540 
14541  ncols = lp->ncols;
14542 
14543  /* delete columns in LP solver */
14544  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
14545 
14546  /* update LP data respectively */
14547  for( c = 0; c < ncols; ++c )
14548  {
14549  col = lp->cols[c];
14550  assert(col != NULL);
14551  assert(col == lp->lpicols[c]);
14552  assert(coldstat[c] <= c);
14553  col->lppos = coldstat[c];
14554  if( coldstat[c] == -1 )
14555  {
14556  assert(col->removable);
14557 
14558  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
14559  * function vector norms
14560  */
14561  markColDeleted(col);
14562  colUpdateDelLP(col, set);
14563  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
14564  col->lpdepth = -1;
14565 
14566  lp->cols[c] = NULL;
14567  lp->lpicols[c] = NULL;
14568  lp->ncols--;
14569  lp->nremovablecols--;
14570  lp->nlpicols--;
14571  }
14572  else if( coldstat[c] < c )
14573  {
14574  assert(lp->cols[coldstat[c]] == NULL);
14575  assert(lp->lpicols[coldstat[c]] == NULL);
14576  lp->cols[coldstat[c]] = col;
14577  lp->lpicols[coldstat[c]] = col;
14578  lp->cols[coldstat[c]]->lppos = coldstat[c];
14579  lp->cols[coldstat[c]]->lpipos = coldstat[c];
14580  lp->cols[c] = NULL;
14581  lp->lpicols[c] = NULL;
14582  }
14583  }
14584 
14585  /* remove columns which are deleted from the lazy column array */
14586  c = 0;
14587  while( c < lp->nlazycols )
14588  {
14589  if( lp->lazycols[c]->lpipos < 0 )
14590  {
14591  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
14592  lp->nlazycols--;
14593  }
14594  else
14595  c++;
14596  }
14597 
14598  /* mark LP to be unsolved */
14599  if( lp->ncols < ncols )
14600  {
14601  assert(lp->ncols == lp->nlpicols);
14602  assert(lp->nchgcols == 0);
14603  assert(lp->flushed);
14604 
14605  lp->lpifirstchgcol = lp->nlpicols;
14606 
14607  /* mark the current solution invalid */
14608  lp->solved = FALSE;
14609  lp->primalfeasible = FALSE;
14610  lp->primalchecked = FALSE;
14611  lp->lpobjval = SCIP_INVALID;
14613  }
14614 
14615  checkLazyColArray(lp, set);
14616  checkLinks(lp);
14617 
14618  return SCIP_OKAY;
14619 }
14620 
14621 /* deletes the marked rows from the LP and the LP interface */
14622 static
14624  SCIP_LP* lp, /**< current LP data */
14625  BMS_BLKMEM* blkmem, /**< block memory buffers */
14626  SCIP_SET* set, /**< global SCIP settings */
14627  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14628  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14629  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
14630  )
14631 {
14632  SCIP_ROW* row;
14633  int nrows;
14634  int r;
14635 
14636  assert(lp != NULL);
14637  assert(lp->flushed);
14638  assert(lp->nrows == lp->nlpirows);
14639  assert(!lp->diving);
14640  assert(rowdstat != NULL);
14641 
14642  nrows = lp->nrows;
14643 
14644  /* delete rows in LP solver */
14645  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
14646 
14647  /* update LP data respectively */
14648  for( r = 0; r < nrows; ++r )
14649  {
14650  row = lp->rows[r];
14651  assert(row == lp->lpirows[r]);
14652  assert(rowdstat[r] <= r);
14653  assert(row != NULL);
14654  row->lppos = rowdstat[r];
14655  if( rowdstat[r] == -1 )
14656  {
14657  if( row->removable )
14658  lp->nremovablerows--;
14659 
14660  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
14661  markRowDeleted(row);
14662  rowUpdateDelLP(row);
14663  row->lpdepth = -1;
14664 
14665  /* check, if row deletion events are tracked
14666  * if so, issue ROWDELETEDLP event
14667  */
14668  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
14669  {
14670  SCIP_EVENT* event;
14671 
14672  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
14673  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
14674  }
14675 
14676  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
14677  SCIProwUnlock(lp->rows[r]);
14678  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
14679  assert(lp->lpirows[r] == NULL);
14680  assert(lp->rows[r] == NULL);
14681  lp->nrows--;
14682  lp->nlpirows--;
14683  }
14684  else if( rowdstat[r] < r )
14685  {
14686  assert(lp->rows[rowdstat[r]] == NULL);
14687  assert(lp->lpirows[rowdstat[r]] == NULL);
14688  lp->rows[rowdstat[r]] = row;
14689  lp->lpirows[rowdstat[r]] = row;
14690  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
14691  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
14692  lp->rows[r] = NULL;
14693  lp->lpirows[r] = NULL;
14694  }
14695  }
14696 
14697  /* mark LP to be unsolved */
14698  if( lp->nrows < nrows )
14699  {
14700  assert(lp->nrows == lp->nlpirows);
14701  assert(lp->nchgrows == 0);
14702  assert(lp->flushed);
14703 
14704  lp->lpifirstchgrow = lp->nlpirows;
14705 
14706  /* mark the current solution invalid */
14707  lp->solved = FALSE;
14708  lp->dualfeasible = FALSE;
14709  lp->dualchecked = FALSE;
14710  lp->lpobjval = SCIP_INVALID;
14712  }
14713 
14714  checkLinks(lp);
14715 
14716  return SCIP_OKAY;
14717 }
14718 
14719 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
14720 static
14722  SCIP_LP* lp, /**< current LP data */
14723  SCIP_SET* set, /**< global SCIP settings */
14724  SCIP_STAT* stat, /**< problem statistics */
14725  int firstcol /**< first column to check for clean up */
14726  )
14727 {
14728  SCIP_COL** cols;
14729 #ifndef NDEBUG
14730  SCIP_COL** lpicols;
14731 #endif
14732  int* coldstat;
14733  int ncols;
14734  int ndelcols;
14735  int c;
14736 
14737  assert(lp != NULL);
14738  assert(lp->flushed);
14739  assert(lp->ncols == lp->nlpicols);
14740  assert(lp->nremovablecols <= lp->ncols);
14741  assert(!lp->diving);
14742  assert(set != NULL);
14743  assert(stat != NULL);
14744 
14745  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
14746  return SCIP_OKAY;
14747 
14748  ncols = lp->ncols;
14749  cols = lp->cols;
14750 #ifndef NDEBUG
14751  lpicols = lp->lpicols;
14752 #endif
14753 
14754  /* get temporary memory */
14755  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14756 
14757  /* mark obsolete columns to be deleted */
14758  ndelcols = 0;
14759  BMSclearMemoryArray(coldstat, ncols);
14760  for( c = firstcol; c < ncols; ++c )
14761  {
14762  assert(cols[c] == lpicols[c]);
14763  assert(cols[c]->lppos == c);
14764  assert(cols[c]->lpipos == c);
14765  if( cols[c]->removable
14766  && 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 */
14767  && cols[c]->age > set->lp_colagelimit
14769  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14770  {
14771  assert(cols[c]->primsol == 0.0);
14772  coldstat[c] = 1;
14773  ndelcols++;
14774  cols[c]->obsoletenode = stat->nnodes;
14775  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
14776  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
14777  }
14778  }
14779 
14780  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
14781 
14782  /* delete the marked columns in the LP solver interface, update the LP respectively */
14783  if( ndelcols > 0 )
14784  {
14785  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14786  }
14787  assert(lp->ncols == ncols - ndelcols);
14788 
14789  /* release temporary memory */
14790  SCIPsetFreeBufferArray(set, &coldstat);
14791 
14792  return SCIP_OKAY;
14793 }
14794 
14795 /** removes all basic rows, that are too old, beginning with the given firstrow */
14796 static
14798  SCIP_LP* lp, /**< current LP data */
14799  BMS_BLKMEM* blkmem, /**< block memory buffers */
14800  SCIP_SET* set, /**< global SCIP settings */
14801  SCIP_STAT* stat, /**< problem statistics */
14802  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14803  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14804  int firstrow /**< first row to check for clean up */
14805  )
14806 {
14807  SCIP_ROW** rows;
14808 #ifndef NDEBUG
14809  SCIP_ROW** lpirows;
14810 #endif
14811  int* rowdstat;
14812  int nrows;
14813  int ndelrows;
14814  int r;
14815 
14816  assert(lp != NULL);
14817  assert(lp->flushed);
14818  assert(lp->nrows == lp->nlpirows);
14819  assert(lp->nremovablerows <= lp->nrows);
14820  assert(!lp->diving);
14821  assert(set != NULL);
14822  assert(stat != NULL);
14823 
14824  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
14825  return SCIP_OKAY;
14826 
14827  nrows = lp->nrows;
14828  rows = lp->rows;
14829 #ifndef NDEBUG
14830  lpirows = lp->lpirows;
14831 #endif
14832 
14833  /* get temporary memory */
14834  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14835 
14836  /* mark obsolete rows to be deleted */
14837  ndelrows = 0;
14838  BMSclearMemoryArray(rowdstat, nrows);
14839  for( r = firstrow; r < nrows; ++r )
14840  {
14841  assert(rows[r] == lpirows[r]);
14842  assert(rows[r]->lppos == r);
14843  assert(rows[r]->lpipos == r);
14844  if( rows[r]->removable
14845  && 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 */
14846  && rows[r]->age > set->lp_rowagelimit
14848  {
14849  rowdstat[r] = 1;
14850  ndelrows++;
14851  rows[r]->obsoletenode = stat->nnodes;
14852  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
14853  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
14854  }
14855  }
14856 
14857  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
14858 
14859  /* delete the marked rows in the LP solver interface, update the LP respectively */
14860  if( ndelrows > 0 )
14861  {
14862  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14863  }
14864  assert(lp->nrows == nrows - ndelrows);
14865 
14866  /* release temporary memory */
14867  SCIPsetFreeBufferArray(set, &rowdstat);
14868 
14869  return SCIP_OKAY;
14870 }
14871 
14872 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
14874  SCIP_LP* lp, /**< current LP data */
14875  BMS_BLKMEM* blkmem, /**< block memory buffers */
14876  SCIP_SET* set, /**< global SCIP settings */
14877  SCIP_STAT* stat, /**< problem statistics */
14878  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14879  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14880  )
14881 {
14882  assert(lp != NULL);
14883  assert(lp->solved);
14884  assert(!lp->diving);
14886  assert(set != NULL);
14887 
14888  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
14889  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
14890 
14891  if( lp->firstnewcol < lp->ncols )
14892  {
14893  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
14894  }
14895  if( lp->firstnewrow < lp->nrows )
14896  {
14897  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
14898  }
14899 
14900  return SCIP_OKAY;
14901 }
14902 
14903 /** removes all non-basic columns and basic rows in whole LP, that are too old */
14905  SCIP_LP* lp, /**< current LP data */
14906  BMS_BLKMEM* blkmem, /**< block memory buffers */
14907  SCIP_SET* set, /**< global SCIP settings */
14908  SCIP_STAT* stat, /**< problem statistics */
14909  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14910  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14911  )
14912 {
14913  assert(lp != NULL);
14914  assert(lp->solved);
14915  assert(!lp->diving);
14917  assert(set != NULL);
14918 
14919  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
14920 
14921  if( 0 < lp->ncols )
14922  {
14923  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
14924  }
14925  if( 0 < lp->nrows )
14926  {
14927  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
14928  }
14929 
14930  return SCIP_OKAY;
14931 }
14932 
14933 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
14934 static
14936  SCIP_LP* lp, /**< current LP data */
14937  SCIP_SET* set, /**< global SCIP settings */
14938  SCIP_STAT* stat, /**< problem statistics */
14939  int firstcol /**< first column to check for clean up */
14940  )
14941 {
14942  SCIP_COL** cols;
14943  SCIP_COL** lpicols;
14944  int* coldstat;
14945  int ncols;
14946  int ndelcols;
14947  int c;
14948 
14949  assert(lp != NULL);
14950  assert(lp->flushed);
14951  assert(lp->ncols == lp->nlpicols);
14952  assert(!lp->diving);
14953  assert(stat != NULL);
14954  assert(lp->validsollp == stat->lpcount);
14955  assert(0 <= firstcol && firstcol < lp->ncols);
14956 
14957  if( lp->nremovablecols == 0 || !lp->solisbasic )
14958  return SCIP_OKAY;
14959 
14960  ncols = lp->ncols;
14961  cols = lp->cols;
14962  lpicols = lp->lpicols;
14963 
14964  /* get temporary memory */
14965  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14966 
14967  /* mark unused columns to be deleted */
14968  ndelcols = 0;
14969  BMSclearMemoryArray(coldstat, ncols);
14970  for( c = firstcol; c < ncols; ++c )
14971  {
14972  assert(cols[c] == lpicols[c]);
14973  assert(cols[c]->lppos == c);
14974  assert(cols[c]->lpipos == c);
14975  if( lpicols[c]->removable
14976  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
14977  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
14978  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14979  {
14980  coldstat[c] = 1;
14981  ndelcols++;
14982  }
14983  }
14984 
14985  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
14986 
14987  /* delete the marked columns in the LP solver interface, update the LP respectively */
14988  if( ndelcols > 0 )
14989  {
14990  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14991  }
14992  assert(lp->ncols == ncols - ndelcols);
14993 
14994  /* release temporary memory */
14995  SCIPsetFreeBufferArray(set, &coldstat);
14996 
14997  return SCIP_OKAY;
14998 }
14999 
15000 /** removes all basic rows beginning with the given firstrow */
15001 static
15003  SCIP_LP* lp, /**< current LP data */
15004  BMS_BLKMEM* blkmem, /**< block memory buffers */
15005  SCIP_SET* set, /**< global SCIP settings */
15006  SCIP_STAT* stat, /**< problem statistics */
15007  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15008  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15009  int firstrow /**< first row to check for clean up */
15010  )
15011 {
15012 #ifndef NDEBUG
15013  SCIP_ROW** rows;
15014 #endif
15015  SCIP_ROW** lpirows;
15016  int* rowdstat;
15017  int nrows;
15018  int ndelrows;
15019  int r;
15020 
15021  assert(lp != NULL);
15022  assert(lp->flushed);
15023  assert(lp->ncols == lp->nlpicols);
15024  assert(lp->nrows == lp->nlpirows);
15025  assert(!lp->diving);
15026  assert(stat != NULL);
15027  assert(lp->validsollp == stat->lpcount);
15028  assert(0 <= firstrow && firstrow < lp->nrows);
15029 
15030  if( lp->nremovablerows == 0 || !lp->solisbasic )
15031  return SCIP_OKAY;
15032 
15033 #ifndef NDEBUG
15034  rows = lp->rows;
15035 #endif
15036  nrows = lp->nrows;
15037  lpirows = lp->lpirows;
15038 
15039  /* get temporary memory */
15040  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15041 
15042  /* mark unused rows to be deleted */
15043  ndelrows = 0;
15044  BMSclearMemoryArray(rowdstat, nrows);
15045  for( r = firstrow; r < nrows; ++r )
15046  {
15047  assert(rows[r] == lpirows[r]);
15048  assert(rows[r]->lppos == r);
15049  assert(rows[r]->lpipos == r);
15050  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15051  {
15052  rowdstat[r] = 1;
15053  ndelrows++;
15054  }
15055  }
15056 
15057  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15058 
15059  /* delete the marked rows in the LP solver interface, update the LP respectively */
15060  if( ndelrows > 0 )
15061  {
15062  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15063  }
15064  assert(lp->nrows == nrows - ndelrows);
15065 
15066  /* release temporary memory */
15067  SCIPsetFreeBufferArray(set, &rowdstat);
15068 
15069  return SCIP_OKAY;
15070 }
15071 
15072 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15074  SCIP_LP* lp, /**< current LP data */
15075  BMS_BLKMEM* blkmem, /**< block memory buffers */
15076  SCIP_SET* set, /**< global SCIP settings */
15077  SCIP_STAT* stat, /**< problem statistics */
15078  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15079  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15080  SCIP_Bool root /**< are we at the root node? */
15081  )
15082 {
15083  SCIP_Bool cleanupcols;
15084  SCIP_Bool cleanuprows;
15085 
15086  assert(lp != NULL);
15087  assert(lp->solved);
15088  assert(!lp->diving);
15090  assert(set != NULL);
15091 
15092  /* check, if we want to clean up the columns and rows */
15093  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15094  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15095 
15096  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15097  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15098 
15099  if( cleanupcols && lp->firstnewcol < lp->ncols )
15100  {
15101  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15102  }
15103  if( cleanuprows && lp->firstnewrow < lp->nrows )
15104  {
15105  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15106  }
15107 
15108  return SCIP_OKAY;
15109 }
15110 
15111 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15113  SCIP_LP* lp, /**< current LP data */
15114  BMS_BLKMEM* blkmem, /**< block memory buffers */
15115  SCIP_SET* set, /**< global SCIP settings */
15116  SCIP_STAT* stat, /**< problem statistics */
15117  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15118  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15119  SCIP_Bool root /**< are we at the root node? */
15120  )
15121 {
15122  SCIP_Bool cleanupcols;
15123  SCIP_Bool cleanuprows;
15124 
15125  assert(lp != NULL);
15126  assert(lp->solved);
15127  assert(!lp->diving);
15129  assert(set != NULL);
15130 
15131  /* check, if we want to clean up the columns and rows */
15132  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15133  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15134 
15135  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15136  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15137 
15138  if( cleanupcols && 0 < lp->ncols )
15139  {
15140  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15141  }
15142  if( cleanuprows && 0 < lp->nrows )
15143  {
15144  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15145  }
15146 
15147  return SCIP_OKAY;
15148 }
15149 
15150 /** removes all redundant rows that were added at the current node */
15152  SCIP_LP* lp, /**< current LP data */
15153  BMS_BLKMEM* blkmem, /**< block memory buffers */
15154  SCIP_SET* set, /**< global SCIP settings */
15155  SCIP_STAT* stat, /**< problem statistics */
15156  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15157  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15158  )
15159 {
15160 #ifndef NDEBUG
15161  SCIP_ROW** rows;
15162 #endif
15163  SCIP_ROW** lpirows;
15164  int* rowdstat;
15165  int nrows;
15166  int ndelrows;
15167  int r;
15168 
15169  assert(lp != NULL);
15170  assert(lp->flushed);
15171  assert(lp->ncols == lp->nlpicols);
15172  assert(lp->nrows == lp->nlpirows);
15173  assert(!lp->diving);
15174  assert(stat != NULL);
15175  assert(lp->validsollp == stat->lpcount);
15176  assert(lp->firstnewrow <= lp->nrows);
15177 
15178  if( lp->firstnewrow == lp->nrows )
15179  return SCIP_OKAY;
15180 
15181 #ifndef NDEBUG
15182  rows = lp->rows;
15183 #endif
15184  nrows = lp->nrows;
15185  lpirows = lp->lpirows;
15186 
15187  /* get temporary memory */
15188  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15189 
15190  /* mark redundant rows to be deleted (only delete basic rows!) */
15191  ndelrows = 0;
15192  BMSclearMemoryArray(rowdstat, nrows);
15193  for( r = lp->firstnewrow; r < nrows; ++r )
15194  {
15195  assert(rows[r] == lpirows[r]);
15196  assert(rows[r]->lppos == r);
15197  assert(rows[r]->lpipos == r);
15198  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15199  && SCIProwIsRedundant(lpirows[r], set, stat) )
15200  {
15201  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15202  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15203  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15204  rowdstat[r] = 1;
15205  ndelrows++;
15206  }
15207  }
15208 
15209  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15210 
15211  /* delete the marked rows in the LP solver interface, update the LP respectively */
15212  if( ndelrows > 0 )
15213  {
15214  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15215  }
15216  assert(lp->nrows == nrows - ndelrows);
15217 
15218  /* release temporary memory */
15219  SCIPsetFreeBufferArray(set, &rowdstat);
15220 
15221  return SCIP_OKAY;
15222 }
15223 
15224 /** initiates LP diving */
15226  SCIP_LP* lp, /**< current LP data */
15227  BMS_BLKMEM* blkmem, /**< block memory */
15228  SCIP_SET* set, /**< global SCIP settings */
15229  SCIP_STAT* stat /**< problem statistics */
15230  )
15231 {
15232  int c;
15233  int r;
15234 
15235  assert(lp != NULL);
15236  assert(lp->flushed || !lp->solved);
15237  assert(!lp->diving);
15238  assert(!lp->probing);
15239  assert(lp->divelpistate == NULL);
15240  assert(lp->divelpwasprimfeas);
15241  assert(lp->divelpwasdualfeas);
15242  assert(lp->validsollp <= stat->lpcount);
15243  assert(blkmem != NULL);
15244  assert(set != NULL);
15245  assert(lp->ndivechgsides == 0);
15246 
15247  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15248  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15249 
15250 #ifndef NDEBUG
15251  for( c = 0; c < lp->ncols; ++c )
15252  {
15253  assert(lp->cols[c] != NULL);
15254  assert(lp->cols[c]->var != NULL);
15255  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15256  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15257  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15258  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15259  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15260  }
15261 #endif
15262 
15263  /* save current LPI state (basis information) */
15264  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15266  lp->divelpwasdualfeas = lp->dualfeasible;
15269 
15270  /* save current LP values dependent on the solution */
15271  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15272  assert(lp->storedsolvals != NULL);
15273  if( !set->lp_resolverestore && lp->solved )
15274  {
15275  SCIP_Bool store = TRUE;
15276 
15277  switch ( lp->lpsolstat )
15278  {
15280  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15281  assert(lp->validsollp == stat->lpcount);
15282  break;
15284  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15285  assert(lp->validsollp == stat->lpcount);
15286  break;
15290  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15291  assert(lp->validsollp == stat->lpcount);
15292  break;
15294  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
15295  break;
15297  case SCIP_LPSOLSTAT_ERROR:
15298  default:
15299  store = FALSE;
15300  }
15301 
15302  if ( store )
15303  {
15304  for( c = 0; c < lp->ncols; ++c )
15305  {
15306  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15307  }
15308  for( r = 0; r < lp->nrows; ++r )
15309  {
15311  }
15312  }
15313  }
15314 
15315  /* store LPI iteration limit */
15317 
15318  /* remember the number of domain changes */
15319  lp->divenolddomchgs = stat->domchgcount;
15320 
15321  /* store current number of rows */
15322  lp->ndivingrows = lp->nrows;
15323 
15324  /* switch to diving mode */
15325  lp->diving = TRUE;
15326 
15327  return SCIP_OKAY;
15328 }
15329 
15330 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15332  SCIP_LP* lp, /**< current LP data */
15333  BMS_BLKMEM* blkmem, /**< block memory */
15334  SCIP_SET* set, /**< global SCIP settings */
15335  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15336  SCIP_STAT* stat, /**< problem statistics */
15337  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15338  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15339  SCIP_PROB* prob, /**< problem data */
15340  SCIP_VAR** vars, /**< array with all active variables */
15341  int nvars /**< number of active variables */
15342  )
15343 {
15344  SCIP_VAR* var;
15345  int v;
15346 
15347  assert(lp != NULL);
15348  assert(lp->diving);
15349  assert(blkmem != NULL);
15350  assert(nvars == 0 || vars != NULL);
15351 
15352  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15353 
15354  /* reset all columns' objective values and bounds to its original values */
15355  for( v = 0; v < nvars; ++v )
15356  {
15357  var = vars[v];
15358  assert(var != NULL);
15360  {
15361  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15362  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15363  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15364  }
15365  }
15366 
15367  /* remove rows which were added in diving mode */
15368  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15369 
15370  /* undo changes to left hand sides and right hand sides */
15371  while( lp->ndivechgsides > 0 )
15372  {
15373  SCIP_Real oldside;
15374  SCIP_SIDETYPE sidetype;
15375  SCIP_ROW* row;
15376 
15377  lp->ndivechgsides--;
15378  oldside = lp->divechgsides[lp->ndivechgsides];
15379  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15380  row = lp->divechgrows[lp->ndivechgsides];
15381 
15382  if( sidetype == SCIP_SIDETYPE_LEFT )
15383  {
15384  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15385  }
15386  else
15387  {
15388  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15389  }
15390  }
15391 
15392  /* restore LPI iteration limit */
15394 
15395  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15396  * happens
15397  */
15398  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15400  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15401  lp->divelpwasprimfeas = TRUE;
15402  lp->divelpwasdualfeas = TRUE;
15403  lp->divelpwasprimchecked = TRUE;
15404  lp->divelpwasdualchecked = TRUE;
15405  assert(lp->divelpistate == NULL);
15406 
15407  /* switch to standard (non-diving) mode */
15408  lp->diving = FALSE;
15409  lp->divingobjchg = FALSE;
15410 
15411  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15412  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15413  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15414  * the parameter resolverestore to TRUE
15415  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15416  */
15417  assert(lp->storedsolvals != NULL);
15418  if( lp->storedsolvals->lpissolved
15419  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
15420  {
15421  SCIP_Bool lperror;
15422 
15423  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15424  if( lperror )
15425  {
15426  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
15427  lp->resolvelperror = TRUE;
15428  }
15433  {
15434  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15435  "LP was not resolved to a sufficient status after diving\n");
15436  lp->resolvelperror = TRUE;
15437  }
15438  }
15439  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15440  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15441  * re-solve as above can lead to a different LP status
15442  */
15443  else
15444  {
15445  int c;
15446  int r;
15447 
15448  /* if there are lazy bounds, remove them from the LP */
15449  if( lp->nlazycols > 0 )
15450  {
15451  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15452  * first resolve LP?
15453  */
15454  SCIP_CALL( updateLazyBounds(lp, set) );
15455  assert(lp->diving == lp->divinglazyapplied);
15456 
15457  /* flush changes to the LP solver */
15458  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15459  }
15460 
15461  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15462  SCIPstatIncrement(stat, set, lpcount);
15463 
15464  /* restore LP solution values in lp data, columns and rows */
15465  if( lp->storedsolvals->lpissolved &&
15472  )
15473  {
15474  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15475 
15476  for( c = 0; c < lp->ncols; ++c )
15477  {
15478  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15479  }
15480  for( r = 0; r < lp->nrows; ++r )
15481  {
15482  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15483  }
15484  }
15485  else
15486  {
15487  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15488  }
15489  }
15490 
15491 #ifndef NDEBUG
15492  {
15493  int c;
15494  for( c = 0; c < lp->ncols; ++c )
15495  {
15496  assert(lp->cols[c] != NULL);
15497  assert(lp->cols[c]->var != NULL);
15498  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15499  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15500  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15501  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15502  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15503  }
15504  }
15505 #endif
15506 
15507  return SCIP_OKAY;
15508 }
15509 
15510 #define DIVESTACKGROWFACT 1.5
15511 
15512 /** records a current row side such that any change will be undone after diving */
15514  SCIP_LP* lp, /**< LP data object */
15515  SCIP_ROW* row, /**< row affected by the change */
15516  SCIP_SIDETYPE sidetype /**< side type */
15517  )
15518 {
15519  assert(lp != NULL);
15520  assert(row != NULL);
15521 
15522  if( lp->ndivechgsides == lp->divechgsidessize )
15523  {
15525  }
15526  assert(lp->ndivechgsides < lp->divechgsidessize);
15527 
15528  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
15529  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
15530  lp->divechgrows[lp->ndivechgsides] = row;
15531  lp->ndivechgsides++;
15532 
15533  return SCIP_OKAY;
15534 }
15535 
15536 /** informs the LP that probing mode was initiated */
15538  SCIP_LP* lp /**< current LP data */
15539  )
15540 {
15541  assert(lp != NULL);
15542  assert(!lp->probing);
15543  assert(!lp->strongbranching);
15544  assert(!lp->strongbranchprobing);
15545 
15546  lp->probing = TRUE;
15547 
15548  return SCIP_OKAY;
15549 }
15550 
15551 /** informs the LP that probing mode was finished */
15553  SCIP_LP* lp /**< current LP data */
15554  )
15555 {
15556  assert(lp != NULL);
15557  assert(lp->probing);
15558  assert(!lp->strongbranching);
15559  assert(!lp->strongbranchprobing);
15560 
15561  lp->probing = FALSE;
15562 
15563  return SCIP_OKAY;
15564 }
15565 
15566 /** informs the LP that the probing mode is now used for strongbranching */
15568  SCIP_LP* lp /**< current LP data */
15569  )
15570 {
15571  assert(lp != NULL);
15572  assert(lp->probing);
15573  assert(!lp->strongbranching);
15574  assert(!lp->strongbranchprobing);
15575 
15576  lp->strongbranchprobing = TRUE;
15577 }
15578 
15579 /** informs the LP that the probing mode is not used for strongbranching anymore */
15581  SCIP_LP* lp /**< current LP data */
15582  )
15583 {
15584  assert(lp != NULL);
15585  assert(lp->probing);
15586  assert(!lp->strongbranching);
15587  assert(lp->strongbranchprobing);
15588 
15589  lp->strongbranchprobing = FALSE;
15590 }
15591 
15592 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
15593  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
15594  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
15595  * we have only left hand sides):
15596  * min{cx | b <= Ax, lb <= x <= ub}
15597  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
15598  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
15599  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
15600  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
15601  */
15602 static
15604  SCIP_LP* lp, /**< current LP data */
15605  SCIP_SET* set, /**< global SCIP settings */
15606  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
15607  SCIP_Real* bound /**< result of interval arithmetic minimization */
15608  )
15609 {
15610  SCIP_INTERVAL* yinter;
15611  SCIP_INTERVAL b;
15612  SCIP_INTERVAL ytb;
15613  SCIP_INTERVAL prod;
15614  SCIP_INTERVAL diff;
15615  SCIP_INTERVAL x;
15616  SCIP_INTERVAL minprod;
15617  SCIP_INTERVAL a;
15618  SCIP_ROW* row;
15619  SCIP_COL* col;
15620  SCIP_Real y;
15621  SCIP_Real c;
15622  int i;
15623  int j;
15624 
15625  assert(lp != NULL);
15626  assert(lp->solved);
15627  assert(set != NULL);
15628  assert(bound != NULL);
15629 
15630  /* allocate buffer for storing y in interval arithmetic */
15631  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
15632 
15633  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
15634  SCIPintervalSet(&ytb, 0.0);
15635  for( j = 0; j < lp->nrows; ++j )
15636  {
15637  row = lp->rows[j];
15638  assert(row != NULL);
15639 
15640  y = (usefarkas ? row->dualfarkas : row->dualsol);
15641 
15642  if( SCIPsetIsFeasPositive(set, y) )
15643  {
15644  SCIPintervalSet(&yinter[j], y);
15645  SCIPintervalSet(&b, row->lhs - row->constant);
15646  }
15647  else if( SCIPsetIsFeasNegative(set, y) )
15648  {
15649  SCIPintervalSet(&yinter[j], y);
15650  SCIPintervalSet(&b, row->rhs - row->constant);
15651  }
15652  else
15653  {
15654  SCIPintervalSet(&yinter[j], 0.0);
15655  SCIPintervalSet(&b, 0.0);
15656  }
15657 
15658  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
15659  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
15660  }
15661 
15662  /* calculate min{(c^T - y^TA)x} */
15663  SCIPintervalSet(&minprod, 0.0);
15664  for( j = 0; j < lp->ncols; ++j )
15665  {
15666  col = lp->cols[j];
15667  assert(col != NULL);
15668  assert(col->nunlinked == 0);
15669 
15671 
15672  c = usefarkas ? 0.0 : col->obj;
15673  SCIPintervalSet(&diff, c);
15674 
15675  for( i = 0; i < col->nlprows; ++i )
15676  {
15677  assert(col->rows[i] != NULL);
15678  assert(col->rows[i]->lppos >= 0);
15679  assert(col->linkpos[i] >= 0);
15680  SCIPintervalSet(&a, col->vals[i]);
15681  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
15682  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
15683  }
15684 
15685 #ifndef NDEBUG
15686  for( i = col->nlprows; i < col->len; ++i )
15687  {
15688  assert(col->rows[i] != NULL);
15689  assert(col->rows[i]->lppos == -1);
15690  assert(col->rows[i]->dualsol == 0.0);
15691  assert(col->rows[i]->dualfarkas == 0.0);
15692  assert(col->linkpos[i] >= 0);
15693  }
15694 #endif
15695 
15696  SCIPintervalSetBounds(&x, col->lb, col->ub);
15697  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
15698  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
15699  }
15700 
15701  /* add y^Tb */
15702  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
15703 
15704  /* free buffer for storing y in interval arithmetic */
15705  SCIPsetFreeBufferArray(set, &yinter);
15706 
15707  *bound = SCIPintervalGetInf(minprod);
15708 
15709  return SCIP_OKAY;
15710 }
15711 
15712 /** gets proven lower (dual) bound of last LP solution */
15714  SCIP_LP* lp, /**< current LP data */
15715  SCIP_SET* set, /**< global SCIP settings */
15716  SCIP_Real* bound /**< pointer to store proven dual bound */
15717  )
15718 {
15719  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
15720 
15721  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
15722 
15723  return SCIP_OKAY;
15724 }
15725 
15726 /** gets proven dual bound of last LP solution */
15728  SCIP_LP* lp, /**< current LP data */
15729  SCIP_SET* set, /**< global SCIP settings */
15730  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
15731  )
15732 {
15733  SCIP_Real bound;
15734 
15735  assert(proved != NULL);
15736 
15737  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
15738 
15739  *proved = (bound > 0.0);
15740 
15741  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
15742 
15743  return SCIP_OKAY;
15744 }
15745 
15746 
15747 
15748 /** writes LP to a file */
15750  SCIP_LP* lp, /**< current LP data */
15751  const char* fname /**< file name */
15752  )
15753 {
15754  assert(lp != NULL);
15755  assert(lp->flushed);
15756  assert(fname != NULL);
15757 
15758  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
15759 
15760  return SCIP_OKAY;
15761 }
15762 
15763 /** writes MIP relaxation of the current B&B node to a file */
15765  SCIP_LP* lp, /**< current LP data */
15766  SCIP_SET* set, /**< global SCIP settings */
15767  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15768  const char* fname, /**< file name */
15769  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
15770  * troubles with reserved symbols? */
15771  SCIP_Bool origobj, /**< should the original objective function be used? */
15772  SCIP_OBJSENSE objsense, /**< objective sense */
15773  SCIP_Real objscale, /**< objective scaling factor */
15774  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
15775  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
15776  )
15777 {
15778  FILE* file;
15779  int i;
15780  int j;
15781  char rowname[SCIP_MAXSTRLEN];
15782  SCIP_Real coeff;
15783 
15784  assert(lp != NULL);
15785  assert(lp->flushed);
15786  assert(fname != NULL);
15787 
15788  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
15789  file = fopen(fname, "w");
15790  if( file == NULL )
15791  {
15792  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
15793  SCIPprintSysError(fname);
15794  return SCIP_FILECREATEERROR;
15795  }
15796 
15797  /* print comments */
15798  if( genericnames )
15799  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
15800  else
15801  {
15802  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
15803  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
15804  }
15805 
15806  if( origobj && objoffset != 0.0 )
15807  {
15808  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
15809  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
15810  }
15811 
15812  /* print objective function */
15813  /**@note the transformed problem in SCIP is always a minimization problem */
15814  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
15815  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
15816  else
15817  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
15818 
15819  /* print objective */
15820  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
15821  j = 0;
15822  for( i = 0; i < lp->ncols; ++i )
15823  {
15824  if( lp->cols[i]->obj != 0.0 )
15825  {
15826  coeff = lp->cols[i]->obj;
15827  if( origobj )
15828  {
15829  coeff *= (SCIP_Real) objsense;
15830  coeff *= objscale;
15831  }
15832 
15833  if( genericnames )
15834  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
15835  else
15836  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
15837 
15838  ++j;
15839  if( j % 10 == 0 )
15840  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15841  }
15842  }
15843  /* add artificial variable 'objoffset' to transfer objective offset */
15844  if( origobj && objoffset != 0.0 )
15845  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
15846 
15847  /* print constraint section */
15848  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
15849  for( i = 0; i < lp->nrows; i++ )
15850  {
15851  char type = 'i';
15852 
15853  /* skip removable rows if we want to write them as lazy constraints */
15854  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
15855  continue;
15856 
15857  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15858  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15859  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15860  * type 'i' means: lhs and rhs are both infinite */
15861  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15862  type = 'r';
15863  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15864  type = 'l';
15865  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15866  type = 'e';
15867  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15868  type = 'b';
15869 
15870  /* print name of row */
15871  if( genericnames )
15872  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15873  else
15874  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15875 
15876  WRITEROW:
15877  switch( type )
15878  {
15879  case 'r':
15880  case 'l':
15881  case 'e':
15882  if( strlen(rowname) > 0 )
15883  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15884  break;
15885  case 'i':
15886  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15887  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15888  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
15889  type = 'b';
15890  /*lint -fallthrough*/
15891  case 'b':
15892  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15893  break;
15894  default:
15895  assert(type == 'B');
15896  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15897  break;
15898  }
15899 
15900  /* print coefficients and variables */
15901  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15902  {
15903  if( genericnames )
15904  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15905  else
15906  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15907 
15908  if( (j+1) % 10 == 0 )
15909  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15910  }
15911 
15912  /* print right hand side */
15913  switch( type )
15914  {
15915  case 'b':
15916  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15917  type = 'B';
15918  goto WRITEROW;
15919  case 'l':
15920  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15921  break;
15922  case 'B':
15923  case 'r':
15924  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15925  break;
15926  case 'e':
15927  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15928  break;
15929  default:
15930  SCIPerrorMessage("Undefined row type!\n");
15931  return SCIP_ERROR;
15932  }
15933  }
15934 
15935  if ( lazyconss )
15936  {
15937  /* print lazy constraint section */
15938  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
15939  for( i = 0; i < lp->nrows; i++ )
15940  {
15941  char type = 'i';
15942 
15943  /* skip non-removable rows if we want to write lazy constraints */
15944  if ( ! SCIProwIsRemovable(lp->rows[i]) )
15945  continue;
15946 
15947  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15948  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15949  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15950  * type 'i' means: lhs and rhs are both infinite */
15951  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15952  type = 'r';
15953  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15954  type = 'l';
15955  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15956  type = 'e';
15957  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15958  type = 'b';
15959 
15960  /* print name of row */
15961  if( genericnames )
15962  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15963  else
15964  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15965 
15966  WRITELAZYROW:
15967  switch( type )
15968  {
15969  case 'r':
15970  case 'l':
15971  case 'e':
15972  if( strlen(rowname) > 0 )
15973  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15974  break;
15975  case 'i':
15976  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15977  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15978  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
15979  type = 'b';
15980  /*lint -fallthrough*/
15981  case 'b':
15982  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15983  break;
15984  default:
15985  assert(type == 'B');
15986  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15987  break;
15988  }
15989 
15990  /* print coefficients and variables */
15991  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15992  {
15993  if( genericnames )
15994  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15995  else
15996  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15997 
15998  if( (j+1) % 10 == 0 )
15999  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16000  }
16001 
16002  /* print right hand side */
16003  switch( type )
16004  {
16005  case 'b':
16006  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16007  type = 'B';
16008  goto WRITELAZYROW;
16009  case 'l':
16010  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16011  break;
16012  case 'B':
16013  case 'r':
16014  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16015  break;
16016  case 'e':
16017  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16018  break;
16019  default:
16020  SCIPerrorMessage("Undefined row type!\n");
16021  return SCIP_ERROR;
16022  }
16023  }
16024  }
16025 
16026  /* print variable bounds */
16027  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16028  for( i = 0; i < lp->ncols; ++i )
16029  {
16030  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16031  {
16032  /* print lower bound as far this one is not infinity */
16033  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16034  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16035 
16036  /* print variable name */
16037  if( genericnames )
16038  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16039  else
16040  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16041 
16042  /* print upper bound as far this one is not infinity */
16043  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16044  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16045  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16046  }
16047  }
16048  if( origobj && objoffset != 0.0 )
16049  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16050 
16051  /* print integer variables */
16052  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16053  j = 0;
16054  for( i = 0; i < lp->ncols; ++i )
16055  {
16056  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16057  {
16058  /* print variable name */
16059  if( genericnames )
16060  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16061  else
16062  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16063 
16064  j++;
16065  if( j % 10 == 0 )
16066  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16067  }
16068  }
16069 
16070  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16071  fclose(file);
16072 
16073  return SCIP_OKAY;
16074 }
16075 
16076 /*
16077  * simple functions implemented as defines
16078  */
16079 
16080 /* In debug mode, the following methods are implemented as function calls to ensure
16081  * type validity.
16082  * In optimized mode, the methods are implemented as defines to improve performance.
16083  * However, we want to have them in the library anyways, so we have to undef the defines.
16084  */
16085 
16086 #undef SCIPcolGetObj
16087 #undef SCIPcolGetLb
16088 #undef SCIPcolGetUb
16089 #undef SCIPcolGetBestBound
16090 #undef SCIPcolGetPrimsol
16091 #undef SCIPcolGetMinPrimsol
16092 #undef SCIPcolGetMaxPrimsol
16093 #undef SCIPcolGetBasisStatus
16094 #undef SCIPcolGetVar
16095 #undef SCIPcolGetIndex
16096 #undef SCIPcolIsIntegral
16097 #undef SCIPcolIsRemovable
16098 #undef SCIPcolGetLPPos
16099 #undef SCIPcolGetLPDepth
16100 #undef SCIPcolIsInLP
16101 #undef SCIPcolGetNNonz
16102 #undef SCIPcolGetNLPNonz
16103 #undef SCIPcolGetRows
16104 #undef SCIPcolGetVals
16105 #undef SCIPcolGetStrongbranchNode
16106 #undef SCIPcolGetNStrongbranchs
16107 #undef SCIPboundtypeOpposite
16108 #undef SCIProwGetNNonz
16109 #undef SCIProwGetNLPNonz
16110 #undef SCIProwGetCols
16111 #undef SCIProwGetVals
16112 #undef SCIProwGetConstant
16113 #undef SCIProwGetNorm
16114 #undef SCIProwGetSumNorm
16115 #undef SCIProwGetLhs
16116 #undef SCIProwGetRhs
16117 #undef SCIProwGetDualsol
16118 #undef SCIProwGetDualfarkas
16119 #undef SCIProwGetBasisStatus
16120 #undef SCIProwGetName
16121 #undef SCIProwGetIndex
16122 #undef SCIProwGetAge
16123 #undef SCIProwGetRank
16124 #undef SCIProwIsIntegral
16125 #undef SCIProwIsLocal
16126 #undef SCIProwIsModifiable
16127 #undef SCIProwIsRemovable
16128 #undef SCIProwGetOrigintype
16129 #undef SCIProwGetOriginCons
16130 #undef SCIProwGetOriginSepa
16131 #undef SCIProwIsInGlobalCutpool
16132 #undef SCIProwGetLPPos
16133 #undef SCIProwGetLPDepth
16134 #undef SCIProwIsInLP
16135 #undef SCIProwGetActiveLPCount
16136 #undef SCIProwGetNLPsAfterCreation
16137 #undef SCIProwChgRank
16138 #undef SCIPlpGetCols
16139 #undef SCIPlpGetNCols
16140 #undef SCIPlpGetRows
16141 #undef SCIPlpGetNRows
16142 #undef SCIPlpGetNewcols
16143 #undef SCIPlpGetNNewcols
16144 #undef SCIPlpGetNewrows
16145 #undef SCIPlpGetNNewrows
16146 #undef SCIPlpGetObjNorm
16147 #undef SCIPlpGetRootObjval
16148 #undef SCIPlpGetRootColumnObjval
16149 #undef SCIPlpGetRootLooseObjval
16150 #undef SCIPlpGetLPI
16151 #undef SCIPlpSetIsRelax
16152 #undef SCIPlpIsRelax
16153 #undef SCIPlpIsSolved
16154 #undef SCIPlpIsSolBasic
16155 #undef SCIPlpDiving
16156 #undef SCIPlpDivingObjChanged
16157 #undef SCIPlpMarkDivingObjChanged
16158 #undef SCIPlpUnmarkDivingObjChanged
16159 #undef SCIPlpDivingRowsChanged
16160 
16161 /** gets objective value of column */
16163  SCIP_COL* col /**< LP column */
16164  )
16165 {
16166  assert(col != NULL);
16167 
16168  return col->obj;
16169 }
16170 
16171 /** gets lower bound of column */
16173  SCIP_COL* col /**< LP column */
16174  )
16175 {
16176  assert(col != NULL);
16177 
16178  return col->lb;
16179 }
16180 
16181 /** gets upper bound of column */
16183  SCIP_COL* col /**< LP column */
16184  )
16185 {
16186  assert(col != NULL);
16187 
16188  return col->ub;
16189 }
16190 
16191 /** gets best bound of column with respect to the objective function */
16193  SCIP_COL* col /**< LP column */
16194  )
16195 {
16196  assert(col != NULL);
16197 
16198  if( col->obj >= 0.0 )
16199  return col->lb;
16200  else
16201  return col->ub;
16202 }
16203 
16204 /** gets the primal LP solution of a column */
16206  SCIP_COL* col /**< LP column */
16207  )
16208 {
16209  assert(col != NULL);
16210 
16211  if( col->lppos >= 0 )
16212  return col->primsol;
16213  else
16214  return 0.0;
16215 }
16216 
16217 /** gets the minimal LP solution value, this column ever assumed */
16219  SCIP_COL* col /**< LP column */
16220  )
16221 {
16222  assert(col != NULL);
16223 
16224  return col->minprimsol;
16225 }
16226 
16227 /** gets the maximal LP solution value, this column ever assumed */
16229  SCIP_COL* col /**< LP column */
16230  )
16231 {
16232  assert(col != NULL);
16233 
16234  return col->maxprimsol;
16235 }
16236 
16237 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16238  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16239  */
16241  SCIP_COL* col /**< LP column */
16242  )
16243 {
16244  assert(col != NULL);
16245  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16246 
16247  return (SCIP_BASESTAT)col->basisstatus;
16248 }
16249 
16250 /** gets variable this column represents */
16252  SCIP_COL* col /**< LP column */
16253  )
16254 {
16255  assert(col != NULL);
16256 
16257  return col->var;
16258 }
16259 
16260 /** gets unique index of col */
16262  SCIP_COL* col /**< LP col */
16263  )
16264 {
16265  assert(col != NULL);
16266 
16267  return col->index;
16268 }
16269 
16270 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16272  SCIP_COL* col /**< LP column */
16273  )
16274 {
16275  assert(col != NULL);
16276  assert(SCIPvarIsIntegral(col->var) == col->integral);
16277 
16278  return col->integral;
16279 }
16280 
16281 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16283  SCIP_COL* col /**< LP column */
16284  )
16285 {
16286  assert(col != NULL);
16287 
16288  return col->removable;
16289 }
16290 
16291 /** gets position of column in current LP, or -1 if it is not in LP */
16293  SCIP_COL* col /**< LP column */
16294  )
16295 {
16296  assert(col != NULL);
16297  assert((col->lppos == -1) == (col->lpdepth == -1));
16298 
16299  return col->lppos;
16300 }
16301 
16302 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16304  SCIP_COL* col /**< LP column */
16305  )
16306 {
16307  assert(col != NULL);
16308  assert((col->lppos == -1) == (col->lpdepth == -1));
16309 
16310  return col->lpdepth;
16311 }
16312 
16313 /** returns TRUE iff column is member of current LP */
16315  SCIP_COL* col /**< LP column */
16316  )
16317 {
16318  assert(col != NULL);
16319  assert((col->lppos == -1) == (col->lpdepth == -1));
16320 
16321  return (col->lppos >= 0);
16322 }
16323 
16324 /** get number of nonzero entries in column vector */
16326  SCIP_COL* col /**< LP column */
16327  )
16328 {
16329  assert(col != NULL);
16330 
16331  return col->len;
16332 }
16333 
16334 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16335  *
16336  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16337  * 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
16338  */
16340  SCIP_COL* col /**< LP column */
16341  )
16342 {
16343  assert(col != NULL);
16344  assert(col->nunlinked == 0);
16345 
16346  return col->nlprows;
16347 }
16348 
16349 /** gets array with rows of nonzero entries */
16351  SCIP_COL* col /**< LP column */
16352  )
16353 {
16354  assert(col != NULL);
16355 
16356  return col->rows;
16357 }
16358 
16359 /** gets array with coefficients of nonzero entries */
16361  SCIP_COL* col /**< LP column */
16362  )
16363 {
16364  assert(col != NULL);
16365 
16366  return col->vals;
16367 }
16368 
16369 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16370  * given column, or -1 if strong branching was never applied to the column in current run
16371  */
16373  SCIP_COL* col /**< LP column */
16374  )
16375 {
16376  assert(col != NULL);
16377 
16378  return col->sbnode;
16379 }
16380 
16381 /** gets number of times, strong branching was applied in current run on the given column */
16383  SCIP_COL* col /**< LP column */
16384  )
16385 {
16386  assert(col != NULL);
16387 
16388  return col->nsbcalls;
16389 }
16390 
16391 /** gets opposite bound type of given bound type */
16393  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16394  )
16395 {
16396  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16397 
16399 }
16400 
16401 /** get number of nonzero entries in row vector */
16403  SCIP_ROW* row /**< LP row */
16404  )
16405 {
16406  assert(row != NULL);
16407 
16408  return row->len;
16409 }
16410 
16411 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16412  *
16413  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16414  * 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
16415  */
16417  SCIP_ROW* row /**< LP row */
16418  )
16419 {
16420  assert(row != NULL);
16421  assert(row->nunlinked == 0);
16422 
16423  return row->nlpcols;
16424 }
16425 
16426 /** gets array with columns of nonzero entries */
16428  SCIP_ROW* row /**< LP row */
16429  )
16430 {
16431  assert(row != NULL);
16432 
16433  return row->cols;
16434 }
16435 
16436 /** gets array with coefficients of nonzero entries */
16438  SCIP_ROW* row /**< LP row */
16439  )
16440 {
16441  assert(row != NULL);
16442 
16443  return row->vals;
16444 }
16445 
16446 /** gets constant shift of row */
16448  SCIP_ROW* row /**< LP row */
16449  )
16450 {
16451  assert(row != NULL);
16452 
16453  return row->constant;
16454 }
16455 
16456 /** gets Euclidean norm of row vector */
16458  SCIP_ROW* row /**< LP row */
16459  )
16460 {
16461  assert(row != NULL);
16462 
16463  checkRowSqrnorm(row);
16464 
16465  return sqrt(row->sqrnorm);
16466 }
16467 
16468 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16470  SCIP_ROW* row /**< LP row */
16471  )
16472 {
16473  assert(row != NULL);
16474 
16475  checkRowSumnorm(row);
16476 
16477  return row->sumnorm;
16478 }
16479 
16480 /** returns the left hand side of the row */
16482  SCIP_ROW* row /**< LP row */
16483  )
16484 {
16485  assert(row != NULL);
16486 
16487  return row->lhs;
16488 }
16489 
16490 /** returns the right hand side of the row */
16492  SCIP_ROW* row /**< LP row */
16493  )
16494 {
16495  assert(row != NULL);
16496 
16497  return row->rhs;
16498 }
16499 
16500 /** gets the dual LP solution of a row */
16502  SCIP_ROW* row /**< LP row */
16503  )
16504 {
16505  assert(row != NULL);
16506 
16507  if( row->lppos >= 0 )
16508  return row->dualsol;
16509  else
16510  return 0.0;
16511 }
16512 
16513 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16515  SCIP_ROW* row /**< LP row */
16516  )
16517 {
16518  assert(row != NULL);
16519 
16520  if( row->lppos >= 0 )
16521  return row->dualfarkas;
16522  else
16523  return 0.0;
16524 }
16525 
16526 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16527  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
16528  */
16530  SCIP_ROW* row /**< LP row */
16531  )
16532 {
16533  assert(row != NULL);
16534  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
16535 
16536  return (SCIP_BASESTAT)row->basisstatus;
16537 }
16538 
16539 /** returns the name of the row */
16540 const char* SCIProwGetName(
16541  SCIP_ROW* row /**< LP row */
16542  )
16543 {
16544  assert(row != NULL);
16545 
16546  return row->name;
16547 }
16548 
16549 /** gets unique index of row */
16551  SCIP_ROW* row /**< LP row */
16552  )
16553 {
16554  assert(row != NULL);
16555 
16556  return row->index;
16557 }
16558 
16559 /** gets age of row */
16561  SCIP_ROW* row /**< LP row */
16562  )
16563 {
16564  assert(row != NULL);
16565 
16566  return row->age;
16567 }
16568 
16569 /** gets rank of row */
16571  SCIP_ROW* row /**< LP row */
16572  )
16573 {
16574  assert(row != NULL);
16575 
16576  return row->rank;
16577 }
16578 
16579 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
16581  SCIP_ROW* row /**< LP row */
16582  )
16583 {
16584  assert(row != NULL);
16585 
16586  return row->integral;
16587 }
16588 
16589 /** returns TRUE iff row is only valid locally */
16591  SCIP_ROW* row /**< LP row */
16592  )
16593 {
16594  assert(row != NULL);
16595 
16596  return row->local;
16597 }
16598 
16599 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
16601  SCIP_ROW* row /**< LP row */
16602  )
16603 {
16604  assert(row != NULL);
16605 
16606  return row->modifiable;
16607 }
16608 
16609 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
16611  SCIP_ROW* row /**< LP row */
16612  )
16613 {
16614  assert(row != NULL);
16615 
16616  return row->removable;
16617 }
16618 
16619 /** returns type of origin that created the row */
16621  SCIP_ROW* row /**< LP row */
16622  )
16623 {
16624  assert( row != NULL );
16625 
16626  return (SCIP_ROWORIGINTYPE) row->origintype;
16627 }
16628 
16629 /** returns origin constraint handler that created the row (NULL if not available) */
16631  SCIP_ROW* row /**< LP row */
16632  )
16633 {
16634  assert( row != NULL );
16635 
16637  {
16638  assert( row->origin != NULL );
16639  return (SCIP_CONSHDLR*) row->origin;
16640  }
16641  return NULL;
16642 }
16643 
16644 /** returns origin separator that created the row (NULL if not available) */
16646  SCIP_ROW* row /**< LP row */
16647  )
16648 {
16649  assert( row != NULL );
16650 
16652  {
16653  assert( row->origin != NULL );
16654  return (SCIP_SEPA*) row->origin;
16655  }
16656  return NULL;
16657 }
16658 
16659 /** returns TRUE iff row is member of the global cut pool */
16661  SCIP_ROW* row /**< LP row */
16662  )
16663 {
16664  assert(row != NULL);
16665 
16666  return row->inglobalcutpool;
16667 }
16668 
16669 /** gets position of row in current LP, or -1 if it is not in LP */
16671  SCIP_ROW* row /**< LP row */
16672  )
16673 {
16674  assert(row != NULL);
16675  assert((row->lppos == -1) == (row->lpdepth == -1));
16676 
16677  return row->lppos;
16678 }
16679 
16680 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
16682  SCIP_ROW* row /**< LP row */
16683  )
16684 {
16685  assert(row != NULL);
16686  assert((row->lppos == -1) == (row->lpdepth == -1));
16687 
16688  return row->lpdepth;
16689 }
16690 
16691 /** returns TRUE iff row is member of current LP */
16693  SCIP_ROW* row /**< LP row */
16694  )
16695 {
16696  assert(row != NULL);
16697  assert((row->lppos == -1) == (row->lpdepth == -1));
16698 
16699  return (row->lppos >= 0);
16700 }
16701 
16702 /** changes the rank of LP row */
16704  SCIP_ROW* row, /**< LP row */
16705  int rank /**< new value for rank */
16706  )
16707 {
16708  assert(row != NULL);
16709 
16710  row->rank = rank;
16711 }
16712 
16713 /** returns the number of times that this row has been sharp in an optimal LP solution */
16715  SCIP_ROW* row /**< row */
16716  )
16717 {
16718  assert(row != NULL);
16719 
16720  return row->activeinlpcounter;
16721 }
16722 
16723 /** returns the number of LPs since this row has been created */
16725  SCIP_ROW* row /**< row */
16726  )
16727 {
16728  assert(row != NULL);
16729 
16730  return row->nlpsaftercreation;
16731 }
16732 
16733 /** gets array with columns of the LP */
16735  SCIP_LP* lp /**< current LP data */
16736  )
16737 {
16738  assert(lp != NULL);
16739 
16740  return lp->cols;
16741 }
16742 
16743 /** gets current number of columns in LP */
16745  SCIP_LP* lp /**< current LP data */
16746  )
16747 {
16748  assert(lp != NULL);
16749 
16750  return lp->ncols;
16751 }
16752 
16753 /** gets array with rows of the LP */
16755  SCIP_LP* lp /**< current LP data */
16756  )
16757 {
16758  assert(lp != NULL);
16759 
16760  return lp->rows;
16761 }
16762 
16763 /** gets current number of rows in LP */
16765  SCIP_LP* lp /**< current LP data */
16766  )
16767 {
16768  assert(lp != NULL);
16769 
16770  return lp->nrows;
16771 }
16772 
16773 /** gets array with newly added columns after the last mark */
16775  SCIP_LP* lp /**< current LP data */
16776  )
16777 {
16778  assert(lp != NULL);
16779  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16780 
16781  return &(lp->cols[lp->firstnewcol]);
16782 }
16783 
16784 /** gets number of newly added columns after the last mark */
16786  SCIP_LP* lp /**< current LP data */
16787  )
16788 {
16789  assert(lp != NULL);
16790  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16791 
16792  return lp->ncols - lp->firstnewcol;
16793 }
16794 
16795 /** gets array with newly added rows after the last mark */
16797  SCIP_LP* lp /**< current LP data */
16798  )
16799 {
16800  assert(lp != NULL);
16801  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16802 
16803  return &(lp->rows[lp->firstnewrow]);
16804 }
16805 
16806 /** gets number of newly added rows after the last mark */
16808  SCIP_LP* lp /**< current LP data */
16809  )
16810 {
16811  assert(lp != NULL);
16812  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16813 
16814  return lp->nrows - lp->firstnewrow;
16815 }
16816 
16817 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
16819  SCIP_SET* set, /**< global SCIP settings */
16820  SCIP_LP* lp /**< LP data */
16821  )
16822 {
16823  if( lp->objsqrnormunreliable )
16824  {
16825  SCIP_COL** cols;
16826  int c;
16827 
16828  cols = lp->cols;
16829  assert(cols != NULL || lp->ncols == 0);
16830 
16831  lp->objsqrnorm = 0.0;
16832 
16833  for( c = lp->ncols - 1; c >= 0; --c )
16834  {
16835  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
16836  }
16837  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
16838 
16839  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
16840  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
16841 
16843  }
16844  return;
16845 }
16846 
16847 /** gets Euclidean norm of objective function vector of column variables, only use this method if
16848  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
16850  SCIP_LP* lp /**< LP data */
16851  )
16852 {
16853  assert(lp != NULL);
16854  assert(!lp->objsqrnormunreliable);
16855  assert(lp->objsqrnorm >= 0.0);
16856 
16857  return SQRT(lp->objsqrnorm);
16858 }
16859 
16860 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16862  SCIP_LP* lp, /**< LP data */
16863  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
16864  )
16865 {
16866  assert(lp != NULL);
16867 
16868  lp->rootlpisrelax = isrelax;
16869 }
16870 
16871 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16873  SCIP_LP* lp /**< LP data */
16874  )
16875 {
16876  assert(lp != NULL);
16877 
16878  return lp->rootlpisrelax;
16879 }
16880 
16881 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
16883  SCIP_LP* lp /**< LP data */
16884  )
16885 {
16886  assert(lp != NULL);
16887 
16888  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
16889 }
16890 
16891 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
16892  * returns SCIP_INVALID if the root node LP was not (yet) solved
16893  */
16895  SCIP_LP* lp /**< LP data */
16896  )
16897 {
16898  assert(lp != NULL);
16899 
16900  return lp->rootlpobjval;
16901 }
16902 
16903 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
16904  * returns SCIP_INVALID if the root node LP was not (yet) solved
16905  */
16907  SCIP_LP* lp /**< LP data */
16908  )
16909 {
16910  assert(lp != NULL);
16911 
16912  return lp->rootlooseobjval;
16913 }
16914 
16915 /** gets the LP solver interface */
16917  SCIP_LP* lp /**< current LP data */
16918  )
16919 {
16920  assert(lp != NULL);
16921 
16922  return lp->lpi;
16923 }
16924 
16925 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
16927  SCIP_LP* lp, /**< LP data */
16928  SCIP_Bool relax /**< is the current lp a relaxation? */
16929  )
16930 {
16931  assert(lp != NULL);
16932 
16933  lp->isrelax = relax;
16934 }
16935 
16936 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
16937  * solution value a valid local lower bound?
16938  */
16940  SCIP_LP* lp /**< LP data */
16941  )
16942 {
16943  assert(lp != NULL);
16944 
16945  return lp->isrelax;
16946 }
16947 
16948 /** returns whether the current LP is flushed and solved */
16950  SCIP_LP* lp /**< current LP data */
16951  )
16952 {
16953  assert(lp != NULL);
16954 
16955  return lp->flushed && lp->solved;
16956 }
16957 
16958 /** return whether the current LP solution passed the primal feasibility check */
16960  SCIP_LP* lp /**< current LP data */
16961  )
16962 {
16963  assert(lp != NULL);
16964 
16965  return (lp->primalchecked && lp->primalfeasible);
16966 }
16967 
16968 /** return whether the current LP solution passed the dual feasibility check */
16970  SCIP_LP* lp /**< current LP data */
16971  )
16972 {
16973  assert(lp != NULL);
16974 
16975  return (lp->dualchecked && lp->dualfeasible);
16976 }
16977 
16978 /** returns whether the current LP solution is a basic solution */
16980  SCIP_LP* lp /**< current LP data */
16981  )
16982 {
16983  assert(lp != NULL);
16984 
16985  return lp->solisbasic;
16986 }
16987 
16988 /** returns whether the LP is in diving mode */
16990  SCIP_LP* lp /**< current LP data */
16991  )
16992 {
16993  assert(lp != NULL);
16994 
16995  return lp->diving;
16996 }
16997 
16998 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17000  SCIP_LP* lp /**< current LP data */
17001  )
17002 {
17003  assert(lp != NULL);
17004 
17005  return lp->divingobjchg;
17006 }
17007 
17008 /** marks the diving LP to have a changed objective function */
17010  SCIP_LP* lp /**< current LP data */
17011  )
17012 {
17013  assert(lp != NULL);
17014  assert(lp->diving || lp->probing);
17015 
17016  lp->divingobjchg = TRUE;
17017 }
17018 
17019 /** marks the diving LP to not have a changed objective function anymore */
17021  SCIP_LP* lp /**< current LP data */
17022  )
17023 {
17024  assert(lp != NULL);
17025  assert(lp->diving || lp->probing);
17026 
17027  lp->divingobjchg = FALSE;
17028 }
17029 
17030 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17032  SCIP_LP* lp /**< current LP data */
17033  )
17034 {
17035  assert(lp != NULL);
17036  assert(lp->diving || lp->ndivechgsides == 0);
17037 
17038  return (lp->ndivechgsides > 0);
17039 }
17040 
17041 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17042 static
17044  SCIP_LPI* lpi, /**< auxiliary LP interface */
17045  SCIP_SET* set, /**< global SCIP settings */
17046  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17047  SCIP_LP* lp, /**< LP data */
17048  SCIP_PROB* prob, /**< problem data */
17049  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17050  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17051  SCIP_Real timelimit, /**< time limit for LP solver */
17052  int iterlimit, /**< iteration limit for LP solver */
17053  SCIP_Real* point, /**< array to store relative interior point on exit */
17054  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17055  )
17056 {
17057  SCIP_RETCODE retcode;
17058  SCIP_Real* primal;
17059  SCIP_Real* obj;
17060  SCIP_Real* lb;
17061  SCIP_Real* ub;
17062  SCIP_Real* matvals;
17063  SCIP_Real* matlhs;
17064  SCIP_Real* matrhs;
17065  SCIP_Real objval;
17066  SCIP_Real alpha;
17067  int* matinds;
17068  int* matbeg;
17069 #ifndef NDEBUG
17070  int nslacks;
17071 #endif
17072  int nnewcols;
17073  int ntotnonz = 0;
17074  int ntotrows = 0;
17075  int matrowidx;
17076  int matidx;
17077  int cnt;
17078  int j;
17079  int i;
17080 
17081  assert(lpi != NULL);
17082 
17084  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17085  {
17086  SCIP_CALL( retcode );
17087  }
17088 
17090  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17091  {
17092  SCIP_CALL( retcode );
17093  }
17094 
17095  /* get storage */
17096  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17097  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17098  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17099  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17100 
17101  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17102  for( j = 0; j < lp->ncols; ++j )
17103  {
17104  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17105  obj[j] = 0.0;
17106  lb[j] = -SCIPlpiInfinity(lpi);
17107  ub[j] = SCIPlpiInfinity(lpi);
17108  /* note: we could also use the original bounds - free variables seem to be faster. */
17109  }
17110 
17111  /* add artificial alpha variable */
17112  nnewcols = lp->ncols;
17113  obj[nnewcols] = 0.0;
17114  lb[nnewcols] = 1.0;
17115  ub[nnewcols] = SCIPlpiInfinity(lpi);
17116  ++nnewcols;
17117 
17118  /* create slacks for rows */
17119  for( i = 0; i < lp->nrows; ++i )
17120  {
17121  SCIP_ROW* row;
17122 
17123  row = lp->rows[i];
17124  assert( row != NULL );
17125 
17126  if( SCIProwIsModifiable(row) )
17127  continue;
17128 
17129  /* make sure row is sorted */
17130  rowSortLP(row);
17131  assert( row->lpcolssorted );
17132 
17133  /* check whether we have an equation */
17134  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17135  {
17136  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17137  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17138  ntotnonz += row->nlpcols + 1;
17139  ++ntotrows;
17140  }
17141  else
17142  {
17143  /* otherwise add slacks for each side if necessary */
17144  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17145  {
17146  if ( relaxrows )
17147  {
17148  lb[nnewcols] = 0.0;
17149  ub[nnewcols] = 1.0;
17150  obj[nnewcols++] = 1.0;
17151  ntotnonz += row->nlpcols + 2;
17152  }
17153  else
17154  ntotnonz += row->nlpcols + 1;
17155  ++ntotrows;
17156  }
17157  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17158  {
17159  if ( relaxrows )
17160  {
17161  lb[nnewcols] = 0.0;
17162  ub[nnewcols] = 1.0;
17163  obj[nnewcols++] = 1.0;
17164  ntotnonz += row->nlpcols + 2;
17165  }
17166  else
17167  ntotnonz += row->nlpcols + 1;
17168  ++ntotrows;
17169  }
17170  }
17171  }
17172 
17173  /* create slacks for objective cutoff row */
17174  if( inclobjcutoff && relaxrows )
17175  {
17176  /* add slacks for right hand side */
17177  lb[nnewcols] = 0.0;
17178  ub[nnewcols] = 1.0;
17179  obj[nnewcols++] = 1.0;
17180  ntotnonz += lp->ncols + 2;
17181  ++ntotrows;
17182  }
17183 
17184  /* create slacks for bounds */
17185  for( j = 0; j < lp->ncols; ++j )
17186  {
17187  SCIP_COL* col;
17188 
17189  col = lp->cols[j];
17190  assert( col != NULL );
17191 
17192  /* no slacks for fixed variables */
17193  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17194  {
17195  ++ntotrows;
17196  ntotnonz += 2;
17197  }
17198  else
17199  {
17200  /* add slacks for each bound if necessary */
17201  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17202  {
17203  lb[nnewcols] = 0.0;
17204  ub[nnewcols] = 1.0;
17205  obj[nnewcols++] = 1.0;
17206  ntotnonz += 3;
17207  ++ntotrows;
17208  }
17209  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
17210  {
17211  lb[nnewcols] = 0.0;
17212  ub[nnewcols] = 1.0;
17213  obj[nnewcols++] = 1.0;
17214  ntotnonz += 3;
17215  ++ntotrows;
17216  }
17217  }
17218  }
17219 #ifndef NDEBUG
17220  nslacks = nnewcols - lp->ncols - 1;
17221  assert( nslacks >= 0 );
17222  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17223 #endif
17224 
17225  /* add columns */
17226  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17227 
17228  /* free storage */
17229  SCIPsetFreeBufferArray(set, &obj);
17230  SCIPsetFreeBufferArray(set, &ub);
17231  SCIPsetFreeBufferArray(set, &lb);
17232 
17233  /* prepare storage for rows */
17234  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
17235  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
17236  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
17237  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
17238  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
17239 
17240  /* create rows arising from original rows */
17241  cnt = 0;
17242  matrowidx = 0;
17243  matidx = 0;
17244  for( i = 0; i < lp->nrows; ++i )
17245  {
17246  SCIP_ROW* row;
17247  SCIP_COL** rowcols;
17248  SCIP_Real* rowvals;
17249  SCIP_Real lhs;
17250  SCIP_Real rhs;
17251  int nnonz;
17252 
17253  row = lp->rows[i];
17254  assert( row != NULL );
17255 
17256  if( SCIProwIsModifiable(row) )
17257  continue;
17258  assert( row->lpcolssorted );
17259 
17260  /* get row data */
17261  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17262  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17263  nnonz = row->nlpcols;
17264  assert( nnonz <= lp->ncols );
17265  rowcols = row->cols;
17266  rowvals = row->vals;
17267 
17268  /* if we have an equation */
17269  if( SCIPsetIsEQ(set, lhs, rhs) )
17270  {
17271  /* set up indices */
17272  matbeg[matrowidx] = matidx;
17273  for( j = 0; j < nnonz; ++j )
17274  {
17275  assert( rowcols[j] != NULL );
17276  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17277  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17278  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17279  matinds[matidx] = rowcols[j]->lppos;
17280  matvals[matidx++] = rowvals[j];
17281  assert( matidx <= ntotnonz );
17282  }
17283 
17284  /* add artificial variable */
17285  if ( ! SCIPsetIsZero(set, rhs) )
17286  {
17287  matinds[matidx] = lp->ncols;
17288  matvals[matidx++] = -rhs;
17289  assert( matidx <= ntotnonz );
17290  }
17291 
17292  matlhs[matrowidx] = 0.0;
17293  matrhs[matrowidx++] = 0.0;
17294  assert( matrowidx <= ntotrows );
17295  }
17296  else
17297  {
17298  SCIP_Real abslhs = REALABS(lhs);
17299  SCIP_Real absrhs = REALABS(rhs);
17300 
17301  assert(!SCIPsetIsEQ(set, lhs, rhs));
17302 
17303  /* treat lhs */
17304  if( !SCIPsetIsInfinity(set, abslhs) )
17305  {
17306  /* set up indices */
17307  matbeg[matrowidx] = matidx;
17308  for( j = 0; j < nnonz; ++j )
17309  {
17310  assert( rowcols[j] != NULL );
17311  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17312  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17313  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17314  matinds[matidx] = rowcols[j]->lppos;
17315  matvals[matidx++] = rowvals[j];
17316  assert( matidx <= ntotnonz );
17317  }
17318 
17319  /* add artificial variable */
17320  if ( ! SCIPsetIsZero(set, lhs) )
17321  {
17322  matinds[matidx] = lp->ncols;
17323  matvals[matidx++] = -lhs;
17324  assert( matidx <= ntotnonz );
17325  }
17326 
17327  if( relaxrows )
17328  {
17329  /* add slack variable */
17330  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
17331  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17332  assert( matidx <= ntotnonz );
17333  ++cnt;
17334  }
17335 
17336  matlhs[matrowidx] = 0.0;
17337  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
17338  assert( matrowidx <= ntotrows );
17339  }
17340 
17341  /* treat rhs */
17342  if( !SCIPsetIsInfinity(set, absrhs) )
17343  {
17344  /* set up indices */
17345  matbeg[matrowidx] = matidx;
17346  for( j = 0; j < nnonz; ++j )
17347  {
17348  assert( rowcols[j] != NULL );
17349  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17350  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17351  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17352  matinds[matidx] = rowcols[j]->lppos;
17353  matvals[matidx++] = rowvals[j];
17354  assert( matidx <= ntotnonz );
17355  }
17356 
17357  /* add artificial variable */
17358  if ( ! SCIPsetIsZero(set, rhs) )
17359  {
17360  matinds[matidx] = lp->ncols;
17361  matvals[matidx++] = -rhs;
17362  assert( matidx <= ntotnonz );
17363  }
17364 
17365  if( relaxrows )
17366  {
17367  /* add slack variable */
17368  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
17369  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17370  ++cnt;
17371  }
17372 
17373  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
17374  matrhs[matrowidx++] = 0.0;
17375  assert( matrowidx <= ntotrows );
17376  }
17377  }
17378  }
17379 
17380  /* create row arising from objective cutoff */
17381  if( inclobjcutoff )
17382  {
17383  SCIP_Real rhs;
17384 
17385  /* get row data */
17386  assert(lp->looseobjvalinf == 0);
17387  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17388 
17389  /* set up indices and coefficients */
17390  matbeg[matrowidx] = matidx;
17391  for( j = 0; j < lp->ncols; ++j )
17392  {
17393  assert( lp->cols[j] != NULL );
17394  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17395  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17396 
17397  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
17398  {
17399  matinds[matidx] = lp->cols[j]->lppos;
17400  matvals[matidx++] = lp->cols[j]->obj;
17401  assert( matidx <= ntotnonz );
17402  }
17403  }
17404 
17405  /* treat rhs */
17406 
17407  /* add artificial variable */
17408  if ( ! SCIPsetIsZero(set, rhs) )
17409  {
17410  matinds[matidx] = lp->ncols;
17411  matvals[matidx++] = -rhs;
17412  assert( matidx <= ntotnonz );
17413  }
17414 
17415  if( relaxrows )
17416  {
17417  SCIP_Real absrhs = REALABS(rhs);
17418 
17419  /* add slack variable */
17420  matvals[matidx] = MAX(1.0, absrhs);
17421  matinds[matidx++] = lp->ncols + 1 + cnt;
17422  assert( matidx <= ntotnonz );
17423  ++cnt;
17424  }
17425  matlhs[matrowidx] = -SCIPsetInfinity(set);
17426  matrhs[matrowidx++] = 0.0;
17427  assert( matrowidx <= ntotrows );
17428  }
17429 
17430  /* create rows arising from bounds */
17431  for( j = 0; j < lp->ncols; ++j )
17432  {
17433  SCIP_COL* col;
17434  SCIP_Real abscollb;
17435  SCIP_Real abscolub;
17436 
17437  col = lp->cols[j];
17438  assert( col != NULL );
17439  assert( col->lppos == j );
17440 
17441  /* fixed variable */
17442  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17443  {
17444  /* set up index of column */
17445  matbeg[matrowidx] = matidx;
17446 
17447  matinds[matidx] = j;
17448  matvals[matidx++] = 1.0;
17449  assert( matidx <= ntotnonz );
17450 
17451  /* add artificial variable */
17452  if ( ! SCIPsetIsZero(set, col->ub) )
17453  {
17454  matinds[matidx] = lp->ncols;
17455  matvals[matidx++] = -col->lb;
17456  assert( matidx <= ntotnonz );
17457  }
17458 
17459  matlhs[matrowidx] = 0.0;
17460  matrhs[matrowidx++] = 0.0;
17461  assert( matrowidx <= ntotrows );
17462 
17463  continue;
17464  }
17465 
17466  abscollb = REALABS(col->lb);
17467  abscolub = REALABS(col->ub);
17468 
17469  /* lower bound */
17470  if ( ! SCIPsetIsInfinity(set, abscollb) )
17471  {
17472  /* set up index of column */
17473  matbeg[matrowidx] = matidx;
17474 
17475  matinds[matidx] = j;
17476  matvals[matidx++] = 1.0;
17477  assert( matidx <= ntotnonz );
17478 
17479  /* add artificial variable */
17480  if ( ! SCIPsetIsZero(set, col->lb) )
17481  {
17482  matinds[matidx] = lp->ncols;
17483  matvals[matidx++] = -col->lb;
17484  assert( matidx <= ntotnonz );
17485  }
17486 
17487  /* add slack variable */
17488  matvals[matidx] = -MAX(1.0, abscollb);
17489  matinds[matidx++] = lp->ncols + 1 + cnt;
17490  assert( matidx <= ntotnonz );
17491  ++cnt;
17492 
17493  matlhs[matrowidx] = 0.0;
17494  matrhs[matrowidx++] = SCIPsetInfinity(set);
17495  assert( matrowidx <= ntotrows );
17496  }
17497 
17498  /* upper bound */
17499  if ( ! SCIPsetIsInfinity(set, abscolub) )
17500  {
17501  /* set up index of column */
17502  matbeg[matrowidx] = matidx;
17503 
17504  matinds[matidx] = j;
17505  matvals[matidx++] = 1.0;
17506  assert( matidx <= ntotnonz );
17507 
17508  /* add artificial variable */
17509  if ( ! SCIPsetIsZero(set, col->ub) )
17510  {
17511  matinds[matidx] = lp->ncols;
17512  matvals[matidx++] = -col->ub;
17513  assert( matidx <= ntotnonz );
17514  }
17515 
17516  /* add slack variable */
17517  matvals[matidx] = MAX(1.0, abscolub);
17518  matinds[matidx++] = lp->ncols + 1 + cnt;
17519  assert( matidx <= ntotnonz );
17520  ++cnt;
17521 
17522  matlhs[matrowidx] = -SCIPsetInfinity(set);
17523  matrhs[matrowidx++] = 0.0;
17524  assert( matrowidx <= ntotrows );
17525  }
17526  }
17527  assert( cnt == nslacks );
17528  assert( matrowidx == ntotrows );
17529 
17530  /* add rows */
17531  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
17532 
17533  SCIPsetFreeBufferArray(set, &matrhs);
17534  SCIPsetFreeBufferArray(set, &matlhs);
17535  SCIPsetFreeBufferArray(set, &matbeg);
17536  SCIPsetFreeBufferArray(set, &matvals);
17537  SCIPsetFreeBufferArray(set, &matinds);
17538 
17539 #ifdef SCIP_OUTPUT
17540  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
17541 #endif
17542 
17543 #ifndef NDEBUG
17544  {
17545  int ncols;
17546  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
17547  assert( ncols == nnewcols );
17548  }
17549 #endif
17550 
17551  /* set time limit */
17552  if( SCIPsetIsInfinity(set, timelimit) )
17553  timelimit = SCIPlpiInfinity(lpi);
17554  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
17555 
17556  /* check, if parameter is unknown */
17557  if ( retcode == SCIP_PARAMETERUNKNOWN )
17558  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
17559 
17560  /* set iteration limit */
17561  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
17562 
17563  /* check, if parameter is unknown */
17564  if ( retcode == SCIP_PARAMETERUNKNOWN )
17565  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
17566 
17567  /* solve and store point */
17568  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
17569  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
17570 
17571 #ifndef NDEBUG
17572  if ( SCIPlpiIsIterlimExc(lpi) )
17573  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
17574  if ( SCIPlpiIsTimelimExc(lpi) )
17575  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
17576 #endif
17577 
17578  if( SCIPlpiIsOptimal(lpi) )
17579  {
17580  /* get primal solution */
17581  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
17582  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
17583  alpha = primal[lp->ncols];
17584  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
17585 
17586  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
17587 
17588  /* construct relative interior point */
17589  for( j = 0; j < lp->ncols; ++j )
17590  point[j] = primal[j]/alpha;
17591 
17592 #ifdef SCIP_DEBUG
17593  /* check whether the point is a relative interior point */
17594  cnt = 0;
17595  if( relaxrows )
17596  {
17597  for( i = 0; i < lp->nrows; ++i )
17598  {
17599  SCIP_ROW* row;
17600  SCIP_COL** rowcols;
17601  SCIP_Real* rowvals;
17602  SCIP_Real lhs;
17603  SCIP_Real rhs;
17604  SCIP_Real sum;
17605  int nnonz;
17606 
17607  row = lp->rows[i];
17608  assert( row != NULL );
17609 
17610  /* get row data */
17611  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17612  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17613  nnonz = row->nlpcols;
17614  assert( nnonz <= lp->ncols );
17615  rowcols = row->cols;
17616  rowvals = row->vals;
17617 
17618  sum = 0.0;
17619  for( j = 0; j < nnonz; ++j )
17620  sum += rowvals[j] * primal[rowcols[j]->lppos];
17621  sum /= alpha;
17622 
17623  /* if we have an equation */
17624  if( SCIPsetIsEQ(set, lhs, rhs) )
17625  {
17626  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
17627  }
17628  else
17629  {
17630  /* treat lhs */
17631  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
17632  {
17633  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
17634  ++cnt;
17635  }
17636  /* treat rhs */
17637  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
17638  {
17639  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17640  ++cnt;
17641  }
17642  }
17643  }
17644  if( inclobjcutoff )
17645  {
17646  SCIP_Real sum;
17647 #ifndef NDEBUG
17648  SCIP_Real rhs;
17649 
17650  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17651 #endif
17652  sum = 0.0;
17653  for( j = 0; j < lp->ncols; ++j )
17654  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
17655  sum /= alpha;
17656 
17657  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17658  ++cnt;
17659  }
17660  }
17661  /* check bounds */
17662  for( j = 0; j < lp->ncols; ++j )
17663  {
17664  SCIP_COL* col;
17665 #ifndef NDEBUG
17666  SCIP_Real val;
17667 #endif
17668 
17669  col = lp->cols[j];
17670  assert( col != NULL );
17671 #ifndef NDEBUG
17672  val = primal[col->lppos] / alpha;
17673 #endif
17674  /* if the variable is not fixed */
17675  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
17676  {
17677  /* treat lb */
17678  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17679  {
17680  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
17681  ++cnt;
17682  }
17683  /* treat rhs */
17684  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17685  {
17686  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
17687  ++cnt;
17688  }
17689  }
17690  }
17691 #endif
17692 
17693  /* free */
17694  SCIPsetFreeBufferArray(set, &primal);
17695 
17696  *success = TRUE;
17697  }
17698 
17699  return SCIP_OKAY;
17700 }
17701 
17702 /** compute relative interior point
17703  *
17704  * We use the approach of@par
17705  * R. Freund, R. Roundy, M. J. Todd@par
17706  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
17707  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
17708  *
17709  * to compute a relative interior point for the current LP.
17710  *
17711  * Assume the original LP looks as follows:
17712  * \f[
17713  * \begin{array}{rrl}
17714  * \min & c^T x &\\
17715  * & A x & \geq a\\
17716  * & B x & \leq b\\
17717  * & D x & = d.
17718  * \end{array}
17719  * \f]
17720  * Note that bounds should be included in the system.
17721  *
17722  * To find an interior point the following LP does the job:
17723  * \f[
17724  * \begin{array}{rrl}
17725  * \max & 1^T y &\\
17726  * & A x - y - \alpha a & \geq 0\\
17727  * & B x + y - \alpha b & \leq 0\\
17728  * & D x - \alpha d & = 0\\
17729  * & 0 \leq y & \leq 1\\
17730  * & \alpha & \geq 1.
17731  * \end{array}
17732  * \f]
17733  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
17734  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
17735  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
17736  */
17738  SCIP_SET* set, /**< global SCIP settings */
17739  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17740  SCIP_LP* lp, /**< LP data */
17741  SCIP_PROB* prob, /**< problem data */
17742  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17743  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17744  SCIP_Real timelimit, /**< time limit for LP solver */
17745  int iterlimit, /**< iteration limit for LP solver */
17746  SCIP_Real* point, /**< array to store relative interior point on exit */
17747  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17748  )
17749 {
17750  SCIP_LPI* lpi;
17751 
17752  SCIP_RETCODE retcode;
17753 
17754  assert(set != NULL);
17755  assert(lp != NULL);
17756  assert(point != NULL);
17757  assert(success != NULL);
17758 
17759  *success = FALSE;
17760 
17761  /* check time and iteration limits */
17762  if ( timelimit <= 0.0 || iterlimit <= 0 )
17763  return SCIP_OKAY;
17764 
17765  /* exit if there are no columns */
17766  assert(lp->nrows >= 0);
17767  assert(lp->ncols >= 0);
17768  if( lp->ncols == 0 )
17769  return SCIP_OKAY;
17770 
17771  /* disable objective cutoff if we have none */
17772  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
17773  inclobjcutoff = FALSE;
17774 
17775  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
17776 
17777  /* if there are no rows, we return the zero point */
17778  if( lp->nrows == 0 && !inclobjcutoff )
17779  {
17780  /* create zero point */
17781  BMSclearMemoryArray(point, lp->ncols);
17782  *success = TRUE;
17783 
17784  return SCIP_OKAY;
17785  }
17786 
17787  /* create auxiliary LP */
17788  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
17789 
17790  /* catch return code and ensure that lpi is freed, anyway */
17791  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
17792 
17793  SCIP_CALL( SCIPlpiFree(&lpi) );
17794 
17795  return retcode;
17796 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:369
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:6891
SCIP_Longint nprimallps
Definition: struct_stat.h:175
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:16610
SCIP_Bool solisbasic
Definition: struct_lp.h:353
SCIP_Real lazyub
Definition: struct_lp.h:134
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1698
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:61
SCIP_Bool lpissolved
Definition: struct_lp.h:116
int nunlinked
Definition: struct_lp.h:228
static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition: lp.c:17043
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4641
int firstnewrow
Definition: struct_lp.h:317
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:15713
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6383
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:12700
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:4597
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:71
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:189
int nsbcalls
Definition: struct_lp.h:167
SCIP_Bool primalchecked
Definition: struct_lp.h:112
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lp.c:335
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5776
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6079
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2502
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2793
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6566
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:449
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2693
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:13235
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8738
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:9941
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17031
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2768
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7171
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5834
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:16807
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6284
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2894
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:6814
void * origin
Definition: struct_lp.h:216
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:222
static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
Definition: lp.c:4830
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13539
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
SCIP_STATUS status
Definition: struct_stat.h:167
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:16989
SCIP_Real farkascoef
Definition: struct_lp.h:141
unsigned int ubchanged
Definition: struct_lp.h:175
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1821
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9486
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:16926
SCIP_Longint validactivitylp
Definition: struct_lp.h:223
int lpifirstchgrow
Definition: struct_lp.h:303
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2354
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3547
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:16560
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1358
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:16645
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:93
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:190
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6550
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:78
int * cols_index
Definition: struct_lp.h:219
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15580
int nremovablecols
Definition: struct_lp.h:312
char * name
Definition: struct_var.h:229
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:14935
SCIP_Bool primalfeasible
Definition: struct_lp.h:349
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:17737
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:862
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3043
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:842
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
int nchgrows
Definition: struct_lp.h:307
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:8477
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9653
char * name
Definition: struct_lp.h:217
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:17424
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6149
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:3416
int nlpicols
Definition: struct_lp.h:299
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6174
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:501
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:14904
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6297
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:16861
SCIP_Longint nlps
Definition: struct_stat.h:173
SCIP_Longint activeinlpcounter
Definition: struct_lp.h:213
SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
Definition: event.c:2117
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17276
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6503
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:335
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
#define SCIP_MAXSTRLEN
Definition: def.h:259
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7811
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16240
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6047
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:16818
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:68
internal methods for clocks and timing issues
unsigned int origintype
Definition: struct_lp.h:255
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13112
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16360
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16372
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5899
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:105
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16402
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
SCIP_Real objsumnorm
Definition: struct_lp.h:281
SCIP_Longint ndivinglps
Definition: struct_stat.h:187
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:1856
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17332
SCIP_ROW ** chgrows
Definition: struct_lp.h:286
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5214
SCIP_COL ** chgcols
Definition: struct_lp.h:285
SCIP_RETCODE SCIProwChgConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real constant)
Definition: lp.c:5460
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:14524
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14449
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11645
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16540
int rank
Definition: struct_lp.h:239
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:990
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16842
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5636
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1225
int rowssize
Definition: struct_lp.h:314
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8703
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3601
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7703
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:16714
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12779
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13430
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13718
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:586
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11175
unsigned int nonlprowssorted
Definition: struct_lp.h:172
int nclockskipsleft
Definition: struct_stat.h:256
SCIP_COL ** cols
Definition: struct_lp.h:287
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9880
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1261
int nlpirows
Definition: struct_lp.h:302
#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:16416
#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:3182
static const int nscalars
Definition: lp.c:5619
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:9639
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:38
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13402
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16481
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:64
int lppos
Definition: struct_lp.h:163
SCIP_Real lazylb
Definition: struct_lp.h:132
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:15749
#define EPSEQ(x, y, eps)
Definition: def.h:174
#define EPSISINT(x, eps)
Definition: def.h:186
int pseudoobjvalinf
Definition: struct_lp.h:321
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:16979
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:13471
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6317
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:736
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:16271
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3522
int divinglpiitlim
Definition: struct_lp.h:325
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16182
SCIP_Bool solved
Definition: struct_lp.h:348
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:1655
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:10289
struct SCIP_LPiNorms SCIP_LPINORMS
Definition: type_lpi.h:98
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Longint nrootlps
Definition: struct_stat.h:174
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:16529
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16162
SCIP_Bool dualchecked
Definition: struct_lp.h:352
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10011
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5888
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:15727
#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:8034
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool lpifromscratch
Definition: struct_lp.h:366
unsigned int basisstatus
Definition: struct_lp.h:240
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2730
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6614
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9814
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:16894
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15567
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1877
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:447
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2542
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:5351
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16969
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:341
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:48
unsigned int sbdownvalid
Definition: struct_lp.h:179
unsigned int objchanged
Definition: struct_lp.h:173
#define DIVESTACKGROWFACT
Definition: lp.c:15510
unsigned int delaysort
Definition: struct_lp.h:243
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5326
unsigned int basisstatus
Definition: struct_lp.h:170
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:16303
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Real lpidualfeastol
Definition: struct_lp.h:277
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:63
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:14873
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5985
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3020
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:8859
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:327
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:105
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6770
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1865
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:15331
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:5856
int index
Definition: struct_lp.h:158
SCIP_Real relpseudoobjval
Definition: struct_lp.h:271
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2869
SCIP_Real dualfarkas
Definition: struct_lp.h:206
SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12045
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:149
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11963
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:16754
SCIP_Bool diving
Definition: struct_lp.h:361
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7725
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:13153
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12811
SCIP_Real rootlooseobjval
Definition: struct_lp.h:273
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
SCIP_RETCODE SCIPcolIncCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real incval)
Definition: lp.c:3467
int firstnewcol
Definition: struct_lp.h:313
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:15112
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3371
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:9955
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:5001
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:14464
unsigned int integral
Definition: struct_lp.h:248
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:427
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:9921
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1094
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:94
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5910
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:16620
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:2955
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1023
#define SCIP_LONGINT_MAX
Definition: def.h:135
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:147
int lpifirstchgcol
Definition: struct_lp.h:300
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1884
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:127
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:15552
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2514
#define checkRow(row)
Definition: lp.c:652
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6130
int maxdepth
Definition: struct_stat.h:217
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:8833
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:76
int looseobjvalinf
Definition: struct_lp.h:318
SCIP_Real obj
Definition: struct_var.h:203
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:342
unsigned int rhschanged
Definition: struct_lp.h:246
SCIP_RETCODE SCIProwIncCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real incval)
Definition: lp.c:5403
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:16501
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:283
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:11084
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12612
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4629
internal methods for LP management
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
int lazycolssize
Definition: struct_lp.h:310
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13631
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:820
SCIP_Real objprod
Definition: struct_lp.h:201
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:16872
int colssize
Definition: struct_lp.h:308
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:336
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:15513
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:372
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:382
SCIP_Bool lpipresolving
Definition: struct_lp.h:367
int nremovablerows
Definition: struct_lp.h:316
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_Bool primalchecked
Definition: struct_lp.h:350
real eps
SCIP_Bool strongbranching
Definition: struct_lp.h:358
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1298
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
#define checkLinks(lp)
Definition: lp.c:1581
int lpithreads
Definition: struct_lp.h:328
int ndivechgsides
Definition: struct_lp.h:323
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:16744
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11936
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11227
#define SCIP_DEFAULT_EPSILON
Definition: def.h:155
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:11230
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5870
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:16692
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:6646
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2310
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int integral
Definition: struct_lp.h:177
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:8721
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:3945
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
int nloosevars
Definition: struct_lp.h:319
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:1942
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:16882
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3750
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4720
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17286
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6034
int divechgsidessize
Definition: struct_lp.h:324
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5816
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:15073
int * linkpos
Definition: struct_lp.h:157
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:354
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6043
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:39
int lpiitlim
Definition: struct_lp.h:326
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition: lp.c:9838
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: lp.c:7639
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:278
SCIP_RETCODE SCIPcolAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition: lp.c:3350
int glbpseudoobjvalinf
Definition: struct_lp.h:320
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:16785
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13498
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16469
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:443
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2436
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13763
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:454
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15225
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16205
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6582
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:15537
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5541
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:5891
int lpirefactorinterval
Definition: struct_lp.h:332
SCIP_ROW ** divechgrows
Definition: struct_lp.h:293
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:378
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:7985
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:1763
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:15764
SCIP_Bool installing
Definition: struct_lp.h:357
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:383
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:16959
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16392
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:4790
SCIP_Real SCIPsetLpfeastol(SCIP_SET *set)
Definition: set.c:5698
#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:3132
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:13841
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:16969
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:171
SCIP_Bool lpilpinfo
Definition: struct_lp.h:368
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:16350
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_Real pseudoactivity
Definition: struct_lp.h:207
SCIP_PRICING lpipricing
Definition: struct_lp.h:333
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9231
SCIP_Bool dualchecked
Definition: struct_lp.h:114
SCIP_COL ** cols
Definition: struct_lp.h:218
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:959
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9414
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:16734
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16590
SCIP_Bool adjustlpval
Definition: struct_lp.h:365
SCIP_Real minval
Definition: struct_lp.h:203
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:3985
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIPInterval sqrt(const SCIPInterval &x)
SCIP_ROW ** lpirows
Definition: struct_lp.h:284
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:180
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:15002
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8429
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5605
SCIP_Longint validfarkaslp
Definition: struct_lp.h:296
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:9728
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9571
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5711
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16172
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:96
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
int nuses
Definition: struct_lp.h:229
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16662
int lpiscaling
Definition: struct_lp.h:331
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:2000
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:16580
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
struct SCIP_LPiState SCIP_LPISTATE
Definition: type_lpi.h:97
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6211
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14153
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6023
SCIP_Real cutoffbound
Definition: struct_lp.h:274
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6325
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:9290
internal miscellaneous methods
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:16630
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:10034
SCIP_Bool isrelax
Definition: struct_lp.h:355
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:16849
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
int numintcols
Definition: struct_lp.h:235
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
#define REALABS(x)
Definition: def.h:173
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:294
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2656
SCIP_Bool looseobjvalid
Definition: struct_lp.h:339
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:14383
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:350
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6262
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:17414
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6401
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:16764
int lpirandomseed
Definition: struct_lp.h:330
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:584
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:214
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17009
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:345
SCIP_Bool resolvelperror
Definition: struct_lp.h:364
unsigned int removable
Definition: struct_lp.h:178
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:271
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:16491
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8182
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11166
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5798
#define lpCutoffDisabled(set)
Definition: lp.c:2607
int lpicolssize
Definition: struct_lp.h:298
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:16916
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12628
SCIP_LPI * lpi
Definition: struct_lp.h:282
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5174
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2393
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:16600
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1776
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:266
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6218
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16427
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6714
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:182
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:292
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2257
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4083
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6598
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:150
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:1481
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:8811
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8663
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5227
int var_probindex
Definition: struct_lp.h:169
static SCIP_RETCODE lpSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:11676
SCIP_Longint nduallps
Definition: struct_stat.h:177
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6341
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16261
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:446
internal methods for problem variables
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7776
#define SCIP_UNKNOWN
Definition: def.h:170
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9597
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5921
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16437
int nchgcols
Definition: struct_lp.h:305
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
int len
Definition: struct_lp.h:160
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:16906
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9552
#define SCIP_Bool
Definition: def.h:61
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12711
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5668
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:183
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:435
int numminval
Definition: struct_lp.h:237
int lpipos
Definition: struct_lp.h:231
int size
Definition: struct_lp.h:225
unsigned int modifiable
Definition: struct_lp.h:250
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:778
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
void SCIPprintSysError(const char *message)
Definition: misc.c:9920
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:14623
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:9156
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16192
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5924
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:95
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3802
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
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
int chgrowssize
Definition: struct_lp.h:306
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:16796
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:17663
SCIP_Longint validfarkaslp
Definition: struct_lp.h:155
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:285
unsigned int lbchanged
Definition: struct_lp.h:174
SCIP_Bool divingobjchg
Definition: struct_lp.h:362
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9631
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:448
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16999
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3660
#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:1058
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_Bool updateintegrality
Definition: struct_lp.h:346
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17134
#define DIVESTACKINITSIZE
Definition: lp.c:8876
#define SCIPsetDebugMsg
Definition: set.h:1913
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:376
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:4113
int minidx
Definition: struct_lp.h:233
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:16282
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2141
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2262
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:381
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17124
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
int nlprows
Definition: struct_lp.h:161
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition: lp.c:5305
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:8879
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9614
unsigned int lpcolssorted
Definition: struct_lp.h:241
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:363
SCIP_Longint validsollp
Definition: struct_lp.h:295
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3268
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9583
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16514
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16990
static void colSortLP(SCIP_COL *col)
Definition: lp.c:926
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13329
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6671
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6730
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:239
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15151
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6196
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6007
SCIP_ROW ** rows
Definition: struct_lp.h:289
SCIP_Longint validredcostlp
Definition: struct_lp.h:154
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3705
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1172
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:290
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:9897
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3008
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:7663
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3280
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3310
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12025
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1133
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:198
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:16570
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:12939
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:148
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16218
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9200
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:4361
#define SCIP_REAL_MAX
Definition: def.h:150
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5253
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6506
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6482
SCIP_Real rhs
Definition: struct_lp.h:196
static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13071
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:10947
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7530
#define checkRowObjprod(row)
Definition: lp.c:727
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12667
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:15603
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:7969
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:12841
unsigned int removable
Definition: struct_lp.h:251
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lp.c:538
unsigned int lhschanged
Definition: struct_lp.h:245
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2578
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:151
SCIP_COL ** lazycols
Definition: struct_lp.h:288
static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1423
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:268
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16447
int sbitlim
Definition: struct_lp.h:166
static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:14721
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12687
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16325
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6655
int age
Definition: struct_lp.h:168
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:210
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:150
SCIP_Real * vals
Definition: struct_lp.h:153
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6461
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:360
SCIP_Real rellooseobjval
Definition: struct_lp.h:264
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16251
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8777
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:9965
static const SCIP_Real scalars[]
Definition: lp.c:5618
int lpipos
Definition: struct_lp.h:164
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real objlim)
Definition: lp.c:2614
int chgcolssize
Definition: struct_lp.h:304
int lpitiming
Definition: struct_lp.h:329
internal methods for main solving loop and node processing
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:623
SCIP_Longint domchgcount
Definition: struct_stat.h:103
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:215
SCIP_Real * divechgsides
Definition: struct_lp.h:291
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:16703
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8535
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1590
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
SCIP_Real rootlpobjval
Definition: struct_lp.h:272
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1723
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:135
unsigned int coefchanged
Definition: struct_lp.h:247
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:142
SCIP_Longint nbarrierlps
Definition: struct_stat.h:180
SCIP_Bool flushed
Definition: struct_lp.h:347
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8330
SCIP_CLOCK * primallptime
Definition: struct_stat.h:146
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13348
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6141
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:128
int lpdepth
Definition: struct_lp.h:165
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
unsigned int inglobalcutpool
Definition: struct_lp.h:252
int nrows
Definition: struct_lp.h:315
#define checkRowSqrnorm(row)
Definition: lp.c:725
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:14797
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:156
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13584
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:170
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4661
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:380
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:230
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:6129
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5852
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:16382
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16781
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
struct SCIP_LPi SCIP_LPI
Definition: type_lpi.h:96
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:16670
int ndivingrows
Definition: struct_lp.h:322
SCIP_Longint divenolddomchgs
Definition: struct_lp.h:297
SCIP_Real lpobjval
Definition: struct_lp.h:261
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4202
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:149
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:16949
int size
Definition: struct_lp.h:159
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7606
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6295
SCIP_Longint validsblp
Definition: struct_lp.h:156
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:3669
SCIP_Real lpiobjlim
Definition: struct_lp.h:275
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:5688
#define SCIPsetDebugMsgPrint
Definition: set.h:1914
int lpirowssize
Definition: struct_lp.h:301
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4064
#define BMSallocMemory(ptr)
Definition: memory.h:101
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13820
#define SCIP_INVALID
Definition: def.h:169
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:109
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5573
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:16939
SCIP_CLOCK * duallptime
Definition: struct_stat.h:147
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:134
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17388
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6495
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10011
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:2978
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:16681
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14326
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2919
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:5622
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:338
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6240
SCIP_VAR * var
Definition: struct_lp.h:151
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9679
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7684
int SCIPsetInitializeRandomSeed(SCIP_SET *set, int initialseedvalue)
Definition: set.c:6956
int nlazycols
Definition: struct_lp.h:311
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:16550
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:351
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6534
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4038
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6099
unsigned int nlocks
Definition: struct_lp.h:254
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2819
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17342
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:433
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6517
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3338
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3879
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:907
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:112
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9704
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13696
SCIP_Longint obsoletenode
Definition: struct_lp.h:212
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:276
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:12881
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:884
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4167
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13560
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:1453
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3102
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:16774
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16228
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:5284
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
unsigned int validminmaxidx
Definition: struct_lp.h:244
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3855
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:13859
#define SCIP_ALLOC(x)
Definition: def.h:361
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12656
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6270
#define SCIPABORT()
Definition: def.h:322
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2844
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:193
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:334
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:2201
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:16339
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2475
unsigned int nonlpcolssorted
Definition: struct_lp.h:242
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16292
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16853
const char * SCIPlpiGetSolverName(void)
SCIP_Bool flushaddedcols
Definition: struct_lp.h:343
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:10349
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:16724
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:340
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:8448
int ncols
Definition: struct_lp.h:309
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2567
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4098
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:16457
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:10175
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17020
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:439
SCIP_Real objsqrnorm
Definition: struct_lp.h:280
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1321
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3565
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16314
unsigned int local
Definition: struct_lp.h:249
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5142
SCIP_Bool probing
Definition: struct_lp.h:359
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:344
SCIP_Real looseobjval
Definition: struct_lp.h:262
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7594
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6306
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3155
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:11847
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9361
SCIP_Real flushedlhs
Definition: struct_lp.h:197
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
SCIP_RETCODE SCIProwAddConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real addval)
Definition: lp.c:5515
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:5268
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:3824
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:3933
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:279
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3068
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:16660
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:726