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-2018 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  {
8512  lp->solved = FALSE;
8514  }
8515 
8516  assert(lp->nlpicols == lp->ncols);
8517  assert(lp->lpifirstchgcol == lp->nlpicols);
8518  assert(lp->nlpirows == lp->nrows);
8519  assert(lp->lpifirstchgrow == lp->nlpirows);
8520  assert(lp->nchgcols == 0);
8521  assert(lp->nchgrows == 0);
8522 #ifndef NDEBUG
8523  {
8524  int ncols;
8525  int nrows;
8526 
8527  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8528  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8529  assert(ncols == lp->ncols);
8530  assert(nrows == lp->nrows);
8531  }
8532 #endif
8533 
8534  return SCIP_OKAY;
8535 }
8536 
8537 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8539  SCIP_LP* lp, /**< current LP data */
8540  SCIP_SET* set /**< global SCIP settings */
8541  )
8542 {
8543 #ifndef NDEBUG
8544  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8545 #endif
8546  int i;
8547 
8548  assert(lp != NULL);
8549 
8550 #ifndef NDEBUG
8551  /* check, if there are really no column or row deletions or coefficient changes left */
8552  while( lp->lpifirstchgcol < lp->nlpicols
8553  && lp->lpifirstchgcol < lp->ncols
8554  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8555  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8556  {
8557  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8558  lp->lpifirstchgcol++;
8559  }
8560  assert(lp->nlpicols == lp->lpifirstchgcol);
8561 
8562  while( lp->lpifirstchgrow < lp->nlpirows
8563  && lp->lpifirstchgrow < lp->nrows
8564  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8565  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8566  {
8567  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8568  lp->lpifirstchgrow++;
8569  }
8570  assert(lp->nlpirows == lp->lpifirstchgrow);
8571 #endif
8572 
8573  lp->lpifirstchgcol = lp->nlpicols;
8574  lp->lpifirstchgrow = lp->nlpirows;
8575 
8576  /* check, if there are really no column or row additions left */
8577  assert(lp->ncols == lp->nlpicols);
8578  assert(lp->nrows == lp->nlpirows);
8579 
8580  /* mark the changed columns to be unchanged, and check, if this is really correct */
8581  for( i = 0; i < lp->nchgcols; ++i )
8582  {
8583  SCIP_COL* col;
8584 
8585  col = lp->chgcols[i];
8586  assert(col != NULL);
8587  assert(col->var != NULL);
8588  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8589  assert(SCIPvarGetCol(col->var) == col);
8590 
8591  if( col->lpipos >= 0 )
8592  {
8593 #ifndef NDEBUG
8594  /* do not check consistency of data with LPI in case of LPI=none */
8595  if( !lpinone )
8596  {
8597  SCIP_Real lpiobj;
8598  SCIP_Real lpilb;
8599  SCIP_Real lpiub;
8600 
8601  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8602  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8603  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8604  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8605  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8606  assert(col->flushedobj == col->obj); /*lint !e777*/
8607  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8608  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8609  }
8610 #endif
8611  col->objchanged = FALSE;
8612  col->lbchanged = FALSE;
8613  col->ubchanged = FALSE;
8614  }
8615  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8616  }
8617  lp->nchgcols = 0;
8618 
8619  /* mark the changed rows to be unchanged, and check, if this is really correct */
8620  for( i = 0; i < lp->nchgrows; ++i )
8621  {
8622  SCIP_ROW* row;
8623 
8624  row = lp->chgrows[i];
8625  assert(row != NULL);
8626 
8627  if( row->lpipos >= 0 )
8628  {
8629 #ifndef NDEBUG
8630  /* do not check consistency of data with LPI in case of LPI=none */
8631  if( !lpinone )
8632  {
8633  SCIP_Real lpilhs;
8634  SCIP_Real lpirhs;
8635 
8636  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8637  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8638  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8639  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8640  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8641  }
8642 #endif
8643  row->lhschanged = FALSE;
8644  row->rhschanged = FALSE;
8645  }
8646  }
8647  lp->nchgrows = 0;
8648 
8649  /* mark the LP to be flushed */
8650  lp->flushed = TRUE;
8651 
8652  checkLinks(lp);
8653 
8654  return SCIP_OKAY;
8655 }
8656 
8657 
8658 
8659 
8660 /*
8661  * LP methods
8662  */
8663 
8664 /** updates link data after addition of column */
8665 static
8667  SCIP_COL* col, /**< LP column */
8668  SCIP_SET* set /**< global SCIP settings */
8669  )
8670 {
8671  SCIP_ROW* row;
8672  int i;
8673  int pos;
8674 
8675  assert(col != NULL);
8676  assert(col->lppos >= 0);
8677 
8678  /* update column arrays of all linked rows */
8679  for( i = 0; i < col->len; ++i )
8680  {
8681  pos = col->linkpos[i];
8682  if( pos >= 0 )
8683  {
8684  row = col->rows[i];
8685  assert(row != NULL);
8686  assert(row->linkpos[pos] == i);
8687  assert(row->cols[pos] == col);
8688  assert(row->nlpcols <= pos && pos < row->len);
8689 
8690  row->nlpcols++;
8691  rowSwapCoefs(row, pos, row->nlpcols-1);
8692  assert(row->cols[row->nlpcols-1] == col);
8693 
8694  /* if no swap was necessary, mark lpcols to be unsorted */
8695  if( pos == row->nlpcols-1 )
8696  row->lpcolssorted = FALSE;
8697 
8698  /* update norms */
8699  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8700  }
8701  }
8702 }
8703 
8704 /** updates link data after addition of row */
8705 static
8707  SCIP_ROW* row /**< LP row */
8708  )
8709 {
8710  SCIP_COL* col;
8711  int i;
8712  int pos;
8713 
8714  assert(row != NULL);
8715  assert(row->lppos >= 0);
8716 
8717  /* update row arrays of all linked columns */
8718  for( i = 0; i < row->len; ++i )
8719  {
8720  pos = row->linkpos[i];
8721  if( pos >= 0 )
8722  {
8723  col = row->cols[i];
8724  assert(col != NULL);
8725  assert(col->linkpos[pos] == i);
8726  assert(col->rows[pos] == row);
8727  assert(col->nlprows <= pos && pos < col->len);
8728 
8729  col->nlprows++;
8730  colSwapCoefs(col, pos, col->nlprows-1);
8731 
8732  /* if no swap was necessary, mark lprows to be unsorted */
8733  if( pos == col->nlprows-1 )
8734  col->lprowssorted = FALSE;
8735  }
8736  }
8737 }
8738 
8739 /** updates link data after removal of column */
8740 static
8742  SCIP_COL* col, /**< LP column */
8743  SCIP_SET* set /**< global SCIP settings */
8744  )
8745 {
8746  SCIP_ROW* row;
8747  int i;
8748  int pos;
8749 
8750  assert(col != NULL);
8751  assert(col->lppos == -1);
8752 
8753  /* update column arrays of all linked rows */
8754  for( i = 0; i < col->len; ++i )
8755  {
8756  pos = col->linkpos[i];
8757  if( pos >= 0 )
8758  {
8759  row = col->rows[i];
8760  assert(row != NULL);
8761  assert(row->linkpos[pos] == i);
8762  assert(row->cols[pos] == col);
8763  assert(0 <= pos && pos < row->nlpcols);
8764 
8765  /* update norms */
8766  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8767 
8768  row->nlpcols--;
8769  rowSwapCoefs(row, pos, row->nlpcols);
8770 
8771  /* if no swap was necessary, mark nonlpcols to be unsorted */
8772  if( pos == row->nlpcols )
8773  row->nonlpcolssorted = FALSE;
8774  }
8775  }
8776 }
8777 
8778 /** updates link data after removal of row */
8779 static
8781  SCIP_ROW* row /**< LP row */
8782  )
8783 {
8784  SCIP_COL* col;
8785  int i;
8786  int pos;
8787 
8788  assert(row != NULL);
8789  assert(row->lppos == -1);
8790 
8791  /* update row arrays of all linked columns */
8792  for( i = 0; i < row->len; ++i )
8793  {
8794  pos = row->linkpos[i];
8795  if( pos >= 0 )
8796  {
8797  col = row->cols[i];
8798  assert(col != NULL);
8799  assert(0 <= pos && pos < col->nlprows);
8800  assert(col->linkpos[pos] == i);
8801  assert(col->rows[pos] == row);
8802 
8803  col->nlprows--;
8804  colSwapCoefs(col, pos, col->nlprows);
8805 
8806  /* if no swap was necessary, mark lprows to be unsorted */
8807  if( pos == col->nlprows )
8808  col->nonlprowssorted = FALSE;
8809  }
8810  }
8811 }
8812 
8813 static
8815  SCIP_LP* lp, /**< LP data object */
8816  int initsize /**< initial size of the arrays */
8817  )
8818 {
8819  assert(lp != NULL);
8820  assert(lp->divechgsides == NULL);
8821  assert(lp->divechgsidetypes == NULL);
8822  assert(lp->divechgrows == NULL);
8823  assert(lp->ndivechgsides == 0);
8824  assert(lp->divechgsidessize == 0);
8825  assert(initsize > 0);
8826 
8827  lp->divechgsidessize = initsize;
8831 
8832  return SCIP_OKAY;
8833 }
8834 
8835 static
8837  SCIP_LP* lp, /**< LP data object */
8838  int minsize, /**< minimal number of elements */
8839  SCIP_Real growfact /**< growing factor */
8840  )
8841 {
8842  assert(lp != NULL);
8843  assert(lp->divechgsides != NULL);
8844  assert(lp->divechgsidetypes != NULL);
8845  assert(lp->divechgrows != NULL);
8846  assert(lp->ndivechgsides > 0);
8847  assert(lp->divechgsidessize > 0);
8848  assert(minsize > 0);
8849 
8850  if( minsize <= lp->divechgsidessize )
8851  return SCIP_OKAY;
8852 
8853  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
8857 
8858  return SCIP_OKAY;
8859 }
8860 
8861 static
8863  SCIP_LP* lp /**< LP data object */
8864  )
8865 {
8866  assert(lp != NULL);
8867  assert(lp->divechgsides != NULL);
8868  assert(lp->divechgsidetypes != NULL);
8869  assert(lp->divechgrows != NULL);
8870  assert(lp->ndivechgsides == 0);
8871  assert(lp->divechgsidessize > 0);
8872 
8876  lp->divechgsidessize = 0;
8877 }
8878 
8879 #define DIVESTACKINITSIZE 100
8880 
8881 /** creates empty LP data object */
8883  SCIP_LP** lp, /**< pointer to LP data object */
8884  SCIP_SET* set, /**< global SCIP settings */
8885  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
8886  SCIP_STAT* stat, /**< problem statistics */
8887  const char* name /**< problem name */
8888  )
8889 {
8890  SCIP_Bool success;
8891 
8892  assert(lp != NULL);
8893  assert(set != NULL);
8894  assert(stat != NULL);
8895  assert(name != NULL);
8896 
8897  SCIP_ALLOC( BMSallocMemory(lp) );
8898 
8899  /* open LP Solver interface */
8900  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
8901 
8902  (*lp)->lpicols = NULL;
8903  (*lp)->lpirows = NULL;
8904  (*lp)->chgcols = NULL;
8905  (*lp)->chgrows = NULL;
8906  (*lp)->cols = NULL;
8907  (*lp)->lazycols = NULL;
8908  (*lp)->rows = NULL;
8909  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
8910  (*lp)->lpobjval = 0.0;
8911  (*lp)->glbpseudoobjval = 0.0;
8912  (*lp)->relglbpseudoobjval = 0.0;
8913  (*lp)->glbpseudoobjvalid = TRUE;
8914  (*lp)->glbpseudoobjvalinf = 0;
8915  (*lp)->pseudoobjval = 0.0;
8916  (*lp)->relpseudoobjval = 0.0;
8917  (*lp)->pseudoobjvalid = TRUE;
8918  (*lp)->pseudoobjvalinf = 0;
8919  (*lp)->looseobjval = 0.0;
8920  (*lp)->rellooseobjval = 0.0;
8921  (*lp)->looseobjvalid = TRUE;
8922  (*lp)->looseobjvalinf = 0;
8923  (*lp)->nloosevars = 0;
8924  (*lp)->rootlpobjval = SCIP_INVALID;
8925  (*lp)->rootlooseobjval = SCIP_INVALID;
8926  (*lp)->cutoffbound = SCIPsetInfinity(set);
8927  (*lp)->objsqrnorm = 0.0;
8928  (*lp)->objsumnorm = 0.0;
8929  (*lp)->lpicolssize = 0;
8930  (*lp)->nlpicols = 0;
8931  (*lp)->lpirowssize = 0;
8932  (*lp)->nlpirows = 0;
8933  (*lp)->lpifirstchgcol = 0;
8934  (*lp)->lpifirstchgrow = 0;
8935  (*lp)->colssize = 0;
8936  (*lp)->ncols = 0;
8937  (*lp)->lazycolssize = 0;
8938  (*lp)->nlazycols = 0;
8939  (*lp)->rowssize = 0;
8940  (*lp)->nrows = 0;
8941  (*lp)->chgcolssize = 0;
8942  (*lp)->nchgcols = 0;
8943  (*lp)->chgrowssize = 0;
8944  (*lp)->nchgrows = 0;
8945  (*lp)->firstnewcol = 0;
8946  (*lp)->firstnewrow = 0;
8947  (*lp)->nremovablecols = 0;
8948  (*lp)->nremovablerows = 0;
8949  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
8950  (*lp)->validfarkaslp = -1;
8951  (*lp)->objsqrnormunreliable = FALSE;
8952  (*lp)->flushdeletedcols = FALSE;
8953  (*lp)->flushaddedcols = FALSE;
8954  (*lp)->flushdeletedrows = FALSE;
8955  (*lp)->flushaddedrows = FALSE;
8956  (*lp)->updateintegrality = TRUE;
8957  (*lp)->flushed = TRUE;
8958  (*lp)->solved = TRUE;
8959  (*lp)->primalfeasible = TRUE;
8960  (*lp)->primalchecked = TRUE;
8961  (*lp)->dualfeasible = TRUE;
8962  (*lp)->dualchecked = TRUE;
8963  (*lp)->solisbasic = FALSE;
8964  (*lp)->rootlpisrelax = TRUE;
8965  (*lp)->isrelax = TRUE;
8966  (*lp)->installing = FALSE;
8967  (*lp)->strongbranching = FALSE;
8968  (*lp)->strongbranchprobing = FALSE;
8969  (*lp)->probing = FALSE;
8970  (*lp)->diving = FALSE;
8971  (*lp)->divingobjchg = FALSE;
8972  (*lp)->divinglazyapplied = FALSE;
8973  (*lp)->divelpistate = NULL;
8974  (*lp)->divelpwasprimfeas = TRUE;
8975  (*lp)->divelpwasprimchecked = TRUE;
8976  (*lp)->divelpwasdualfeas = TRUE;
8977  (*lp)->divelpwasdualchecked = TRUE;
8978  (*lp)->divechgsides = NULL;
8979  (*lp)->divechgsidetypes = NULL;
8980  (*lp)->divechgrows = NULL;
8981  (*lp)->ndivechgsides = 0;
8982  (*lp)->divechgsidessize = 0;
8983  (*lp)->ndivingrows = 0;
8984  (*lp)->divinglpiitlim = INT_MAX;
8985  (*lp)->resolvelperror = FALSE;
8986  (*lp)->divenolddomchgs = 0;
8987  (*lp)->adjustlpval = FALSE;
8988  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
8989  (*lp)->lpifeastol = SCIPsetLpfeastol(set);
8990  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
8991  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
8992  (*lp)->lpifromscratch = FALSE;
8993  (*lp)->lpifastmip = set->lp_fastmip;
8994  (*lp)->lpiscaling = set->lp_scaling;
8995  (*lp)->lpipresolving = set->lp_presolving;
8996  (*lp)->lpilpinfo = set->disp_lpinfo;
8997  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
8998  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
8999  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9000  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9001  (*lp)->lpiitlim = INT_MAX;
9002  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9003  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9004  (*lp)->lpithreads = set->lp_threads;
9005  (*lp)->lpitiming = (int) set->time_clocktype;
9006  (*lp)->lpirandomseed = set->random_randomseed;
9007  (*lp)->storedsolvals = NULL;
9008 
9009  /* allocate arrays for diving */
9011 
9012  /* set default parameters in LP solver */
9013  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9014  if( !success )
9015  {
9016  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9017  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9019  }
9020  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9021  (*lp)->lpihasfeastol = success;
9022  if( !success )
9023  {
9024  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9025  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9027  }
9028  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9029  (*lp)->lpihasdualfeastol = success;
9030  if( !success )
9031  {
9032  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9033  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9035  }
9036  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9037  (*lp)->lpihasbarrierconvtol = success;
9038  if( !success )
9039  {
9040  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9041  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9043  }
9044  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9045  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9046  (*lp)->lpihasfastmip = success;
9047  if( !success )
9048  {
9049  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9050  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9052  }
9053  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9054  (*lp)->lpihasscaling = success;
9055  if( !success )
9056  {
9057  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9058  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9060  }
9061  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9062  (*lp)->lpihaspresolving = success;
9063  if( !success )
9064  {
9065  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9066  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9068  }
9069  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9070  if( !success )
9071  {
9072  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9073  "LP Solver <%s>: clock type cannot be set\n",
9075  }
9076  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9077  if( !success )
9078  {
9079  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9080  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9082  }
9083  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9084  if( !success )
9085  {
9086  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9087  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9089  }
9090  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9091  if( !success )
9092  {
9093  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9094  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9096  }
9097  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9098  (*lp)->lpihasrowrep = success;
9099  if( !success )
9100  {
9101  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9102  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9104  }
9105  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9106  (*lp)->lpihaspolishing = success;
9107  if( !success )
9108  {
9109  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9110  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9112  }
9113  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9114  (*lp)->lpihasrefactor = success;
9115  if( !success )
9116  {
9117  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9118  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9120  }
9121  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9122  if( !success )
9123  {
9124  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9125  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9127  }
9128  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9129  if( !success )
9130  {
9131  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9132  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9134  }
9135  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9136  if( (*lp)->lpirandomseed != 0 )
9137  {
9138  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9139  if( !success )
9140  {
9141  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9142  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9144  }
9145  }
9146 
9147  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9148  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9149  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9150  {
9151  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9152  return SCIP_PARAMETERWRONGVAL;
9153  }
9154 
9155  return SCIP_OKAY;
9156 }
9157 
9158 /** frees LP data object */
9160  SCIP_LP** lp, /**< pointer to LP data object */
9161  BMS_BLKMEM* blkmem, /**< block memory */
9162  SCIP_SET* set, /**< global SCIP settings */
9163  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9164  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9165  )
9166 {
9167  int i;
9168 
9169  assert(lp != NULL);
9170  assert(*lp != NULL);
9171 
9172  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9173 
9174  freeDiveChgSideArrays(*lp);
9175 
9176  /* release LPI rows */
9177  for( i = 0; i < (*lp)->nlpirows; ++i )
9178  {
9179  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9180  }
9181 
9182  if( (*lp)->lpi != NULL )
9183  {
9184  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9185  }
9186 
9187  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9188  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9189  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9190  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9191  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9192  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9193  BMSfreeMemoryArrayNull(&(*lp)->cols);
9194  BMSfreeMemoryArrayNull(&(*lp)->rows);
9195  BMSfreeMemory(lp);
9196 
9197  return SCIP_OKAY;
9198 }
9199 
9200 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9201  * changes to the LP solver
9202  */
9204  SCIP_LP* lp, /**< LP data */
9205  BMS_BLKMEM* blkmem, /**< block memory */
9206  SCIP_SET* set, /**< global SCIP settings */
9207  SCIP_STAT* stat, /**< problem statistics */
9208  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9209  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9210  )
9211 {
9212  assert(stat != NULL);
9213 
9214  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9215  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9216 
9217  /* mark the empty LP to be solved */
9219  lp->lpobjval = 0.0;
9220  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9221  lp->validfarkaslp = -1;
9222  lp->solved = TRUE;
9223  lp->primalfeasible = TRUE;
9224  lp->primalchecked = TRUE;
9225  lp->dualfeasible = TRUE;
9226  lp->dualchecked = TRUE;
9227  lp->solisbasic = FALSE;
9229 
9230  return SCIP_OKAY;
9231 }
9232 
9233 /** adds a column to the LP */
9235  SCIP_LP* lp, /**< LP data */
9236  SCIP_SET* set, /**< global SCIP settings */
9237  SCIP_COL* col, /**< LP column */
9238  int depth /**< depth in the tree where the column addition is performed */
9239  )
9240 {
9241  assert(lp != NULL);
9242  assert(!lp->diving);
9243  assert(col != NULL);
9244  assert(col->len == 0 || col->rows != NULL);
9245  assert(col->lppos == -1);
9246  assert(col->var != NULL);
9247  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9248  assert(SCIPvarGetCol(col->var) == col);
9249  assert(SCIPvarIsIntegral(col->var) == col->integral);
9250 
9251  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9252 #ifdef SCIP_DEBUG
9253  {
9254  int i;
9255  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9256  for( i = 0; i < col->len; ++i )
9257  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9258  SCIPsetDebugMsgPrint(set, "\n");
9259  }
9260 #endif
9261 
9262  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9263  lp->cols[lp->ncols] = col;
9264  col->lppos = lp->ncols;
9265  col->lpdepth = depth;
9266  col->age = 0;
9267  lp->ncols++;
9268  if( col->removable )
9269  lp->nremovablecols++;
9270 
9271  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9272  {
9273  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9274  lp->lazycols[lp->nlazycols] = col;
9275  lp->nlazycols++;
9276  }
9277 
9278  /* mark the current LP unflushed */
9279  lp->flushed = FALSE;
9280 
9281  /* update column arrays of all linked rows */
9282  colUpdateAddLP(col, set);
9283 
9284  /* update the objective function vector norms */
9285  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9286 
9287  checkLinks(lp);
9288 
9289  return SCIP_OKAY;
9290 }
9291 
9292 /** adds a row to the LP and captures it */
9294  SCIP_LP* lp, /**< LP data */
9295  BMS_BLKMEM* blkmem, /**< block memory buffers */
9296  SCIP_SET* set, /**< global SCIP settings */
9297  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9298  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9299  SCIP_ROW* row, /**< LP row */
9300  int depth /**< depth in the tree where the row addition is performed */
9301  )
9302 {
9303  assert(lp != NULL);
9304  assert(row != NULL);
9305  assert(row->len == 0 || row->cols != NULL);
9306  assert(row->lppos == -1);
9307 
9308  SCIProwCapture(row);
9309  SCIProwLock(row);
9310 
9311  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9312 #ifdef SCIP_DEBUG
9313  {
9314  int i;
9315  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9316  for( i = 0; i < row->len; ++i )
9317  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9318  if( !SCIPsetIsZero(set, row->constant) )
9319  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9320  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9321  }
9322 #endif
9323 
9324  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9325  lp->rows[lp->nrows] = row;
9326  row->lppos = lp->nrows;
9327  row->lpdepth = depth;
9328  row->age = 0;
9329  lp->nrows++;
9330  if( row->removable )
9331  lp->nremovablerows++;
9332 
9333  /* mark the current LP unflushed */
9334  lp->flushed = FALSE;
9335 
9336  /* update row arrays of all linked columns */
9337  rowUpdateAddLP(row);
9338 
9339  checkLinks(lp);
9340 
9341  rowCalcNorms(row, set);
9342 
9343  /* check, if row addition to LP events are tracked
9344  * if so, issue ROWADDEDLP event
9345  */
9346  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9347  {
9348  SCIP_EVENT* event;
9349 
9350  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9351  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9352  }
9353 
9354  return SCIP_OKAY;
9355 }
9356 
9357 
9358 #ifndef NDEBUG
9359 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9360  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9361  * the lazycols array
9362  */
9363 static
9365  SCIP_LP* lp, /**< LP data */
9366  SCIP_SET* set /**< global SCIP settings */
9367  )
9368 {
9369  SCIP_Bool contained;
9370  int c;
9371  int i;
9372 
9373  assert(lp != NULL);
9374 
9375  /* check if each column in the lazy column array has a counter part in the column array */
9376  for( i = 0; i < lp->nlazycols; ++i )
9377  {
9378  /* check if each lazy column has at least on lazy bound */
9379  assert(lp->lazycols[i] != NULL);
9380  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9381 
9382  contained = FALSE;
9383  for( c = 0; c < lp->ncols; ++c )
9384  {
9385  if( lp->lazycols[i] == lp->cols[c] )
9386  {
9387  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9388  contained = TRUE;
9389  }
9390  }
9391  assert(contained);
9392  }
9393 
9394  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9395  * array */
9396  for( c = 0; c < lp->ncols; ++c )
9397  {
9398  contained = FALSE;
9399  assert(lp->cols[c] != NULL);
9400 
9401  for( i = 0; i < lp->nlazycols; ++i )
9402  {
9403  if( lp->lazycols[i] == lp->cols[c] )
9404  {
9405  contained = TRUE;
9406  }
9407  }
9408 
9409  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9410  }
9411 }
9412 #else
9413 #define checkLazyColArray(lp, set) /**/
9414 #endif
9415 
9416 /** removes all columns after the given number of cols from the LP */
9418  SCIP_LP* lp, /**< LP data */
9419  SCIP_SET* set, /**< global SCIP settings */
9420  int newncols /**< new number of columns in the LP */
9421  )
9422 {
9423  SCIP_COL* col;
9424  int c;
9425 
9426  assert(lp != NULL);
9427 
9428  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9429  assert(0 <= newncols);
9430  assert(newncols <= lp->ncols);
9431 
9432  if( newncols < lp->ncols )
9433  {
9434  assert(!lp->diving);
9435 
9436  for( c = lp->ncols-1; c >= newncols; --c )
9437  {
9438  col = lp->cols[c];
9439  assert(col != NULL);
9440  assert(col->len == 0 || col->rows != NULL);
9441  assert(col->var != NULL);
9442  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9443  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9444  assert(col->lppos == c);
9445 
9446  /* mark column to be removed from the LP */
9447  col->lppos = -1;
9448  col->lpdepth = -1;
9449  lp->ncols--;
9450 
9451  /* count removable columns */
9452  if( col->removable )
9453  lp->nremovablecols--;
9454 
9455  /* update column arrays of all linked rows */
9456  colUpdateDelLP(col, set);
9457 
9458  /* update the objective function vector norms */
9459  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9460  }
9461  assert(lp->ncols == newncols);
9462  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9463 
9464  /* remove columns which are deleted from the lazy column array */
9465  c = 0;
9466  while( c < lp->nlazycols )
9467  {
9468  if( lp->lazycols[c]->lppos < 0 )
9469  {
9470  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9471  lp->nlazycols--;
9472  }
9473  else
9474  c++;
9475  }
9476 
9477  /* mark the current LP unflushed */
9478  lp->flushed = FALSE;
9479 
9480  checkLazyColArray(lp, set);
9481  checkLinks(lp);
9482  }
9483  assert(lp->nremovablecols <= lp->ncols);
9484 
9485  return SCIP_OKAY;
9486 }
9487 
9488 /** removes and releases all rows after the given number of rows from the LP */
9490  SCIP_LP* lp, /**< LP data */
9491  BMS_BLKMEM* blkmem, /**< block memory */
9492  SCIP_SET* set, /**< global SCIP settings */
9493  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9494  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9495  int newnrows /**< new number of rows in the LP */
9496  )
9497 {
9498  SCIP_ROW* row;
9499  int r;
9500 
9501  assert(lp != NULL);
9502  assert(0 <= newnrows && newnrows <= lp->nrows);
9503 
9504  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9505  if( newnrows < lp->nrows )
9506  {
9507  for( r = lp->nrows-1; r >= newnrows; --r )
9508  {
9509  row = lp->rows[r];
9510  assert(row != NULL);
9511  assert(row->len == 0 || row->cols != NULL);
9512  assert(row->lppos == r);
9513 
9514  /* mark row to be removed from the LP */
9515  row->lppos = -1;
9516  row->lpdepth = -1;
9517  lp->nrows--;
9518 
9519  /* count removable rows */
9520  if( row->removable )
9521  lp->nremovablerows--;
9522 
9523  /* update row arrays of all linked columns */
9524  rowUpdateDelLP(row);
9525 
9526  SCIProwUnlock(lp->rows[r]);
9527 
9528  /* check, if row deletion events are tracked
9529  * if so, issue ROWDELETEDLP event
9530  */
9531  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9532  {
9533  SCIP_EVENT* event;
9534 
9535  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9536  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9537  }
9538 
9539  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9540  }
9541  assert(lp->nrows == newnrows);
9542  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9543 
9544  /* mark the current LP unflushed */
9545  lp->flushed = FALSE;
9546 
9547  checkLinks(lp);
9548  }
9549  assert(lp->nremovablerows <= lp->nrows);
9550 
9551  return SCIP_OKAY;
9552 }
9553 
9554 /** removes all columns and rows from LP, releases all rows */
9556  SCIP_LP* lp, /**< LP data */
9557  BMS_BLKMEM* blkmem, /**< block memory */
9558  SCIP_SET* set, /**< global SCIP settings */
9559  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9560  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9561  )
9562 {
9563  assert(lp != NULL);
9564  assert(!lp->diving);
9565 
9566  SCIPsetDebugMsg(set, "clearing LP\n");
9567  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9568  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9569 
9570  return SCIP_OKAY;
9571 }
9572 
9573 /** remembers number of columns and rows to track the newly added ones */
9575  SCIP_LP* lp /**< current LP data */
9576  )
9577 {
9578  assert(lp != NULL);
9579  assert(!lp->diving);
9580 
9581  lp->firstnewrow = lp->nrows;
9582  lp->firstnewcol = lp->ncols;
9583 }
9584 
9585 /** sets the remembered number of columns and rows to the given values */
9587  SCIP_LP* lp, /**< current LP data */
9588  int nrows, /**< number of rows to set the size marker to */
9589  int ncols /**< number of columns to set the size marker to */
9590  )
9591 {
9592  assert(lp != NULL);
9593  assert(!lp->diving);
9594 
9595  lp->firstnewrow = nrows;
9596  lp->firstnewcol = ncols;
9597 }
9598 
9599 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9601  SCIP_LP* lp, /**< LP data */
9602  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9603  )
9604 {
9605  assert(lp != NULL);
9606  assert(lp->flushed);
9607  assert(lp->solved);
9608  assert(lp->solisbasic);
9609  assert(basisind != NULL);
9610 
9611  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9612 
9613  return SCIP_OKAY;
9614 }
9615 
9616 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9618  SCIP_LP* lp, /**< LP data */
9619  int* cstat, /**< array to store column basis status, or NULL */
9620  int* rstat /**< array to store row basis status, or NULL */
9621  )
9622 {
9623  assert(lp != NULL);
9624  assert(lp->flushed);
9625  assert(lp->solved);
9626  assert(lp->solisbasic);
9627 
9628  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9629 
9630  return SCIP_OKAY;
9631 }
9632 
9633 /** gets a row from the inverse basis matrix B^-1 */
9635  SCIP_LP* lp, /**< LP data */
9636  int r, /**< row number */
9637  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9638  int* inds, /**< array to store the non-zero indices, or NULL */
9639  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9640  * (-1: if we do not store sparsity informations) */
9641  )
9642 {
9643  assert(lp != NULL);
9644  assert(lp->flushed);
9645  assert(lp->solved);
9646  assert(lp->solisbasic);
9647  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9648  assert(coef != NULL);
9649 
9650  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9651 
9652  return SCIP_OKAY;
9653 }
9654 
9655 /** gets a column from the inverse basis matrix B^-1 */
9657  SCIP_LP* lp, /**< LP data */
9658  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9659  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9660  * to get the array which links the B^-1 column numbers to the row and
9661  * column numbers of the LP! c must be between 0 and nrows-1, since the
9662  * basis has the size nrows * nrows */
9663  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9664  int* inds, /**< array to store the non-zero indices, or NULL */
9665  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9666  * (-1: if we do not store sparsity informations) */
9667  )
9668 {
9669  assert(lp != NULL);
9670  assert(lp->flushed);
9671  assert(lp->solved);
9672  assert(lp->solisbasic);
9673  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9674  assert(coef != NULL);
9675 
9676  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9677 
9678  return SCIP_OKAY;
9679 }
9680 
9681 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9683  SCIP_LP* lp, /**< LP data */
9684  int r, /**< row number */
9685  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9686  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9687  int* inds, /**< array to store the non-zero indices, or NULL */
9688  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9689  * (-1: if we do not store sparsity informations) */
9690  )
9691 {
9692  assert(lp != NULL);
9693  assert(lp->flushed);
9694  assert(lp->solved);
9695  assert(lp->solisbasic);
9696  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9697  assert(coef != NULL);
9698 
9699  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9700 
9701  return SCIP_OKAY;
9702 }
9703 
9704 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9705  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9706  */
9708  SCIP_LP* lp, /**< LP data */
9709  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9710  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9711  int* inds, /**< array to store the non-zero indices, or NULL */
9712  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9713  * (-1: if we do not store sparsity informations) */
9714  )
9715 {
9716  assert(lp != NULL);
9717  assert(lp->flushed);
9718  assert(lp->solved);
9719  assert(lp->solisbasic);
9720  assert(0 <= c && c < lp->ncols);
9721  assert(coef != NULL);
9722 
9723  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9724 
9725  return SCIP_OKAY;
9726 }
9727 
9728 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9729  * LP row are swapped in the summation
9730  */
9732  SCIP_LP* lp, /**< LP data */
9733  SCIP_SET* set, /**< global SCIP settings */
9734  SCIP_PROB* prob, /**< problem data */
9735  SCIP_Real* weights, /**< row weights in row summation */
9736  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9737  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9738  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9739  )
9740 {
9741  SCIP_ROW* row;
9742  int r;
9743  int i;
9744  int idx;
9745  SCIP_Bool lhsinfinite;
9746  SCIP_Bool rhsinfinite;
9747 
9748  assert(lp != NULL);
9749  assert(prob != NULL);
9750  assert(weights != NULL);
9751  assert(sumcoef != NULL);
9752  assert(sumlhs != NULL);
9753  assert(sumrhs != NULL);
9754 
9755  /**@todo test, if a column based summation is faster */
9756 
9757  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9758  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9759  *sumlhs = 0.0;
9760  *sumrhs = 0.0;
9761  lhsinfinite = FALSE;
9762  rhsinfinite = FALSE;
9763  for( r = 0; r < lp->nrows; ++r )
9764  {
9765  if( !SCIPsetIsZero(set, weights[r]) )
9766  {
9767  row = lp->rows[r];
9768  assert(row != NULL);
9769  assert(row->len == 0 || row->cols != NULL);
9770  assert(row->len == 0 || row->cols_index != NULL);
9771  assert(row->len == 0 || row->vals != NULL);
9772 
9773  /* add the row coefficients to the sum */
9774  for( i = 0; i < row->len; ++i )
9775  {
9776  assert(row->cols[i] != NULL);
9777  assert(row->cols[i]->var != NULL);
9778  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9779  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9780  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9781  idx = row->cols[i]->var_probindex;
9782  assert(0 <= idx && idx < prob->nvars);
9783  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9784  }
9785 
9786  /* add the row sides to the sum, depending on the sign of the weight */
9787  if( weights[r] > 0.0 )
9788  {
9789  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9790  if( !lhsinfinite )
9791  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9792  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9793  if( !rhsinfinite )
9794  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9795  }
9796  else
9797  {
9798  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9799  if( !lhsinfinite )
9800  (*sumlhs) += weights[r] * (row->rhs - row->constant);
9801  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9802  if( !rhsinfinite )
9803  (*sumrhs) += weights[r] * (row->lhs - row->constant);
9804  }
9805  }
9806  }
9807 
9808  if( lhsinfinite )
9809  *sumlhs = -SCIPsetInfinity(set);
9810  if( rhsinfinite )
9811  *sumrhs = SCIPsetInfinity(set);
9812 
9813  return SCIP_OKAY;
9814 }
9815 
9816 /** stores LP state (like basis information) into LP state object */
9818  SCIP_LP* lp, /**< LP data */
9819  BMS_BLKMEM* blkmem, /**< block memory */
9820  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9821  )
9822 {
9823  assert(lp != NULL);
9824  assert(lp->flushed);
9825  assert(lp->solved);
9826  assert(blkmem != NULL);
9827  assert(lpistate != NULL);
9828 
9829  /* check whether there is no lp */
9830  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9831  *lpistate = NULL;
9832  else
9833  {
9834  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
9835  }
9836 
9837  return SCIP_OKAY;
9838 }
9839 
9840 /** loads LP state (like basis information) into solver */
9842  SCIP_LP* lp, /**< LP data */
9843  BMS_BLKMEM* blkmem, /**< block memory */
9844  SCIP_SET* set, /**< global SCIP settings */
9845  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9846  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
9847  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
9848  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
9849  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
9850  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
9851  )
9852 {
9853  assert(lp != NULL);
9854  assert(blkmem != NULL);
9855 
9856  /* flush changes to the LP solver */
9857  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9858  assert(lp->flushed);
9859 
9860  if( lp->solved && lp->solisbasic )
9861  return SCIP_OKAY;
9862 
9863  /* set LPI state in the LP solver */
9864  if( lpistate == NULL )
9865  lp->solisbasic = FALSE;
9866  else
9867  {
9868  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
9869  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
9870  }
9871  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
9872  * flushed and solved, also, e.g., when we hit the iteration limit
9873  */
9874  lp->primalfeasible = wasprimfeas;
9875  lp->primalchecked = wasprimchecked;
9876  lp->dualfeasible = wasdualfeas;
9877  lp->dualchecked = wasdualchecked;
9878 
9879  return SCIP_OKAY;
9880 }
9881 
9882 /** frees LP state information */
9884  SCIP_LP* lp, /**< LP data */
9885  BMS_BLKMEM* blkmem, /**< block memory */
9886  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9887  )
9888 {
9889  assert(lp != NULL);
9890 
9891  if( *lpistate != NULL )
9892  {
9893  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
9894  }
9895 
9896  return SCIP_OKAY;
9897 }
9898 
9899 /** stores pricing norms into LP norms object */
9901  SCIP_LP* lp, /**< LP data */
9902  BMS_BLKMEM* blkmem, /**< block memory */
9903  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9904  )
9905 {
9906  assert(lp != NULL);
9907  assert(lp->flushed);
9908  assert(lp->solved);
9909  assert(blkmem != NULL);
9910  assert(lpinorms != NULL);
9911 
9912  /* check whether there is no lp */
9913  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9914  *lpinorms = NULL;
9915  else
9916  {
9917  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
9918  }
9919 
9920  return SCIP_OKAY;
9921 }
9922 
9923 /** loads pricing norms from LP norms object into solver */
9925  SCIP_LP* lp, /**< LP data */
9926  BMS_BLKMEM* blkmem, /**< block memory */
9927  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
9928  )
9929 {
9930  assert(lp != NULL);
9931  assert(blkmem != NULL);
9932  assert(lp->flushed);
9933 
9934  /* set LPI norms in the LP solver */
9935  if( lpinorms != NULL )
9936  {
9937  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
9938  }
9939 
9940  return SCIP_OKAY;
9941 }
9942 
9943 /** frees pricing norms information */
9945  SCIP_LP* lp, /**< LP data */
9946  BMS_BLKMEM* blkmem, /**< block memory */
9947  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9948  )
9949 {
9950  assert(lp != NULL);
9951 
9952  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
9953 
9954  return SCIP_OKAY;
9955 }
9956 
9957 /** return the current cutoff bound of the lp */
9959  SCIP_LP* lp /**< current LP data */
9960  )
9961 {
9962  assert(lp != NULL);
9963 
9964  return lp->cutoffbound;
9965 }
9966 
9967 /** sets the upper objective limit of the LP solver */
9969  SCIP_LP* lp, /**< current LP data */
9970  SCIP_SET* set, /**< global SCIP settings */
9971  SCIP_PROB* prob, /**< problem data */
9972  SCIP_Real cutoffbound /**< new upper objective limit */
9973  )
9974 {
9975  assert(lp != NULL);
9976 
9977  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
9978 
9979  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
9980  * in SCIPendDive())
9981  */
9982  if( SCIPlpDivingObjChanged(lp) )
9983  {
9984  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
9985  return SCIP_OKAY;
9986  }
9987 
9988  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
9989  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
9990  {
9991  /* mark the current solution invalid */
9992  lp->solved = FALSE;
9993  lp->lpobjval = SCIP_INVALID;
9995  }
9996  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
9997  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
9998  */
10000  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10001  {
10002  assert(lp->flushed);
10003  assert(lp->solved);
10005  }
10006 
10007  lp->cutoffbound = cutoffbound;
10008 
10009  return SCIP_OKAY;
10010 }
10011 
10012 /** returns the name of the given LP algorithm */
10013 static
10014 const char* lpalgoName(
10015  SCIP_LPALGO lpalgo /**< LP algorithm */
10016  )
10017 {
10018  switch( lpalgo )
10019  {
10021  return "primal simplex";
10023  return "dual simplex";
10024  case SCIP_LPALGO_BARRIER:
10025  return "barrier";
10027  return "barrier/crossover";
10028  default:
10029  SCIPerrorMessage("invalid LP algorithm\n");
10030  SCIPABORT();
10031  return "invalid"; /*lint !e527*/
10032  }
10033 }
10034 
10035 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10036 static
10038  SCIP_LP* lp, /**< current LP data */
10039  SCIP_SET* set, /**< global SCIP settings */
10040  SCIP_STAT* stat, /**< problem statistics */
10041  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10042  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10043  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10044  )
10045 {
10046  SCIP_Real timedelta;
10047  SCIP_RETCODE retcode;
10048  int iterations;
10049 
10050  assert(lp != NULL);
10051  assert(lp->flushed);
10052  assert(set != NULL);
10053  assert(stat != NULL);
10054  assert(lperror != NULL);
10055 
10056  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",
10057  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10058 
10059  *lperror = FALSE;
10060 
10061 #if 0 /* for debugging: write all root node LP's */
10062  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10063  {
10064  char fname[SCIP_MAXSTRLEN];
10065  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10066  SCIP_CALL( SCIPlpWrite(lp, fname) );
10067  SCIPsetDebugMsg("wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10068  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10069  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10070  }
10071 #endif
10072 
10073  /* start timing */
10074  if( lp->diving || lp->probing )
10075  {
10076  if( lp->strongbranchprobing )
10077  SCIPclockStart(stat->strongbranchtime, set);
10078  else
10079  SCIPclockStart(stat->divinglptime, set);
10080 
10081  timedelta = 0.0; /* unused for diving or probing */
10082  }
10083  else
10084  {
10085  SCIPclockStart(stat->primallptime, set);
10086  timedelta = -SCIPclockGetTime(stat->primallptime);
10087  }
10088 
10089  /* call primal simplex */
10090  retcode = SCIPlpiSolvePrimal(lp->lpi);
10091  if( retcode == SCIP_LPERROR )
10092  {
10093  *lperror = TRUE;
10094  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10095  }
10096  else
10097  {
10098  SCIP_CALL( retcode );
10099  }
10101  lp->solisbasic = TRUE;
10102 
10103  /* stop timing */
10104  if( lp->diving || lp->probing )
10105  {
10106  if( lp->strongbranchprobing )
10107  SCIPclockStop(stat->strongbranchtime, set);
10108  else
10109  SCIPclockStop(stat->divinglptime, set);
10110  }
10111  else
10112  {
10113  timedelta += SCIPclockGetTime(stat->primallptime);
10114  SCIPclockStop(stat->primallptime, set);
10115  }
10116 
10117  /* count number of iterations */
10118  SCIPstatIncrement(stat, set, lpcount);
10119  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10120  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10121  {
10122  if( !lp->strongbranchprobing )
10123  {
10124  SCIPstatIncrement(stat, set, nlps);
10125  SCIPstatAdd( stat, set, nlpiterations, iterations );
10126  }
10127  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10128  {
10129  SCIPstatIncrement(stat, set, nprimalresolvelps );
10130  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10131  }
10132  if( lp->diving || lp->probing )
10133  {
10134  if( lp->strongbranchprobing )
10135  {
10136  SCIPstatIncrement(stat, set, nsbdivinglps);
10137  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10138  }
10139  else
10140  {
10141  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10142  SCIPstatIncrement(stat, set, ndivinglps);
10143  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10144  }
10145  }
10146  else
10147  {
10148  SCIPstatIncrement(stat, set, nprimallps);
10149  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10150  }
10151  }
10152  else
10153  {
10154  if ( ! lp->diving && ! lp->probing )
10155  {
10156  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10157  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10158  }
10159 
10160  if ( keepsol && !(*lperror) )
10161  {
10162  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10163  if( lp->validsollp == stat->lpcount-1 )
10164  lp->validsollp = stat->lpcount;
10165  if( lp->validfarkaslp == stat->lpcount-1 )
10166  lp->validfarkaslp = stat->lpcount;
10167  }
10168  }
10169 
10170  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10171  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10172 
10173  return SCIP_OKAY;
10174 }
10175 
10176 /** calls LPI to perform dual simplex, measures time and counts iterations */
10177 static
10179  SCIP_LP* lp, /**< current LP data */
10180  SCIP_SET* set, /**< global SCIP settings */
10181  SCIP_STAT* stat, /**< problem statistics */
10182  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10183  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10184  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10185  )
10186 {
10187  SCIP_Real timedelta;
10188  SCIP_RETCODE retcode;
10189  int iterations;
10190 
10191  assert(lp != NULL);
10192  assert(lp->flushed);
10193  assert(set != NULL);
10194  assert(stat != NULL);
10195  assert(lperror != NULL);
10196 
10197  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",
10198  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10199 
10200  *lperror = FALSE;
10201 
10202 #if 0 /* for debugging: write all root node LP's */
10203  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10204  {
10205  char fname[SCIP_MAXSTRLEN];
10206  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10207  SCIP_CALL( SCIPlpWrite(lp, fname) );
10208  SCIPsetDebugMsg("wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10209  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10210  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10211  }
10212 #endif
10213 
10214  /* start timing */
10215  if( lp->diving || lp->probing )
10216  {
10217  if( lp->strongbranchprobing )
10218  SCIPclockStart(stat->strongbranchtime, set);
10219  else
10220  SCIPclockStart(stat->divinglptime, set);
10221 
10222  timedelta = 0.0; /* unused for diving or probing */
10223  }
10224  else
10225  {
10226  SCIPclockStart(stat->duallptime, set);
10227  timedelta = -SCIPclockGetTime(stat->duallptime);
10228  }
10229 
10230  /* call dual simplex */
10231  retcode = SCIPlpiSolveDual(lp->lpi);
10232  if( retcode == SCIP_LPERROR )
10233  {
10234  *lperror = TRUE;
10235  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10236  }
10237  else
10238  {
10239  SCIP_CALL( retcode );
10240  }
10242  lp->solisbasic = TRUE;
10243 
10244  /* stop timing */
10245  if( lp->diving || lp->probing )
10246  {
10247  if( lp->strongbranchprobing )
10248  SCIPclockStop(stat->strongbranchtime, set);
10249  else
10250  SCIPclockStop(stat->divinglptime, set);
10251  }
10252  else
10253  {
10254  timedelta += SCIPclockGetTime(stat->duallptime);
10255  SCIPclockStop(stat->duallptime, set);
10256  }
10257 
10258  /* count number of iterations */
10259  SCIPstatIncrement(stat, set, lpcount);
10260  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10261  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10262  {
10263  if( !lp->strongbranchprobing )
10264  {
10265  SCIPstatIncrement(stat, set, nlps);
10266  SCIPstatAdd(stat, set, nlpiterations, iterations);
10267  }
10268  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10269  {
10270  SCIPstatIncrement(stat, set, ndualresolvelps);
10271  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10272  }
10273  if( lp->diving || lp->probing )
10274  {
10275  if( lp->strongbranchprobing )
10276  {
10277  SCIPstatIncrement(stat, set, nsbdivinglps);
10278  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10279  }
10280  else
10281  {
10282  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10283  SCIPstatIncrement(stat, set, ndivinglps);
10284  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10285  }
10286  }
10287  else
10288  {
10289  SCIPstatIncrement(stat, set, nduallps);
10290  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10291  }
10292  }
10293  else
10294  {
10295  if ( ! lp->diving && ! lp->probing )
10296  {
10297  SCIPstatIncrement(stat, set, ndualzeroitlps);
10298  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10299  }
10300 
10301  if( keepsol && !(*lperror) )
10302  {
10303  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10304  if( lp->validsollp == stat->lpcount-1 )
10305  lp->validsollp = stat->lpcount;
10306  if( lp->validfarkaslp == stat->lpcount-1 )
10307  lp->validfarkaslp = stat->lpcount;
10308  }
10309  }
10310 
10311  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10312  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10313 
10314  return SCIP_OKAY;
10315 }
10316 
10317 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10318  *
10319  * We follow the approach of the following paper to find a lexicographically minimal optimal
10320  * solution:
10321  *
10322  * Zanette, Fischetti, Balas@n
10323  * Can pure cutting plane algorithms work?@n
10324  * IPCO 2008, Bertinoro, Italy.
10325  *
10326  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10327  * heuristic, i.e., we limit the number of components which are minimized.
10328  *
10329  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10330  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10331  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10332  * pivots that will not change the objective are allowed afterwards.
10333  *
10334  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10335  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10336  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10337  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10338  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10339  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10340  * reduced cost. We then choose the next variable and iterate.
10341  *
10342  * We stop the process once we do not find candidates or have performed a maximum number of
10343  * iterations.
10344  *
10345  * @todo Does this really produce a lexicographically minimal solution?
10346  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10347  * guarantee that these variables will not be changed in later stages? We can fix these variables
10348  * to their lower bound, but this destroys the basis.
10349  * @todo Should we use lexicographical minimization in diving/probing or not?
10350  */
10351 static
10353  SCIP_LP* lp, /**< current LP data */
10354  SCIP_SET* set, /**< global SCIP settings */
10355  SCIP_STAT* stat, /**< problem statistics */
10356  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10357  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10358  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10359  )
10360 {
10361  SCIP_Real timedelta;
10362  SCIP_RETCODE retcode;
10363  int totalIterations;
10364  int lexIterations;
10365  int iterations;
10366  int rounds;
10367 
10368  assert(lp != NULL);
10369  assert(lp->flushed);
10370  assert(set != NULL);
10371  assert(stat != NULL);
10372  assert(lperror != NULL);
10373 
10374  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",
10375  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10376 
10377  *lperror = FALSE;
10378 
10379  /* start timing */
10380  if( lp->diving || lp->probing )
10381  {
10382  if( lp->strongbranchprobing )
10383  SCIPclockStart(stat->strongbranchtime, set);
10384  else
10385  SCIPclockStart(stat->divinglptime, set);
10386 
10387  timedelta = 0.0; /* unused for diving or probing */
10388  }
10389  else
10390  {
10391  SCIPclockStart(stat->duallptime, set);
10392  timedelta = -SCIPclockGetTime(stat->duallptime);
10393  }
10394 
10395  /* call dual simplex for first lp */
10396  retcode = SCIPlpiSolveDual(lp->lpi);
10397  if( retcode == SCIP_LPERROR )
10398  {
10399  *lperror = TRUE;
10400  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10401  }
10402  else
10403  {
10404  SCIP_CALL( retcode );
10405  }
10406  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10407  totalIterations = iterations;
10408 
10409  /* stop timing */
10410  if( lp->diving || lp->probing )
10411  {
10412  if( lp->strongbranchprobing )
10413  SCIPclockStop(stat->strongbranchtime, set);
10414  else
10415  SCIPclockStop(stat->divinglptime, set);
10416  }
10417  else
10418  {
10419  timedelta += SCIPclockGetTime(stat->duallptime);
10420  SCIPclockStop(stat->duallptime, set);
10421  }
10422 
10423  /* count number of iterations */
10424  SCIPstatIncrement(stat, set, lpcount);
10425  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10426  {
10427  if( lp->strongbranchprobing )
10428  {
10429  SCIPstatAdd(stat, set, nlpiterations, iterations);
10430  }
10431  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10432  {
10433  SCIPstatIncrement(stat, set, ndualresolvelps);
10434  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10435  }
10436  if( lp->diving || lp->probing )
10437  {
10438  if( lp->strongbranchprobing )
10439  {
10440  SCIPstatIncrement(stat, set, nsbdivinglps);
10441  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10442  }
10443  else
10444  {
10445  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10446  SCIPstatIncrement(stat, set, ndivinglps);
10447  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10448  }
10449  }
10450  else
10451  {
10452  SCIPstatIncrement(stat, set, nduallps);
10453  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10454  }
10455  }
10456  else
10457  {
10458  if ( ! lp->diving && ! lp->probing )
10459  {
10460  SCIPstatIncrement(stat, set, ndualzeroitlps);
10461  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10462  }
10463  }
10464  lexIterations = 0;
10465 
10466  /* search for lexicographically minimal optimal solution */
10467  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10468  {
10469  SCIP_Bool chooseBasic;
10470  SCIP_Real* primsol;
10471  SCIP_Real* dualsol;
10472  SCIP_Real* redcost;
10473  int* cstat;
10474  int* rstat;
10475  SCIP_Real* newobj;
10476  SCIP_Real* newlb;
10477  SCIP_Real* newub;
10478  SCIP_Real* newlhs;
10479  SCIP_Real* newrhs;
10480  SCIP_Real* oldlb;
10481  SCIP_Real* oldub;
10482  SCIP_Real* oldlhs;
10483  SCIP_Real* oldrhs;
10484  SCIP_Real* oldobj;
10485  SCIP_Bool* fixedc;
10486  SCIP_Bool* fixedr;
10487  int* indcol;
10488  int* indrow;
10489  int* indallcol;
10490  int* indallrow;
10491  int nDualDeg;
10492  int r, c;
10493  int cntcol;
10494  int cntrow;
10495  int nruns;
10496  int pos;
10497 
10498  chooseBasic = set->lp_lexdualbasic;
10499 
10500  /* start timing */
10501  SCIPclockStart(stat->lexduallptime, set);
10502 
10503  /* get all solution information */
10504  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10505  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10506  if( chooseBasic )
10507  {
10508  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10509  }
10510  else
10511  primsol = NULL;
10512 
10513  /* get basic and nonbasic information */
10514  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10515  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10516 
10517  /* save bounds, lhs/rhs, and objective */
10518  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10519  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10520  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10521  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10522  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10523  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10524  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10525  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10526 
10527  /* get storage for several arrays */
10528  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10529  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10530  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10531 
10532  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10533  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10534  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10535 
10536  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10537  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10538 
10539  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10540  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10541 
10542  /* initialize: set objective to 0, get fixed variables */
10543  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10544  for( c = 0; c < lp->nlpicols; ++c )
10545  {
10546  newobj[c] = 0.0;
10547  indallcol[c] = c;
10548  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10549  fixedc[c] = TRUE;
10550  else
10551  fixedc[c] = FALSE;
10552  }
10553 
10554  /* initialize: get fixed slack variables */
10555  for( r = 0; r < lp->nlpirows; ++r )
10556  {
10557  indallrow[r] = r;
10558  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10559  fixedr[r] = TRUE;
10560  else
10561  fixedr[r] = FALSE;
10562  }
10563 
10564 #ifdef DEBUG_LEXDUAL
10565  {
10566  int j;
10567 
10568  if( !chooseBasic )
10569  {
10570  assert(primsol == NULL);
10571  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10572  }
10573  assert(primsol != NULL);
10574  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10575  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10576 
10577  for( j = 0; j < lp->nlpicols; ++j )
10578  {
10579  if( fixedc[j] )
10580  {
10581  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10582  }
10583  else
10584  {
10585  char type;
10586  switch( (SCIP_BASESTAT) cstat[j] )
10587  {
10588  case SCIP_BASESTAT_LOWER:
10589  type = 'l';
10590  break;
10591  case SCIP_BASESTAT_UPPER:
10592  type = 'u';
10593  break;
10594  case SCIP_BASESTAT_ZERO:
10595  type = 'z';
10596  break;
10597  case SCIP_BASESTAT_BASIC:
10598  type = 'b';
10599  break;
10600  default:
10601  type = '?';
10602  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10603  SCIPABORT();
10604  }
10605  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10606  }
10607  }
10608  SCIPsetDebugMsg(set, "\n\n");
10609 
10610  if( !chooseBasic )
10611  {
10612  SCIPsetFreeBufferArray(set, &primsol);
10613  assert(primsol == NULL);
10614  }
10615  }
10616 #endif
10617 
10618  /* perform lexicographic rounds */
10619  pos = -1;
10620  nruns = 0;
10621  rounds = 0;
10622  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10623  do
10624  {
10625  int oldpos;
10626 
10627  /* get current solution */
10628  if( chooseBasic )
10629  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10630  else
10631  {
10632  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10633  assert(primsol == NULL);
10634  }
10635 
10636  /* get current basis */
10637  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10638 
10639  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10640  nDualDeg = 0;
10641  cntcol = 0;
10642  oldpos = pos;
10643  pos = -1;
10644  for( c = 0; c < lp->nlpicols; ++c )
10645  {
10646  if( !fixedc[c] )
10647  {
10648  /* check whether variable is in basis */
10649  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10650  {
10651  /* store first candidate */
10652  if( pos == -1 && c > oldpos )
10653  {
10654  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10655  pos = c;
10656  }
10657  }
10658  else
10659  {
10660  /* reduced cost == 0 -> possible candidate */
10661  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10662  {
10663  ++nDualDeg;
10664  /* only if we have not yet found a candidate */
10665  if( pos == -1 && c > oldpos )
10666  {
10667  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10668  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10669  {
10670  newlb[cntcol] = oldlb[c];
10671  newub[cntcol] = oldlb[c];
10672  indcol[cntcol++] = c;
10673  fixedc[c] = TRUE;
10674  }
10675  else /* found a non-fixed candidate */
10676  {
10677  if( !chooseBasic )
10678  pos = c;
10679  }
10680  }
10681  }
10682  else
10683  {
10684  /* nonzero reduced cost -> variable can be fixed */
10685  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10686  {
10687  newlb[cntcol] = oldlb[c];
10688  newub[cntcol] = oldlb[c];
10689  }
10690  else
10691  {
10692  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10693  {
10694  newlb[cntcol] = oldub[c];
10695  newub[cntcol] = oldub[c];
10696  }
10697  else
10698  {
10699  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10700  newlb[cntcol] = 0.0;
10701  newub[cntcol] = 0.0;
10702  }
10703  }
10704  indcol[cntcol++] = c;
10705  fixedc[c] = TRUE;
10706  }
10707  }
10708  }
10709  }
10710 
10711  /* check rows */
10712  cntrow = 0;
10713  for( r = 0; r < lp->nlpirows; ++r )
10714  {
10715  if( !fixedr[r] )
10716  {
10717  /* consider only nonbasic rows */
10718  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
10719  {
10720  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
10721  if( SCIPsetIsFeasZero(set, dualsol[r]) )
10722  ++nDualDeg;
10723  else
10724  {
10725  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
10726  {
10727  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
10728  newlhs[cntrow] = oldlhs[r];
10729  newrhs[cntrow] = oldlhs[r];
10730  }
10731  else
10732  {
10733  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
10734  newlhs[cntrow] = oldrhs[r];
10735  newrhs[cntrow] = oldrhs[r];
10736  }
10737  indrow[cntrow++] = r;
10738  fixedr[r] = TRUE;
10739  }
10740  }
10741  }
10742  }
10743 
10744  if( nDualDeg > 0 && pos >= 0 )
10745  {
10746  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
10747 
10748  /* change objective */
10749  if( nruns == 0 )
10750  {
10751  /* set objective to appropriate unit vector for first run */
10752  newobj[pos] = 1.0;
10753  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
10754  }
10755  else
10756  {
10757  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
10758  SCIP_Real obj = 1.0;
10759  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
10760  }
10761 
10762  /* fix variables */
10763  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
10764  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
10765 
10766  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
10767  retcode = SCIPlpiSolvePrimal(lp->lpi);
10768  if( retcode == SCIP_LPERROR )
10769  {
10770  *lperror = TRUE;
10771  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10772  }
10773  else
10774  {
10775  SCIP_CALL( retcode );
10776  }
10777  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10778  lexIterations += iterations;
10779 
10780 #ifdef DEBUG_LEXDUAL
10781  if( iterations > 0 )
10782  {
10783  int j;
10784 
10785  if( !chooseBasic )
10786  {
10787  assert(primsol == NULL);
10788  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10789  }
10790  assert(primsol != NULL);
10791  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10792 
10793  for( j = 0; j < lp->nlpicols; ++j )
10794  {
10795  if( fixedc[j] )
10796  {
10797  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10798  }
10799  else
10800  {
10801  char cstart = '[';
10802  char cend = ']';
10803  char type;
10804 
10805  if(j == pos)
10806  {
10807  cstart = '*';
10808  cend = '*';
10809  }
10810 
10811  switch( (SCIP_BASESTAT) cstat[j] )
10812  {
10813  case SCIP_BASESTAT_LOWER:
10814  type = 'l';
10815  break;
10816  case SCIP_BASESTAT_UPPER:
10817  type = 'u';
10818  break;
10819  case SCIP_BASESTAT_ZERO:
10820  type = 'z';
10821  break;
10822  case SCIP_BASESTAT_BASIC:
10823  type = 'b';
10824  break;
10825  default:
10826  type = '?';
10827  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
10828  SCIPABORT();
10829  }
10830  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
10831  }
10832  }
10833  SCIPsetDebugMsg(set, "\n\n");
10834 
10835  if( !chooseBasic )
10836  {
10837  SCIPsetFreeBufferArray(set, &primsol);
10838  assert(primsol == NULL);
10839  }
10840  }
10841 #endif
10842 
10843  /* count only as round if iterations have been performed */
10844  if( iterations > 0 )
10845  ++rounds;
10846  ++nruns;
10847  }
10848  }
10849  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
10850 
10851  /* reset bounds, lhs/rhs, and obj */
10852  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
10853  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
10854  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
10855 
10856  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
10857  retcode = SCIPlpiSolveDual(lp->lpi);
10858  if( retcode == SCIP_LPERROR )
10859  {
10860  *lperror = TRUE;
10861  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10862  }
10863  else
10864  {
10865  SCIP_CALL( retcode );
10866  }
10867  assert(SCIPlpiIsOptimal(lp->lpi));
10868  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10869  lexIterations += iterations;
10870 
10871  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
10872 
10873  /* count number of iterations */
10874  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
10875  SCIPstatIncrement(stat, set, nlps);
10876 
10877  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10878  {
10879  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
10880  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10881  {
10882  SCIPstatIncrement(stat, set, nlexdualresolvelps);
10883  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
10884  }
10885  SCIPstatIncrement(stat, set, nlexduallps);
10886  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
10887 
10888  totalIterations += lexIterations;
10889  }
10890 
10891  /* free space */
10892  SCIPsetFreeBufferArray(set, &newobj);
10893 
10894  SCIPsetFreeBufferArray(set, &fixedr);
10895  SCIPsetFreeBufferArray(set, &fixedc);
10896 
10897  SCIPsetFreeBufferArray(set, &indallrow);
10898  SCIPsetFreeBufferArray(set, &indallcol);
10899 
10900  SCIPsetFreeBufferArray(set, &indrow);
10901  SCIPsetFreeBufferArray(set, &newrhs);
10902  SCIPsetFreeBufferArray(set, &newlhs);
10903 
10904  SCIPsetFreeBufferArray(set, &indcol);
10905  SCIPsetFreeBufferArray(set, &newub);
10906  SCIPsetFreeBufferArray(set, &newlb);
10907 
10908  SCIPsetFreeBufferArray(set, &oldobj);
10909  SCIPsetFreeBufferArray(set, &oldrhs);
10910  SCIPsetFreeBufferArray(set, &oldlhs);
10911  SCIPsetFreeBufferArray(set, &oldub);
10912  SCIPsetFreeBufferArray(set, &oldlb);
10913 
10914  SCIPsetFreeBufferArray(set, &rstat);
10915  SCIPsetFreeBufferArray(set, &cstat);
10916 
10917  SCIPsetFreeBufferArray(set, &redcost);
10918  SCIPsetFreeBufferArray(set, &dualsol);
10919  if( chooseBasic )
10920  SCIPsetFreeBufferArray(set, &primsol);
10921 
10922  /* stop timing */
10923  SCIPclockStop(stat->lexduallptime, set);
10924 
10925  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10926  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10927  }
10929  lp->solisbasic = TRUE;
10930 
10931  if( totalIterations > 0 && !lp->strongbranchprobing )
10932  SCIPstatIncrement(stat, set, nlps);
10933  else
10934  {
10935  if( keepsol && !(*lperror) )
10936  {
10937  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10938  if( lp->validsollp == stat->lpcount-1 )
10939  lp->validsollp = stat->lpcount;
10940  if( lp->validfarkaslp == stat->lpcount-1 )
10941  lp->validfarkaslp = stat->lpcount;
10942  }
10943  }
10944 
10945  return SCIP_OKAY;
10946 }
10947 
10948 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
10949 static
10951  SCIP_LP* lp, /**< current LP data */
10952  SCIP_SET* set, /**< global SCIP settings */
10953  SCIP_STAT* stat, /**< problem statistics */
10954  SCIP_Bool crossover, /**< should crossover be performed? */
10955  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10956  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10957  )
10958 {
10959  SCIP_Real timedelta;
10960  SCIP_RETCODE retcode;
10961  int iterations;
10962 
10963  assert(lp != NULL);
10964  assert(lp->flushed);
10965  assert(set != NULL);
10966  assert(stat != NULL);
10967  assert(lperror != NULL);
10968 
10969  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",
10970  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
10971  stat->nbarrierlps, stat->ndivinglps);
10972 
10973  *lperror = FALSE;
10974 
10975 #if 0 /* for debugging: write all root node LP's */
10976  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10977  {
10978  char fname[SCIP_MAXSTRLEN];
10979  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10980  SCIP_CALL( SCIPlpWrite(lp, fname) );
10981  SCIPsetDebugMsg("wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10982  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
10983  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10984  }
10985 #endif
10986 
10987  /* start timing */
10988  if( lp->diving || lp->probing )
10989  {
10990  if( lp->strongbranchprobing )
10991  SCIPclockStart(stat->strongbranchtime, set);
10992  else
10993  SCIPclockStart(stat->divinglptime, set);
10994 
10995  timedelta = 0.0; /* unused for diving or probing */
10996  }
10997  else
10998  {
10999  SCIPclockStart(stat->barrierlptime, set);
11000  timedelta = -SCIPclockGetTime(stat->duallptime);
11001  }
11002 
11003  /* call barrier algorithm */
11004  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11005  if( retcode == SCIP_LPERROR )
11006  {
11007  *lperror = TRUE;
11008  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11009  }
11010  else
11011  {
11012  SCIP_CALL( retcode );
11013  }
11015  lp->solisbasic = crossover;
11016 
11017  /* stop timing */
11018  if( lp->diving || lp->probing )
11019  {
11020  if( lp->strongbranchprobing )
11021  SCIPclockStop(stat->strongbranchtime, set);
11022  else
11023  SCIPclockStop(stat->divinglptime, set);
11024  }
11025  else
11026  {
11027  SCIPclockStop(stat->barrierlptime, set);
11028  timedelta = -SCIPclockGetTime(stat->duallptime);
11029  }
11030 
11031  /* count number of iterations */
11032  SCIPstatIncrement(stat, set, lpcount);
11033  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11034  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11035  {
11036  if( !lp->strongbranchprobing )
11037  {
11038  SCIPstatIncrement(stat, set, nlps);
11039  SCIPstatAdd(stat, set, nlpiterations, iterations);
11040  }
11041  if( lp->diving || lp->probing )
11042  {
11043  if( lp->strongbranchprobing )
11044  {
11045  SCIPstatIncrement(stat, set, nsbdivinglps);
11046  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11047  }
11048  else
11049  {
11050  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11051  SCIPstatIncrement(stat, set, ndivinglps);
11052  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11053  }
11054  }
11055  else
11056  {
11057  SCIPstatIncrement(stat, set, nbarrierlps);
11058  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11059  }
11060  }
11061  else
11062  {
11063  if ( ! lp->diving && ! lp->probing )
11064  {
11065  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11066  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11067  }
11068 
11069  if( keepsol && !(*lperror) )
11070  {
11071  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11072  if( lp->validsollp == stat->lpcount-1 )
11073  lp->validsollp = stat->lpcount;
11074  if( lp->validfarkaslp == stat->lpcount-1 )
11075  lp->validfarkaslp = stat->lpcount;
11076  }
11077  }
11078 
11079  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11080  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11081 
11082  return SCIP_OKAY;
11083 }
11084 
11085 /** solves the LP with the given algorithm */
11086 static
11088  SCIP_LP* lp, /**< current LP data */
11089  SCIP_SET* set, /**< global SCIP settings */
11090  SCIP_STAT* stat, /**< problem statistics */
11091  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11092  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11093  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11094  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11095  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11096  )
11097 {
11098  SCIP_Real lptimelimit;
11099  SCIP_Bool success;
11100 
11101  assert(lp != NULL);
11102  assert(lp->flushed);
11103  assert(lperror != NULL);
11104 
11105  /* check if a time limit is set, and set time limit for LP solver accordingly */
11106  lptimelimit = SCIPlpiInfinity(lp->lpi);
11107  if( set->istimelimitfinite )
11108  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11109 
11110  success = FALSE;
11111  if( lptimelimit > 0.0 )
11112  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11113 
11114  if( lptimelimit <= 0.0 || !success )
11115  {
11116  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11117  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11118  *timelimit = TRUE;
11119  return SCIP_OKAY;
11120  }
11121  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %f seconds\n", lpalgoName(lpalgo), lptimelimit);
11122 
11123  /* call appropriate LP algorithm */
11124  switch( lpalgo )
11125  {
11127  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, lperror) );
11128  break;
11129 
11131  /* run dual lexicographic simplex if required */
11132  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11133  {
11134  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11135  }
11136  else
11137  {
11138  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11139  }
11140  break;
11141 
11142  case SCIP_LPALGO_BARRIER:
11143  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11144  break;
11145 
11147  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11148  break;
11149 
11150  default:
11151  SCIPerrorMessage("invalid LP algorithm\n");
11152  return SCIP_INVALIDDATA;
11153  }
11154 
11155  if( !(*lperror) )
11156  {
11157  /* check for primal and dual feasibility */
11159 
11160  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11161  }
11162 
11163  return SCIP_OKAY;
11164 }
11165 
11166 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11167  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11168  */
11169 #define MAXNUMTROUBLELPMSGS 10
11170 
11171 /** prints message about numerical trouble
11172  *
11173  * If message has verblevel at most high and display/verblevel is not full,
11174  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11175  * were printed before in the current run.
11176  */
11177 static
11179  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11180  SCIP_SET* set, /**< global SCIP settings */
11181  SCIP_STAT* stat, /**< problem statistics */
11182  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11183  const char* formatstr, /**< message format string */
11184  ... /**< arguments to format string */
11185  )
11186 {
11187  va_list ap;
11188 
11189  assert(verblevel > SCIP_VERBLEVEL_NONE);
11190  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11191  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11192 
11193  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11194  {
11195  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11196  {
11197  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11199  return;
11200 
11201  /* increase count on messages with verblevel high */
11202  ++stat->nnumtroublelpmsgs ;
11203  }
11204 
11205  /* if messages wouldn't be printed, then return already */
11206  if( verblevel > set->disp_verblevel )
11207  return;
11208  }
11209 
11210  /* print common begin of message */
11211  SCIPmessagePrintInfo(messagehdlr,
11212  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11213  stat->nnodes, stat->nlps);
11214 
11215  /* print individual part of message */
11216  va_start(ap, formatstr); /*lint !e838*/
11217  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11218  va_end(ap);
11219 
11220  /* warn that further messages will be suppressed */
11221  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11222  {
11223  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11224  }
11225 
11226  /* print closing new-line */
11227  SCIPmessagePrintInfo(messagehdlr, "\n");
11228 }
11229 
11230 #define FEASTOLTIGHTFAC 0.001
11231 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11232 static
11234  SCIP_LP* lp, /**< current LP data */
11235  SCIP_SET* set, /**< global SCIP settings */
11236  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11237  SCIP_STAT* stat, /**< problem statistics */
11238  SCIP_PROB* prob, /**< problem data */
11239  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11240  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11241  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11242  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11243  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11244  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11245  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11246  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11247  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11248  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11249  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11250  )
11251 {
11252  SCIP_Bool success;
11253  SCIP_Bool success2;
11254  SCIP_Bool success3;
11255  SCIP_Bool simplex;
11256  SCIP_Bool itlimishard;
11257  SCIP_Bool usepolishing;
11258 
11259  assert(lp != NULL);
11260  assert(lp->flushed);
11261  assert(set != NULL);
11262  assert(stat != NULL);
11263  assert(lperror != NULL);
11264  assert(timelimit != NULL);
11265 
11266  *lperror = FALSE;
11267 
11268  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11269  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11270  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11271  * SCIP_LP such that we can return a primal ray
11272  */
11273  if( lp->looseobjvalinf > 0 )
11274  {
11275  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11276  return SCIP_ERROR;
11277  }
11278 
11279  /* check, whether we solve with a simplex algorithm */
11280  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11281 
11282  /* check whether the iteration limit is a hard one */
11283  itlimishard = (itlim == harditlim);
11284 
11285  /* check whether solution polishing should be used */
11286  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11287  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11288  {
11289  usepolishing = TRUE;
11290  if( lp->updateintegrality )
11291  {
11292  SCIP_CALL( lpCopyIntegrality(lp, set) );
11293  }
11294  }
11295  else
11296  usepolishing = FALSE;
11297 
11298  /* solve with given settings (usually fast but imprecise) */
11299  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11300  {
11301  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound) );
11302  }
11303  else
11304  {
11305  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) );
11306  }
11307  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11308  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * SCIPsetLpfeastol(set) : SCIPsetLpfeastol(set), &success) );
11309  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11310  &success) );
11311  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11312  : SCIPsetBarrierconvtol(set), &success) );
11313  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11314  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11315  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11316  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11317  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11318  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11319  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11320  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11321  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11322  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11323  SCIP_CALL( lpSetRandomseed(lp, SCIPsetInitializeRandomSeed(set, set->random_randomseed), &success) );
11324  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11325  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11326  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11327  resolve = FALSE; /* only the first solve should be counted as resolving call */
11328 
11329  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11330  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11331  return SCIP_OKAY;
11332  else if( !set->lp_checkstability )
11333  {
11334  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11335  if( success )
11336  {
11337  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11338  return SCIP_OKAY;
11339  }
11340  }
11341 
11342  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11343  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11344  */
11345 
11346  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11347  * do this only if the iteration limit was not exceeded in the last LP solving call
11348  */
11349  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11350  {
11351  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11352  if( success )
11353  {
11354  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11355  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11356 
11357  /* check for stability */
11358  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11359  return SCIP_OKAY;
11360  else if( !set->lp_checkstability )
11361  {
11362  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11363  if( success )
11364  {
11365  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11366  return SCIP_OKAY;
11367  }
11368  }
11369  }
11370  }
11371 
11372  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11373  * and go directly to solving the LP from scratch
11374  */
11375  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11376  {
11377  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11378  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11379  if( success )
11380  {
11381  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling", lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11382  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11383 
11384  /* check for stability */
11385  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11386  return SCIP_OKAY;
11387  else if( !set->lp_checkstability )
11388  {
11389  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11390  if( success )
11391  {
11392  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11393  return SCIP_OKAY;
11394  }
11395  }
11396 
11397  /* reset scaling */
11398  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11399  assert(success);
11400  }
11401  }
11402 
11403  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11404  * and go directly to solving the LP from scratch
11405  */
11406  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11407  {
11408  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11409  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11410  if( success )
11411  {
11412  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11413  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11414  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11415 
11416  /* check for stability */
11417  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11418  return SCIP_OKAY;
11419  else if( !set->lp_checkstability )
11420  {
11421  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11422  if( success )
11423  {
11424  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11425  return SCIP_OKAY;
11426  }
11427  }
11428 
11429  /* reset presolving */
11430  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11431  assert(success);
11432  }
11433  }
11434 
11435  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11436  * do this only if the iteration limit was not exceeded in the last LP solving call
11437  */
11438  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11439  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11440  {
11441  success = FALSE;
11442  if( !tightprimfeastol )
11443  {
11444  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11445  }
11446 
11447  success2 = FALSE;
11448  if( !tightdualfeastol )
11449  {
11451  }
11452 
11453  success3 = FALSE;
11454  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11455  {
11457  }
11458 
11459  if( success || success2 || success3 )
11460  {
11461  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance", lpalgoName(lpalgo));
11462  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11463 
11464  /* check for stability */
11465  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11466  return SCIP_OKAY;
11467  else if( !set->lp_checkstability )
11468  {
11469  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11470  if( success )
11471  {
11472  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11473  return SCIP_OKAY;
11474  }
11475  }
11476 
11477  /* reset feasibility tolerance */
11478  if( !tightprimfeastol )
11479  {
11480  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11481  }
11482  if( !tightdualfeastol )
11483  {
11484  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11485  }
11486  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11487  {
11488  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11489  }
11490  }
11491  }
11492 
11493  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11494  * the given iteration limit might be a soft one to restrict resolving calls only */
11495  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11496 
11497  /* if not already done, solve again from scratch */
11498  if( !fromscratch && simplex )
11499  {
11500  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11501  if( success )
11502  {
11503  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11504  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11505 
11506  /* check for stability */
11507  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11508  return SCIP_OKAY;
11509  else if( !set->lp_checkstability )
11510  {
11511  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11512  if( success )
11513  {
11514  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11515  return SCIP_OKAY;
11516  }
11517  }
11518  }
11519  }
11520 
11521  /* solve again, use other simplex this time */
11522  if( simplex )
11523  {
11525  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11526  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11527 
11528  /* check for stability */
11529  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11530  return SCIP_OKAY;
11531  else if( !set->lp_checkstability )
11532  {
11533  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11534  if( success )
11535  {
11536  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11537  return SCIP_OKAY;
11538  }
11539  }
11540 
11541  /* solve again with opposite scaling and other simplex */
11542  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11543  if( success )
11544  {
11545  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11546  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11547  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11548 
11549  /* check for stability */
11550  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11551  return SCIP_OKAY;
11552  else if( !set->lp_checkstability )
11553  {
11554  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11555  if( success )
11556  {
11557  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11558  return SCIP_OKAY;
11559  }
11560  }
11561 
11562  /* reset scaling */
11563  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11564  assert(success);
11565  }
11566 
11567  /* solve again with opposite presolving and other simplex */
11568  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11569  if( success )
11570  {
11571  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11572  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11573  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11574 
11575  /* check for stability */
11576  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11577  return SCIP_OKAY;
11578  else if( !set->lp_checkstability )
11579  {
11580  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11581  if( success )
11582  {
11583  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11584  return SCIP_OKAY;
11585  }
11586  }
11587 
11588  /* reset presolving */
11589  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11590  assert(success);
11591  }
11592 
11593  /* solve again with tighter feasibility tolerance, use other simplex this time */
11594  if( !tightprimfeastol || !tightdualfeastol )
11595  {
11596  success = FALSE;
11597  if( !tightprimfeastol )
11598  {
11599  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11600  }
11601 
11602  success2 = FALSE;
11603  if( !tightdualfeastol )
11604  {
11606  }
11607 
11608  if( success || success2 )
11609  {
11610  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance", lpalgoName(lpalgo));
11611  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11612 
11613  /* check for stability */
11614  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11615  return SCIP_OKAY;
11616  else if( !set->lp_checkstability )
11617  {
11618  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11619  if( success )
11620  {
11621  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11622  return SCIP_OKAY;
11623  }
11624  }
11625 
11626  /* reset feasibility tolerance */
11627  if( !tightprimfeastol )
11628  {
11629  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11630  }
11631  if( !tightdualfeastol )
11632  {
11633  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11634  }
11635  }
11636  }
11637  }
11638 
11639  /* nothing worked -- exit with an LPERROR */
11640  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11641  *lperror = TRUE;
11642 
11643  return SCIP_OKAY;
11644 }
11645 
11646 /** adjust the LP objective value if its greater/less than +/- SCIPsetInfinity() */
11647 static
11649  SCIP_LP* lp, /**< current LP data */
11650  SCIP_SET* set, /**< global SCIP settings */
11651  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11652  )
11653 {
11654  assert(lp != NULL);
11655  assert(set != NULL);
11656 
11657  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11658  {
11659  if( !lp->adjustlpval )
11660  {
11661  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11662  lp->adjustlpval = TRUE;
11663  }
11664  lp->lpobjval = SCIPsetInfinity(set);
11665  }
11666  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11667  {
11668  if( !lp->adjustlpval )
11669  {
11670  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11671  lp->adjustlpval = TRUE;
11672  }
11673  lp->lpobjval = -SCIPsetInfinity(set);
11674  }
11675 }
11676 
11677 /** solves the LP with the given algorithm and evaluates return status */
11678 static
11680  SCIP_LP* lp, /**< current LP data */
11681  SCIP_SET* set, /**< global SCIP settings */
11682  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11683  SCIP_STAT* stat, /**< problem statistics */
11684  SCIP_PROB* prob, /**< problem data */
11685  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11686  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11687  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11688  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11689  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11690  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11691  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11692  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11693  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11694  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11695  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11696  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11697  )
11698 {
11699  SCIP_Bool solvedprimal;
11700  SCIP_Bool solveddual;
11701  SCIP_Bool timelimit;
11702  int itlim;
11703 
11704  assert(lp != NULL);
11705  assert(lp->flushed);
11706  assert(set != NULL);
11707  assert(stat != NULL);
11708  assert(lperror != NULL);
11709 
11710  checkLinks(lp);
11711 
11712  solvedprimal = FALSE;
11713  solveddual = FALSE;
11714  timelimit = FALSE;
11715 
11716  /* select the basic iteration limit depending on whether this is a resolving call or not */
11717  itlim = ( resolve ? resolveitlim : harditlim );
11718 
11719  SOLVEAGAIN:
11720  /* call simplex */
11721  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11722  keepsol, &timelimit, lperror) );
11723  resolve = FALSE; /* only the first solve should be counted as resolving call */
11724  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11725  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11726 
11727  /* check, if an error occurred */
11728  if( *lperror )
11729  {
11730  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11731  lp->solved = FALSE;
11733  return SCIP_OKAY;
11734  }
11735 
11736  /* check, if a time limit was exceeded */
11737  if( timelimit )
11738  {
11739  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11740  lp->solved = TRUE;
11742  lp->lpobjval = -SCIPsetInfinity(set);
11743  return SCIP_OKAY;
11744  }
11745 
11746  /* only one should return true */
11747  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11749 
11750  /* evaluate solution status */
11751  if( SCIPlpiIsOptimal(lp->lpi) )
11752  {
11753  assert(lp->primalfeasible);
11754  assert(lp->dualfeasible);
11756  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11757  adjustLPobjval(lp, set, messagehdlr);
11758 
11759  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
11760  {
11761  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11762  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
11764  lp->lpobjval = SCIPsetInfinity(set);
11765  }
11766  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11767  * reached if the LP objective value is greater than the cutoff bound
11768  */
11770  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11771  }
11772  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11773  {
11774  assert(!lpCutoffDisabled(set));
11776  lp->lpobjval = SCIPsetInfinity(set);
11777  }
11778  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11779  {
11780  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11781  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11782  {
11783  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11784  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11785  goto SOLVEAGAIN;
11786  }
11788  lp->lpobjval = SCIPsetInfinity(set);
11789  }
11790  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11791  {
11792  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11793  if( needprimalray && !SCIPlpiHasPrimalRay(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11794  {
11795  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11796  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11797  goto SOLVEAGAIN;
11798  }
11800  lp->lpobjval = -SCIPsetInfinity(set);
11801  }
11802  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11803  {
11804  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11805  adjustLPobjval(lp, set, messagehdlr);
11807  }
11808  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11809  {
11810  lp->lpobjval = -SCIPsetInfinity(set);
11812  }
11813  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11814  {
11815  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11816  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11817  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11818  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11819  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11820  goto SOLVEAGAIN;
11821  }
11822  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11823  {
11824  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11825  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11826  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11827  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11828  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11829  goto SOLVEAGAIN;
11830  }
11831  else
11832  {
11833  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
11834  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
11836  return SCIP_LPERROR;
11837  }
11838 
11839  lp->solved = TRUE;
11840 
11841  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
11844 
11845  return SCIP_OKAY;
11846 }
11847 
11848 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
11849 static
11851  SCIP_LP* lp, /**< current LP data */
11852  BMS_BLKMEM* blkmem, /**< block memory */
11853  SCIP_SET* set, /**< global SCIP settings */
11854  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11855  SCIP_STAT* stat, /**< problem statistics */
11856  SCIP_PROB* prob, /**< problem data */
11857  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11858  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11859  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11860  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11861  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11862  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11863  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11864  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11865  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11866  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11867  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11868  )
11869 {
11870  SCIP_Bool resolve;
11871  char algo;
11872 
11873  assert(lp != NULL);
11874  assert(set != NULL);
11875  assert(lperror != NULL);
11876 
11877  /* flush changes to the LP solver */
11878  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
11879  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
11880 
11881  /* select LP algorithm to apply */
11882  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
11883  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
11884 
11885  switch( algo )
11886  {
11887  case 's':
11888  /* select simplex method */
11889  if( lp->dualfeasible || !lp->primalfeasible )
11890  {
11891  SCIPsetDebugMsg(set, "solving dual LP\n");
11892  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11893  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11894  }
11895  else
11896  {
11897  SCIPsetDebugMsg(set, "solving primal LP\n");
11898  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11899  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11900  }
11901  break;
11902 
11903  case 'p':
11904  SCIPsetDebugMsg(set, "solving primal LP\n");
11905  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11906  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11907  break;
11908 
11909  case 'd':
11910  SCIPsetDebugMsg(set, "solving dual LP\n");
11911  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11912  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11913  break;
11914 
11915  case 'b':
11916  SCIPsetDebugMsg(set, "solving barrier LP\n");
11917  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
11918  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11919  break;
11920 
11921  case 'c':
11922  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
11923  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
11924  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11925  break;
11926 
11927  default:
11928  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
11929  return SCIP_PARAMETERWRONGVAL;
11930  }
11931  assert(!(*lperror) || !lp->solved);
11932 
11933  return SCIP_OKAY;
11934 }
11935 
11936 #ifndef NDEBUG
11937 /** checks if the lazy bounds are valid */
11938 static
11940  SCIP_LP* lp, /**< LP data */
11941  SCIP_SET* set /**< global SCIP settings */
11942  )
11943 {
11944  SCIP_COL* col;
11945  int c;
11946 
11947  assert(lp->flushed);
11948 
11949  for( c = 0; c < lp->nlazycols; ++c )
11950  {
11951  col = lp->lazycols[c];
11952 
11953  /* in case lazy bounds are given, check that the primal solution satisfies them */
11954  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
11955  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
11956  }
11957 }
11958 #else
11959 #define checkLazyBounds(lp, set) /**/
11960 #endif
11961 
11962 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
11963  * diving
11964  */
11965 static
11967  SCIP_LP* lp, /**< LP data */
11968  SCIP_SET* set /**< global SCIP settings */
11969  )
11970 {
11971  SCIP_COL* col;
11972  int c;
11973 
11974  assert(lp->nlazycols > 0);
11975 
11976  /* return, if we are in diving, and bounds were already applied
11977  * or if we are not in diving and bounds were not applied
11978  */
11979  if( lp->diving == lp->divinglazyapplied )
11980  return SCIP_OKAY;
11981 
11982  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
11983  lp->diving, lp->divinglazyapplied);
11984 
11985  for( c = 0; c < lp->nlazycols; ++c )
11986  {
11987  col = lp->lazycols[c];
11988 
11989  /* if the column has a lazy lower bound, mark its lower bounds as changed */
11990  if( !SCIPsetIsInfinity(set, -col->lazylb) )
11991  {
11992  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
11993  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
11994  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11995 
11996  /* insert column in the chgcols list (if not already there) */
11997  SCIP_CALL( insertColChgcols(col, set, lp) );
11998 
11999  /* mark bound change in the column */
12000  col->lbchanged = TRUE;
12001  }
12002 
12003  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12004  if( !SCIPsetIsInfinity(set, col->lazyub) )
12005  {
12006  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
12007  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12008  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12009 
12010  /* insert column in the chgcols list (if not already there) */
12011  SCIP_CALL( insertColChgcols(col, set, lp) );
12012 
12013  /* mark bound change in the column */
12014  col->ubchanged = TRUE;
12015  }
12016  }
12017 
12018  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12019  * if not, we just removed them
12020  */
12021  lp->divinglazyapplied = lp->diving;
12022 
12023  return SCIP_OKAY;
12024 }
12025 
12026 /** returns the iteration limit for an LP resolving call */
12027 static
12029  SCIP_SET* set, /**< global SCIP settings */
12030  SCIP_STAT* stat, /**< dynamic problem statistics */
12031  int itlim /**< hard iteration limit */
12032  )
12033 {
12034  /* no limit set or average not yet reliable */
12035  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12036  return itlim;
12037  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12038  if( itlim == -1 )
12039  itlim = INT_MAX;
12040  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12041  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12042  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12043 }
12044 
12045 
12046 
12047 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12049  SCIP_LP* lp, /**< LP data */
12050  SCIP_SET* set, /**< global SCIP settings */
12051  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12052  BMS_BLKMEM* blkmem, /**< block memory buffers */
12053  SCIP_STAT* stat, /**< problem statistics */
12054  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12055  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12056  SCIP_PROB* prob, /**< problem data */
12057  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12058  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12059  * (limit is computed within the method w.r.t. the average LP iterations) */
12060  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12061  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12062  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12063  )
12064 {
12065  SCIP_RETCODE retcode;
12066  SCIP_Bool needprimalray;
12067  SCIP_Bool needdualray;
12068  int harditlim;
12069  int resolveitlim;
12070 
12071  assert(lp != NULL);
12072  assert(prob != NULL);
12073  assert(prob->nvars >= lp->ncols);
12074  assert(lperror != NULL);
12075 
12076  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12077  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12078 
12079  retcode = SCIP_OKAY;
12080  *lperror = FALSE;
12081 
12082  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12083  needprimalray = TRUE;
12084  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12085  || (set->conf_enable && set->conf_useinflp != 'o'));
12086 
12087  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12088  harditlim = (int) MIN(itlim, INT_MAX);
12089  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12090  assert(harditlim == -1 || (resolveitlim <= harditlim));
12091 
12092  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12093  * or removed from the LP (diving was ended)
12094  */
12095  if( lp->nlazycols > 0 )
12096  {
12097  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12098  * first resolve LP?
12099  */
12100  SCIP_CALL( updateLazyBounds(lp, set) );
12101  assert(lp->diving == lp->divinglazyapplied);
12102  }
12103 
12104  /* flush changes to the LP solver */
12105  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12106  assert(lp->flushed);
12107 
12108  /* 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
12109  * to run again anyway, since there seems to be some time left / the time limit was increased
12110  */
12111  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12112  {
12113  SCIP_Bool* primalfeaspointer;
12114  SCIP_Bool* dualfeaspointer;
12115  SCIP_Bool primalfeasible;
12116  SCIP_Bool dualfeasible;
12117  SCIP_Bool rayfeasible;
12118  SCIP_Bool tightprimfeastol;
12119  SCIP_Bool tightdualfeastol;
12120  SCIP_Bool fromscratch;
12121  SCIP_Bool wasfromscratch;
12122  SCIP_Longint oldnlps;
12123  int fastmip;
12124 
12125  /* set initial LP solver settings */
12126  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12127  tightprimfeastol = FALSE;
12128  tightdualfeastol = FALSE;
12129  fromscratch = FALSE;
12130  primalfeasible = FALSE;
12131  dualfeasible = FALSE;
12132  wasfromscratch = (stat->nlps == 0);
12133 
12134  SOLVEAGAIN:
12135  /* solve the LP */
12136  oldnlps = stat->nlps;
12137  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12138  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12139  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12140  assert(!(*lperror) || !lp->solved);
12141 
12142  /* check for error */
12143  if( *lperror )
12144  {
12145  retcode = SCIP_OKAY;
12146  goto TERMINATE;
12147  }
12148 
12149  /* evaluate solution status */
12150  switch( SCIPlpGetSolstat(lp) )
12151  {
12153  /* get LP solution and possibly check the solution's feasibility again */
12154  if( set->lp_checkprimfeas )
12155  {
12156  primalfeaspointer = &primalfeasible;
12157  lp->primalchecked = TRUE;
12158  }
12159  else
12160  {
12161  /* believe in the primal feasibility of the LP solution */
12162  primalfeasible = TRUE;
12163  primalfeaspointer = NULL;
12164  lp->primalchecked = FALSE;
12165  }
12166  if( set->lp_checkdualfeas )
12167  {
12168  dualfeaspointer = &dualfeasible;
12169  lp->dualchecked = TRUE;
12170  }
12171  else
12172  {
12173  /* believe in the dual feasibility of the LP solution */
12174  dualfeasible = TRUE;
12175  dualfeaspointer = NULL;
12176  lp->dualchecked = FALSE;
12177  }
12178 
12179  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12180 
12181  /* in debug mode, check that lazy bounds (if present) are not violated */
12182  checkLazyBounds(lp, set);
12183 
12184  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12185  {
12186  /* update ages and remove obsolete columns and rows from LP */
12187  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12188  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12189  {
12190  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12191  }
12192 
12193  if( !lp->solved )
12194  {
12195  /* resolve LP after removing obsolete columns and rows */
12196  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12197  aging = FALSE; /* to prevent infinite loops */
12198  goto SOLVEAGAIN;
12199  }
12200  }
12201  if( !primalfeasible || !dualfeasible )
12202  {
12204 
12205  if( (fastmip > 0) && simplex )
12206  {
12207  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12208  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12209  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12210  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12211  fastmip = 0;
12212  goto SOLVEAGAIN;
12213  }
12214  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12215  {
12216  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12217  * tolerance
12218  */
12219  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12220  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12221  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12222  tightprimfeastol = tightprimfeastol || !primalfeasible;
12223  tightdualfeastol = tightdualfeastol || !dualfeasible;
12224  goto SOLVEAGAIN;
12225  }
12226  else if( !fromscratch && !wasfromscratch && simplex )
12227  {
12228  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12229  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12230  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12231  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12232  fromscratch = TRUE;
12233  goto SOLVEAGAIN;
12234  }
12235  else
12236  {
12237  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12238  lp->solved = FALSE;
12240  *lperror = TRUE;
12241  }
12242  }
12243  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12244  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12245  lp->lpsolstat, lp->cutoffbound);
12246  break;
12247 
12249  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12250  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12251  {
12252  if( SCIPlpiHasDualRay(lp->lpi) )
12253  {
12254  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12255  }
12256  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12257  * with the primal simplex due to numerical problems) - treat this case like an LP error
12258  */
12259  else
12260  {
12261  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12262  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12263  lp->solved = FALSE;
12265  *lperror = TRUE;
12266  }
12267  }
12268  break;
12269 
12271  if( set->lp_checkprimfeas )
12272  {
12273  /* get unbounded LP solution and check the solution's feasibility again */
12274  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12275 
12276  lp->primalchecked = TRUE;
12277  }
12278  else
12279  {
12280  /* get unbounded LP solution believing in the feasibility of the LP solution */
12281  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12282 
12283  primalfeasible = TRUE;
12284  rayfeasible = TRUE;
12285  lp->primalchecked = FALSE;
12286  }
12287 
12288  /* in debug mode, check that lazy bounds (if present) are not violated */
12289  checkLazyBounds(lp, set);
12290 
12291  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12292  primalfeasible, rayfeasible);
12293 
12294  if( !primalfeasible || !rayfeasible )
12295  {
12297 
12298  if( (fastmip > 0) && simplex )
12299  {
12300  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12301  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12302  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12303  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12304  fastmip = 0;
12305  goto SOLVEAGAIN;
12306  }
12307  else if( !tightprimfeastol )
12308  {
12309  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12310  * tolerance
12311  */
12312  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12313  "(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",
12314  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12315  tightprimfeastol = TRUE;
12316  goto SOLVEAGAIN;
12317  }
12318  else if( !fromscratch && simplex )
12319  {
12320  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12321  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12322  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12323  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12324  fromscratch = TRUE;
12325  goto SOLVEAGAIN;
12326  }
12327  else
12328  {
12329  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12330  * forget about the LP at this node and mark it to be unsolved
12331  */
12332  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12333  lp->solved = FALSE;
12335  *lperror = TRUE;
12336  }
12337  }
12338 
12339  break;
12340 
12342  assert(!lpCutoffDisabled(set));
12343  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12344  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12345  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12346  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12347  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12348  * FASTMIP and solve again.
12349  */
12350  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12351  {
12352  SCIP_LPI* lpi;
12353  SCIP_Real objval;
12354 
12355  lpi = SCIPlpGetLPI(lp);
12356 
12357  assert(lpi != NULL);
12358  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12359  * the assert by using !SCIPsetIsFeasNegative()
12360  */
12361  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12362 
12363  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12364 
12365  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12366  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12367  {
12368  SCIP_Real tmpcutoff;
12369  char tmppricingchar;
12370  SCIP_LPSOLSTAT solstat;
12371 
12372  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12373 
12374  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12375  fromscratch = FALSE;
12376 
12377  /* temporarily disable cutoffbound, which also disables the objective limit */
12378  tmpcutoff = lp->cutoffbound;
12379  lp->cutoffbound = SCIPlpiInfinity(lpi);
12380 
12381  /* set lp pricing strategy to steepest edge */
12382  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12383  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12384 
12385  /* resolve LP with an iteration limit of 1 */
12386  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12387  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12388 
12389  /* reinstall old cutoff bound and lp pricing strategy */
12390  lp->cutoffbound = tmpcutoff;
12391  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12392 
12393  /* get objective value */
12394  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12395 
12396  /* get solution status for the lp */
12397  solstat = SCIPlpGetSolstat(lp);
12398  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12399 
12400  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12401  {
12402  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12403  }
12404 
12405  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12406  fastmip = 0;
12407 
12408  /* the solution is still not exceeding the objective limit and the solving process
12409  * was stopped due to time or iteration limit, solve again with fastmip turned off
12410  */
12411  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12412  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12413  {
12414  assert(!(*lperror));
12415 
12416  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12417  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12418 
12419  /* get objective value */
12420  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12421 
12422  /* get solution status for the lp */
12423  solstat = SCIPlpGetSolstat(lp);
12424 
12425  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12426  }
12427 
12428  /* check for lp errors */
12429  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12430  {
12431  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12432  lp->solved = FALSE;
12434 
12435  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12436  goto TERMINATE;
12437  }
12438 
12439  lp->solved = TRUE;
12440 
12441  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12442  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12443  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12444  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12445  {
12446  /* get LP solution and possibly check the solution's feasibility again */
12447  if( set->lp_checkprimfeas )
12448  {
12449  primalfeaspointer = &primalfeasible;
12450  lp->primalchecked = TRUE;
12451  }
12452  else
12453  {
12454  /* believe in the primal feasibility of the LP solution */
12455  primalfeasible = TRUE;
12456  primalfeaspointer = NULL;
12457  lp->primalchecked = FALSE;
12458  }
12459  if( set->lp_checkdualfeas )
12460  {
12461  dualfeaspointer = &dualfeasible;
12462  lp->dualchecked = TRUE;
12463  }
12464  else
12465  {
12466  /* believe in the dual feasibility of the LP solution */
12467  dualfeasible = TRUE;
12468  dualfeaspointer = NULL;
12469  lp->dualchecked = FALSE;
12470  }
12471 
12472  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12473 
12474  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12475  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12476  {
12477  checkLazyBounds(lp, set);
12478  }
12479 
12480  /* if objective value is larger than the cutoff bound, set solution status to objective
12481  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12482  * this was already done in the lpSolve() method
12483  */
12484  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12485  {
12487  lp->lpobjval = SCIPsetInfinity(set);
12488  }
12489 
12490  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12491  * the cutoffbound; mark the LP to be unsolved
12492  */
12493  if( !primalfeasible || !dualfeasible
12494  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12495  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12496  {
12497  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12498  lp->solved = FALSE;
12500  *lperror = TRUE;
12501  }
12502 
12503  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12504  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12505  lp->lpsolstat, lp->cutoffbound);
12506  }
12507  /* infeasible solution */
12508  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12509  {
12510  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12511  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12512  }
12513  /* unbounded solution */
12514  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12515  {
12516  if( set->lp_checkprimfeas )
12517  {
12518  /* get unbounded LP solution and check the solution's feasibility again */
12519  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12520 
12521  lp->primalchecked = TRUE;
12522  }
12523  else
12524  {
12525  /* get unbounded LP solution believing in its feasibility */
12526  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12527 
12528  primalfeasible = TRUE;
12529  rayfeasible = TRUE;
12530  lp->primalchecked = FALSE;
12531  }
12532 
12533  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12534 
12535  /* in debug mode, check that lazy bounds (if present) are not violated */
12536  checkLazyBounds(lp, set);
12537 
12538  if( !primalfeasible || !rayfeasible )
12539  {
12540  /* unbounded solution is infeasible (this can happen due to numerical problems):
12541  * forget about the LP at this node and mark it to be unsolved
12542 
12543  * @todo: like in the default LP solving evaluation, solve without fastmip,
12544  * with tighter feasibility tolerance and from scratch
12545  */
12546  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12547  lp->solved = FALSE;
12549  *lperror = TRUE;
12550  }
12551 
12552  }
12553 
12554  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12555  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12557  }
12558  else
12559  {
12560  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12561  }
12562  }
12563  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12564  {
12565  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12566  }
12567  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12568  break;
12569 
12571  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12572  break;
12573 
12575  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12576 
12577  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12578  stat->nclockskipsleft = 0;
12579  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12580  {
12581  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12582  "you might consider switching the clock type of SCIP\n");
12583  stat->status = SCIP_STATUS_TIMELIMIT;
12584  }
12585  break;
12586 
12587  case SCIP_LPSOLSTAT_ERROR:
12589  SCIPerrorMessage("error in LP solver\n");
12590  retcode = SCIP_LPERROR;
12591  goto TERMINATE;
12592 
12593  default:
12594  SCIPerrorMessage("unknown LP solution status\n");
12595  retcode = SCIP_ERROR;
12596  goto TERMINATE;
12597  }
12598  }
12599  assert(!(*lperror) || !lp->solved);
12600 
12601  TERMINATE:
12602  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12603  * may happen that we continue to solve from scratch during strong branching */
12604  if( lp->lpifromscratch )
12605  {
12606  SCIP_Bool success;
12607  (void) lpSetFromscratch(lp, FALSE, &success);
12608  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12609  }
12610 
12611  return retcode;
12612 }
12613 
12614 /** gets solution status of current LP */
12616  SCIP_LP* lp /**< current LP data */
12617  )
12618 {
12619  assert(lp != NULL);
12620  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12621 
12622  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12623 }
12624 
12625 /** gets objective value of current LP
12626  *
12627  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12628  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12629  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12630  */
12632  SCIP_LP* lp, /**< current LP data */
12633  SCIP_SET* set, /**< global SCIP settings */
12634  SCIP_PROB* prob /**< problem data */
12635  )
12636 {
12637  assert(lp != NULL);
12638  assert(lp->solved);
12639  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12640  assert(set != NULL);
12641 
12642  if( !lp->flushed )
12643  return SCIP_INVALID;
12644  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12645  return lp->lpobjval;
12646  else if( lp->looseobjvalinf > 0 )
12647  return -SCIPsetInfinity(set);
12648  else
12649  {
12650  /* recalculate the loose objective value, if needed */
12651  if( !lp->looseobjvalid )
12652  recomputeLooseObjectiveValue(lp, set, prob);
12653 
12654  return lp->lpobjval + lp->looseobjval;
12655  }
12656 }
12657 
12658 /** gets part of objective value of current LP that results from COLUMN variables only */
12660  SCIP_LP* lp /**< current LP data */
12661  )
12662 {
12663  assert(lp != NULL);
12664  assert(lp->solved);
12665 
12666  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12667 }
12668 
12669 /** gets part of objective value of current LP that results from LOOSE variables only */
12671  SCIP_LP* lp, /**< current LP data */
12672  SCIP_SET* set, /**< global SCIP settings */
12673  SCIP_PROB* prob /**< problem data */
12674  )
12675 {
12676  assert(lp != NULL);
12677  assert(lp->solved);
12678  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12679  assert(set != NULL);
12680 
12681  if( !lp->flushed )
12682  return SCIP_INVALID;
12683  else if( lp->looseobjvalinf > 0 )
12684  return -SCIPsetInfinity(set);
12685  else
12686  return getFiniteLooseObjval(lp, set, prob);
12687 }
12688 
12689 /** remembers the current LP objective value as root solution value */
12691  SCIP_LP* lp, /**< current LP data */
12692  SCIP_SET* set, /**< global SCIP settings */
12693  SCIP_PROB* prob /**< problem data */
12694  )
12695 {
12696  assert(lp != NULL);
12697 
12699  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12700 }
12701 
12702 /** invalidates the root LP solution value */
12704  SCIP_LP* lp /**< current LP data */
12705  )
12706 {
12707  assert(lp != NULL);
12708 
12709  lp->rootlpobjval = SCIP_INVALID;
12711 }
12712 
12713 /** recomputes local and global pseudo objective values */
12715  SCIP_LP* lp, /**< current LP data */
12716  SCIP_SET* set, /**< global SCIP settings */
12717  SCIP_PROB* prob /**< problem data */
12718  )
12719 {
12720  SCIP_VAR** vars;
12721  int nvars;
12722  int v;
12723 
12724  assert(lp != NULL);
12725  assert(set != NULL);
12726  assert(prob != NULL);
12727 
12728  vars = prob->vars;
12729  nvars = prob->nvars;
12730 
12731  lp->glbpseudoobjvalinf = 0;
12732  lp->glbpseudoobjval = 0.0;
12733 
12734  lp->pseudoobjvalinf = 0;
12735  lp->pseudoobjval = 0.0;
12736 
12737  for( v = 0; v < nvars; ++v )
12738  {
12739  SCIP_Real obj = SCIPvarGetObj(vars[v]);
12740 
12741  if( SCIPsetIsPositive(set, obj) )
12742  {
12743  /* update the global pseudo objective value */
12744  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
12745  ++(lp->glbpseudoobjvalinf);
12746  else
12747  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
12748 
12749  /* update the local pseudo objective value */
12750  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
12751  ++(lp->pseudoobjvalinf);
12752  else
12753  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
12754  }
12755 
12756  if( SCIPsetIsNegative(set, obj) )
12757  {
12758  /* update the global pseudo objective value */
12759  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
12760  ++(lp->glbpseudoobjvalinf);
12761  else
12762  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
12763 
12764  /* update the local pseudo objective value */
12765  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
12766  ++(lp->pseudoobjvalinf);
12767  else
12768  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
12769  }
12770  }
12771 
12772  /* the recomputed values are reliable */
12774  lp->glbpseudoobjvalid = TRUE;
12775  lp->relpseudoobjval = lp->pseudoobjval;
12776  lp->pseudoobjvalid = TRUE;
12777 }
12778 
12779 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
12780  * global bound
12781  */
12783  SCIP_LP* lp, /**< current LP data */
12784  SCIP_SET* set, /**< global SCIP settings */
12785  SCIP_PROB* prob /**< problem data */
12786  )
12787 {
12788  assert(lp != NULL);
12789  assert(lp->glbpseudoobjvalinf >= 0);
12790  assert(set != NULL);
12791 
12792  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
12793  return -SCIPsetInfinity(set);
12794  else
12795  {
12796  /* recalculate the global pseudo solution value, if needed */
12797  if( !lp->glbpseudoobjvalid )
12798  recomputeGlbPseudoObjectiveValue(lp, set, prob);
12799 
12800  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
12801  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
12802  return -SCIPsetInfinity(set);
12803 
12804  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
12805  return SCIPsetInfinity(set);
12806 
12807  return lp->glbpseudoobjval;
12808  }
12809 }
12810 
12811 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
12812  * objective function) local bound
12813  */
12815  SCIP_LP* lp, /**< current LP data */
12816  SCIP_SET* set, /**< global SCIP settings */
12817  SCIP_PROB* prob /**< problem data */
12818  )
12819 {
12820  assert(lp != NULL);
12821  assert(lp->pseudoobjvalinf >= 0);
12822  assert(set != NULL);
12823 
12824  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12825  return -SCIPsetInfinity(set);
12826  else
12827  {
12828  /* recalculate the pseudo solution value, if needed */
12829  if( !lp->pseudoobjvalid )
12830  recomputePseudoObjectiveValue(lp, set, prob);
12831 
12832  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
12833  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
12834  return -SCIPsetInfinity(set);
12835 
12836  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
12837  return SCIPsetInfinity(set);
12838 
12839  return lp->pseudoobjval;
12840  }
12841 }
12842 
12843 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
12845  SCIP_LP* lp, /**< current LP data */
12846  SCIP_SET* set, /**< global SCIP settings */
12847  SCIP_PROB* prob, /**< problem data */
12848  SCIP_VAR* var, /**< problem variable */
12849  SCIP_Real oldbound, /**< old value for bound */
12850  SCIP_Real newbound, /**< new value for bound */
12851  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12852  )
12853 {
12854  SCIP_Real pseudoobjval;
12855  int pseudoobjvalinf;
12856  SCIP_Real obj;
12857 
12858  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
12859  pseudoobjvalinf = lp->pseudoobjvalinf;
12860  obj = SCIPvarGetObj(var);
12861  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12862  {
12863  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12864  pseudoobjvalinf--;
12865  else
12866  pseudoobjval -= oldbound * obj;
12867  assert(pseudoobjvalinf >= 0);
12868  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12869  pseudoobjvalinf++;
12870  else
12871  pseudoobjval += newbound * obj;
12872  }
12873  assert(pseudoobjvalinf >= 0);
12874 
12875  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12876  return -SCIPsetInfinity(set);
12877  else
12878  return pseudoobjval;
12879 }
12880 
12881 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
12882  * perform calculations with interval arithmetic to get an exact lower bound
12883  */
12885  SCIP_LP* lp, /**< current LP data */
12886  SCIP_SET* set, /**< global SCIP settings */
12887  SCIP_VAR* var, /**< problem variable */
12888  SCIP_Real oldbound, /**< old value for bound */
12889  SCIP_Real newbound, /**< new value for bound */
12890  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12891  )
12892 {
12893  SCIP_Real pseudoobjval;
12894  int pseudoobjvalinf;
12895  SCIP_Real obj;
12896 
12897  assert(lp->pseudoobjvalid);
12898 
12899  pseudoobjval = lp->pseudoobjval;
12900  pseudoobjvalinf = lp->pseudoobjvalinf;
12901  obj = SCIPvarGetObj(var);
12902  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12903  {
12904  SCIP_INTERVAL objint;
12905  SCIP_INTERVAL bd;
12906  SCIP_INTERVAL prod;
12907  SCIP_INTERVAL psval;
12908 
12909  SCIPintervalSet(&psval, pseudoobjval);
12910  SCIPintervalSet(&objint, SCIPvarGetObj(var));
12911 
12912  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12913  pseudoobjvalinf--;
12914  else
12915  {
12916  SCIPintervalSet(&bd, oldbound);
12917  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12918  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
12919  }
12920  assert(pseudoobjvalinf >= 0);
12921  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12922  pseudoobjvalinf++;
12923  else
12924  {
12925  SCIPintervalSet(&bd, newbound);
12926  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12927  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
12928  }
12929 
12930  pseudoobjval = SCIPintervalGetInf(psval);
12931  }
12932  assert(pseudoobjvalinf >= 0);
12933 
12934  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12935  return -SCIPsetInfinity(set);
12936  else
12937  return pseudoobjval;
12938 }
12939 
12940 /** compute the objective delta due the new objective coefficient */
12941 static
12943  SCIP_SET* set, /**< global SCIP settings */
12944  SCIP_Real oldobj, /**< old objective value of variable */
12945  SCIP_Real newobj, /**< new objective value of variable */
12946  SCIP_Real lb, /**< lower bound of variable */
12947  SCIP_Real ub, /**< upper bound of variable */
12948  SCIP_Real* deltaval, /**< pointer to store the delta value */
12949  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12950  )
12951 {
12952  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
12953  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
12954  assert(!SCIPsetIsInfinity(set, lb));
12955  assert(!SCIPsetIsInfinity(set, -ub));
12956  assert(!SCIPsetIsEQ(set, oldobj, newobj));
12957 
12958  (*deltaval) = 0.0;
12959  (*deltainf) = 0;
12960 
12961  if( SCIPsetIsPositive(set, oldobj) )
12962  {
12963  /* sign of objective did not change */
12964  if( SCIPsetIsPositive(set, newobj) )
12965  {
12966  /* if the bound is finite, calculate the deltaval */
12967  if( !SCIPsetIsInfinity(set, -lb) )
12968  (*deltaval) = lb * (newobj - oldobj);
12969  }
12970  /* sign of objective did change, so the best bound does change */
12971  else if( SCIPsetIsNegative(set, newobj) )
12972  {
12973  if( SCIPsetIsInfinity(set, -lb) )
12974  {
12975  /* old best bound was infinite while new one is not */
12976  if( !SCIPsetIsInfinity(set, ub) )
12977  {
12978  (*deltainf) = -1;
12979  (*deltaval) = ub * newobj;
12980  }
12981  }
12982  else
12983  {
12984  /* new best bound is infinite while old one was not */
12985  if( SCIPsetIsInfinity(set, ub) )
12986  {
12987  (*deltainf) = 1;
12988  (*deltaval) = -lb * oldobj;
12989  }
12990  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12991  else
12992  {
12993  (*deltaval) = (ub * newobj) - (lb * oldobj);
12994  }
12995  }
12996  }
12997  /* new objective is 0.0 */
12998  else
12999  {
13000  if( SCIPsetIsInfinity(set, -lb) )
13001  (*deltainf) = -1;
13002  else
13003  (*deltaval) = -lb * oldobj;
13004  }
13005 
13006  }
13007  else if( SCIPsetIsNegative(set, oldobj) )
13008  {
13009  /* sign of objective did not change */
13010  if( SCIPsetIsNegative(set, newobj) )
13011  {
13012  /* if the bound is finite, calculate the deltaval */
13013  if( !SCIPsetIsInfinity(set, ub) )
13014  (*deltaval) = ub * (newobj - oldobj);
13015  }
13016  /* sign of objective did change, so the best bound does change */
13017  else if( SCIPsetIsPositive(set, newobj) )
13018  {
13019  if( SCIPsetIsInfinity(set, ub) )
13020  {
13021  /* old best bound was infinite while new one is not */
13022  if( !SCIPsetIsInfinity(set, -lb) )
13023  {
13024  (*deltainf) = -1;
13025  (*deltaval) = lb * newobj;
13026  }
13027  }
13028  else
13029  {
13030  /* new best bound is infinite while old one was not */
13031  if( SCIPsetIsInfinity(set, -lb) )
13032  {
13033  (*deltainf) = 1;
13034  (*deltaval) = -ub * oldobj;
13035  }
13036  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13037  else
13038  {
13039  (*deltaval) = (lb * newobj) - (ub * oldobj);
13040  }
13041  }
13042  }
13043  /* new objective is 0.0 */
13044  else
13045  {
13046  if( SCIPsetIsInfinity(set, ub) )
13047  (*deltainf) = -1;
13048  else
13049  (*deltaval) = -ub * oldobj;
13050  }
13051  }
13052  /* old objective was 0.0 */
13053  else
13054  {
13055  if( SCIPsetIsNegative(set, newobj) )
13056  {
13057  if( SCIPsetIsInfinity(set, ub) )
13058  (*deltainf) = 1;
13059  else
13060  (*deltaval) = ub * newobj;
13061  }
13062  else if( SCIPsetIsPositive(set, newobj) )
13063  {
13064  if( SCIPsetIsInfinity(set, -lb) )
13065  (*deltainf) = 1;
13066  else
13067  (*deltaval) = lb * newobj;
13068  }
13069  }
13070 }
13071 
13072 /** compute the objective delta due the new lower bound */
13073 static
13075  SCIP_SET* set, /**< global SCIP settings */
13076  SCIP_Real obj, /**< objective value of variable */
13077  SCIP_Real oldlb, /**< old lower bound of variable */
13078  SCIP_Real newlb, /**< new lower bound of variable */
13079  SCIP_Real* deltaval, /**< pointer to store the delta value */
13080  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13081  )
13082 {
13083  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13084  assert(!SCIPsetIsInfinity(set, oldlb));
13085  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13086  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13087 
13088  if( SCIPsetIsInfinity(set, -oldlb) )
13089  {
13090  if( !SCIPsetIsInfinity(set, newlb) )
13091  {
13092  (*deltainf) = -1;
13093  (*deltaval) = newlb * obj;
13094  }
13095  else
13096  {
13097  (*deltainf) = 0;
13098  (*deltaval) = 0.0;
13099  }
13100  }
13101  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13102  {
13103  (*deltainf) = 1;
13104  (*deltaval) = -oldlb * obj;
13105  }
13106  else
13107  {
13108  (*deltainf) = 0;
13109  (*deltaval) = obj * (newlb - oldlb);
13110  }
13111 }
13112 
13113 /** compute the objective delta due the new upper bound */
13114 static
13116  SCIP_SET* set, /**< global SCIP settings */
13117  SCIP_Real obj, /**< objective value of variable */
13118  SCIP_Real oldub, /**< old upper bound of variable */
13119  SCIP_Real newub, /**< new upper bound of variable */
13120  SCIP_Real* deltaval, /**< pointer to store the delta value */
13121  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13122  )
13123 {
13124  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13125  assert(!SCIPsetIsInfinity(set, -oldub));
13126  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13127  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13128 
13129  if( SCIPsetIsInfinity(set, oldub) )
13130  {
13131  if( !SCIPsetIsInfinity(set, -newub) )
13132  {
13133  (*deltainf) = -1;
13134  (*deltaval) = newub * obj;
13135  }
13136  else
13137  {
13138  (*deltainf) = 0;
13139  (*deltaval) = 0.0;
13140  }
13141  }
13142  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13143  {
13144  (*deltainf) = 1;
13145  (*deltaval) = -oldub * obj;
13146  }
13147  else
13148  {
13149  (*deltainf) = 0;
13150  (*deltaval) = obj * (newub - oldub);
13151  }
13152 }
13153 
13154 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13155 static
13157  SCIP_LP* lp, /**< current LP data */
13158  SCIP_SET* set, /**< global SCIP settings */
13159  SCIP_VAR* var, /**< problem variable that changed */
13160  SCIP_Real deltaval, /**< delta value in the objective function */
13161  int deltainf, /**< delta value for the number of variables with infinite best bound */
13162  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13163  SCIP_Bool loose, /**< should the loose objective value be updated? */
13164  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13165  )
13166 {
13167  assert(lp != NULL);
13168  assert(lp->looseobjvalinf >= 0);
13169  assert(lp->pseudoobjvalinf >= 0);
13170  assert(lp->glbpseudoobjvalinf >= 0);
13171 
13172  /* update the pseudo objective value */
13173  if( local )
13174  {
13175  lp->pseudoobjvalinf += deltainf;
13176  if( lp->pseudoobjvalid )
13177  {
13178  lp->pseudoobjval += deltaval;
13179 
13180  /* if the absolute value was increased, this is regarded as reliable,
13181  * otherwise, we check whether we can still trust the updated value
13182  */
13183  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13184  lp->relpseudoobjval = lp->pseudoobjval;
13185  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13186  lp->pseudoobjvalid = FALSE;
13187  }
13188 
13189  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13191  loose = TRUE;
13192  }
13193  /* update the loose objective value */
13194  if( loose )
13195  {
13196  lp->looseobjvalinf += deltainf;
13197 
13198  if( deltaval != 0.0 && lp->looseobjvalid )
13199  {
13200  lp->looseobjval += deltaval;
13201 
13202  /* if the absolute value was increased, this is regarded as reliable,
13203  * otherwise, we check whether we can still trust the updated value
13204  */
13205  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13206  lp->rellooseobjval = lp->looseobjval;
13207  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13208  lp->looseobjvalid = FALSE;
13209  }
13210  }
13211  /* update the root pseudo objective values */
13212  if( global )
13213  {
13214  lp->glbpseudoobjvalinf += deltainf;
13215  if( lp->glbpseudoobjvalid )
13216  {
13217  lp->glbpseudoobjval += deltaval;
13218 
13219  /* if the absolute value was increased, this is regarded as reliable,
13220  * otherwise, we check whether we can still trust the updated value
13221  */
13225  lp->glbpseudoobjvalid = FALSE;
13226  }
13227  }
13228 
13229  assert(lp->looseobjvalinf >= 0);
13230  assert(lp->pseudoobjvalinf >= 0);
13231  assert(lp->glbpseudoobjvalinf >= 0);
13232 }
13233 
13234 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13235  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13236  */
13237 static
13239  SCIP_LP* lp, /**< current LP data */
13240  SCIP_SET* set, /**< global SCIP settings */
13241  SCIP_VAR* var, /**< problem variable that changed */
13242  SCIP_Real oldobj, /**< old objective value of variable */
13243  SCIP_Real oldlb, /**< old objective value of variable */
13244  SCIP_Real oldub, /**< old objective value of variable */
13245  SCIP_Real newobj, /**< new objective value of variable */
13246  SCIP_Real newlb, /**< new objective value of variable */
13247  SCIP_Real newub /**< new objective value of variable */
13248  )
13249 {
13250  SCIP_INTERVAL deltaval;
13251  SCIP_INTERVAL bd;
13252  SCIP_INTERVAL obj;
13253  SCIP_INTERVAL prod;
13254  SCIP_INTERVAL psval;
13255  int deltainf;
13256 
13257  assert(lp != NULL);
13258  assert(lp->pseudoobjvalinf >= 0);
13259  assert(lp->looseobjvalinf >= 0);
13260  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13261  assert(!SCIPsetIsInfinity(set, oldlb));
13262  assert(!SCIPsetIsInfinity(set, -oldub));
13263  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13264  assert(!SCIPsetIsInfinity(set, newlb));
13265  assert(!SCIPsetIsInfinity(set, -newub));
13266  assert(var != NULL);
13267 
13269  {
13270  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13271  return SCIP_INVALIDDATA;
13272  }
13273 
13274  assert(SCIPvarGetProbindex(var) >= 0);
13275 
13276  SCIPintervalSet(&deltaval, 0.0);
13277  deltainf = 0;
13278 
13279  /* subtract old pseudo objective value */
13280  if( oldobj > 0.0 )
13281  {
13282  if( SCIPsetIsInfinity(set, -oldlb) )
13283  deltainf--;
13284  else
13285  {
13286  SCIPintervalSet(&bd, oldlb);
13287  SCIPintervalSet(&obj, oldobj);
13288  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13289  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13290  }
13291  }
13292  else if( oldobj < 0.0 )
13293  {
13294  if( SCIPsetIsInfinity(set, oldub) )
13295  deltainf--;
13296  else
13297  {
13298  SCIPintervalSet(&bd, oldub);
13299  SCIPintervalSet(&obj, oldobj);
13300  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13301  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13302  }
13303  }
13304 
13305  /* add new pseudo objective value */
13306  if( newobj > 0.0 )
13307  {
13308  if( SCIPsetIsInfinity(set, -newlb) )
13309  deltainf++;
13310  else
13311  {
13312  SCIPintervalSet(&bd, newlb);
13313  SCIPintervalSet(&obj, newobj);
13314  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13315  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13316  }
13317  }
13318  else if( newobj < 0.0 )
13319  {
13320  if( SCIPsetIsInfinity(set, newub) )
13321  deltainf++;
13322  else
13323  {
13324  SCIPintervalSet(&bd, newub);
13325  SCIPintervalSet(&obj, newobj);
13326  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13327  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13328  }
13329  }
13330 
13331  /* update the pseudo and loose objective values */
13332  SCIPintervalSet(&psval, lp->pseudoobjval);
13333  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13334  lp->pseudoobjval = SCIPintervalGetInf(psval);
13335  lp->pseudoobjvalinf += deltainf;
13337  {
13338  SCIPintervalSet(&psval, lp->looseobjval);
13339  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13340  lp->looseobjval = SCIPintervalGetInf(psval);
13341  lp->looseobjvalinf += deltainf;
13342  }
13343 
13344  assert(lp->pseudoobjvalinf >= 0);
13345  assert(lp->looseobjvalinf >= 0);
13346 
13347  return SCIP_OKAY;
13348 }
13349 
13350 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13352  SCIP_LP* lp, /**< current LP data */
13353  SCIP_SET* set, /**< global SCIP settings */
13354  SCIP_VAR* var, /**< problem variable that changed */
13355  SCIP_Real oldobj, /**< old objective value of variable */
13356  SCIP_Real newobj /**< new objective value of variable */
13357  )
13358 {
13359  assert(set != NULL);
13360  assert(var != NULL);
13361 
13362  if( set->misc_exactsolve )
13363  {
13364  if( oldobj != newobj ) /*lint !e777*/
13365  {
13366  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13367  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13368  }
13369  }
13370  else
13371  {
13372  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13373  {
13374  SCIP_Real deltaval;
13375  int deltainf;
13376 
13378  assert(SCIPvarGetProbindex(var) >= 0);
13379 
13380  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13381  * domain of the variable are the same
13382  */
13383  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13384  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13385 
13386  /* compute the pseudo objective delta due the new objective coefficient */
13387  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13388 
13389  /* update the local pseudo objective value */
13390  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13391 
13392  /* compute the pseudo objective delta due the new objective coefficient */
13393  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13394 
13395  /* update the global pseudo objective value */
13396  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13397  }
13398  }
13399 
13400  return SCIP_OKAY;
13401 }
13402 
13403 
13404 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13406  SCIP_LP* lp, /**< current LP data */
13407  SCIP_SET* set, /**< global SCIP settings */
13408  SCIP_VAR* var, /**< problem variable that changed */
13409  SCIP_Real oldlb, /**< old lower bound of variable */
13410  SCIP_Real newlb /**< new lower bound of variable */
13411  )
13412 {
13413  assert(set != NULL);
13414  assert(var != NULL);
13415 
13416  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13417  {
13418  SCIP_Real deltaval;
13419  int deltainf;
13420 
13421  /* compute the pseudo objective delta due the new lower bound */
13422  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13423 
13424  /* update the root pseudo objective values */
13425  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13426 
13427  }
13428 
13429  return SCIP_OKAY;
13430 }
13431 
13432 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13434  SCIP_LP* lp, /**< current LP data */
13435  SCIP_SET* set, /**< global SCIP settings */
13436  SCIP_VAR* var, /**< problem variable that changed */
13437  SCIP_Real oldlb, /**< old lower bound of variable */
13438  SCIP_Real newlb /**< new lower bound of variable */
13439  )
13440 {
13441  assert(set != NULL);
13442  assert(var != NULL);
13443 
13444  if( set->misc_exactsolve )
13445  {
13446  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13447  {
13448  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13449  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13450  }
13451  }
13452  else
13453  {
13454  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13455  {
13456  SCIP_Real deltaval;
13457  int deltainf;
13458 
13460  assert(SCIPvarGetProbindex(var) >= 0);
13461 
13462  /* compute the pseudo objective delta due the new lower bound */
13463  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13464 
13465  /* update the pseudo and loose objective values */
13466  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13467  }
13468  }
13469 
13470  return SCIP_OKAY;
13471 }
13472 
13473 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13475  SCIP_LP* lp, /**< current LP data */
13476  SCIP_SET* set, /**< global SCIP settings */
13477  SCIP_VAR* var, /**< problem variable that changed */
13478  SCIP_Real oldub, /**< old upper bound of variable */
13479  SCIP_Real newub /**< new upper bound of variable */
13480  )
13481 {
13482  assert(set != NULL);
13483  assert(var != NULL);
13484 
13485  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13486  {
13487  SCIP_Real deltaval;
13488  int deltainf;
13489 
13490  /* compute the pseudo objective delta due the new upper bound */
13491  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13492 
13493  /* update the root pseudo objective values */
13494  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13495  }
13496 
13497  return SCIP_OKAY;
13498 }
13499 
13500 /** updates current pseudo objective value for a change in a variable's upper bound */
13502  SCIP_LP* lp, /**< current LP data */
13503  SCIP_SET* set, /**< global SCIP settings */
13504  SCIP_VAR* var, /**< problem variable that changed */
13505  SCIP_Real oldub, /**< old upper bound of variable */
13506  SCIP_Real newub /**< new upper bound of variable */
13507  )
13508 {
13509  assert(set != NULL);
13510  assert(var != NULL);
13511 
13512  if( set->misc_exactsolve )
13513  {
13514  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13515  {
13516  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13517  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13518  }
13519  }
13520  else
13521  {
13522  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13523  {
13524  SCIP_Real deltaval;
13525  int deltainf;
13526 
13528  assert(SCIPvarGetProbindex(var) >= 0);
13529 
13530  /* compute the pseudo objective delta due the new upper bound */
13531  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13532 
13533  /* update the pseudo and loose objective values */
13534  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13535  }
13536  }
13537 
13538  return SCIP_OKAY;
13539 }
13540 
13541 /** informs LP, that given variable was added to the problem */
13543  SCIP_LP* lp, /**< current LP data */
13544  SCIP_SET* set, /**< global SCIP settings */
13545  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13546  )
13547 {
13548  assert(lp != NULL);
13550  assert(SCIPvarGetProbindex(var) >= 0);
13551 
13552  /* add the variable to the loose objective value sum */
13553  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13554 
13555  /* update the loose variables counter */
13557  lp->nloosevars++;
13558 
13559  return SCIP_OKAY;
13560 }
13561 
13562 /** informs LP, that given variable is to be deleted from the problem */
13564  SCIP_LP* lp, /**< current LP data */
13565  SCIP_SET* set, /**< global SCIP settings */
13566  SCIP_VAR* var /**< variable that will be deleted from the problem */
13567  )
13568 {
13569  assert(lp != NULL);
13571  assert(SCIPvarGetProbindex(var) >= 0);
13572 
13573  /* subtract the variable from the loose objective value sum */
13574  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13575 
13576  /* update the loose variables counter */
13578  {
13579  SCIPlpDecNLoosevars(lp);
13580  }
13581 
13582  return SCIP_OKAY;
13583 }
13584 
13585 /** informs LP, that given formerly loose problem variable is now a column variable */
13586 static
13588  SCIP_LP* lp, /**< current LP data */
13589  SCIP_SET* set, /**< global SCIP settings */
13590  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13591  )
13592 {
13593  SCIP_Real obj;
13594  SCIP_Real lb;
13595  SCIP_Real ub;
13596 
13597  assert(lp != NULL);
13598  assert(lp->nloosevars > 0);
13599  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13600  assert(SCIPvarGetProbindex(var) >= 0);
13601  assert(lp->looseobjvalinf >= 0);
13602 
13603  obj = SCIPvarGetObj(var);
13604 
13605  /* update loose objective value */
13606  if( SCIPsetIsPositive(set, obj) )
13607  {
13608  lb = SCIPvarGetLbLocal(var);
13609  if( SCIPsetIsInfinity(set, -lb) )
13610  lp->looseobjvalinf--;
13611  else
13612  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13613  }
13614  else if( SCIPsetIsNegative(set, obj) )
13615  {
13616  ub = SCIPvarGetUbLocal(var);
13617  if( SCIPsetIsInfinity(set, ub) )
13618  lp->looseobjvalinf--;
13619  else
13620  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13621  }
13622 
13623  SCIPlpDecNLoosevars(lp);
13624 
13625  assert(lp->looseobjvalinf >= 0);
13626 
13627  return SCIP_OKAY;
13628 }
13629 
13630 /** informs LP, that given formerly loose problem variable is now a column variable
13631  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13632  */
13633 static
13635  SCIP_LP* lp, /**< current LP data */
13636  SCIP_SET* set, /**< global SCIP settings */
13637  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13638  )
13639 {
13640  SCIP_INTERVAL bd;
13641  SCIP_INTERVAL ob;
13642  SCIP_INTERVAL prod;
13643  SCIP_INTERVAL loose;
13644  SCIP_Real obj;
13645  SCIP_Real lb;
13646  SCIP_Real ub;
13647 
13648  assert(lp != NULL);
13649  assert(lp->nloosevars > 0);
13650  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13651  assert(SCIPvarGetProbindex(var) >= 0);
13652 
13653  obj = SCIPvarGetObj(var);
13654 
13655  SCIPintervalSet(&loose, lp->looseobjval);
13656 
13657  /* update loose objective value corresponding to the deletion of variable */
13658  if( obj > 0.0 )
13659  {
13660  lb = SCIPvarGetLbLocal(var);
13661  if( SCIPsetIsInfinity(set, -lb) )
13662  lp->looseobjvalinf--;
13663  else
13664  {
13665  SCIPintervalSet(&bd, lb);
13666  SCIPintervalSet(&ob, obj);
13667  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13668  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13669  }
13670  }
13671  else if( SCIPsetIsNegative(set, obj) )
13672  {
13673  ub = SCIPvarGetUbLocal(var);
13674  if( SCIPsetIsInfinity(set, ub) )
13675  lp->looseobjvalinf--;
13676  else
13677  {
13678  SCIPintervalSet(&bd, ub);
13679  SCIPintervalSet(&ob, obj);
13680  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13681  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13682  }
13683  }
13684  lp->nloosevars--;
13685 
13686  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13687  if( lp->nloosevars == 0 )
13688  {
13689  assert(lp->looseobjvalinf == 0);
13690  lp->looseobjval = 0.0;
13691  }
13692  else
13693  lp->looseobjval = SCIPintervalGetInf(loose);
13694 
13695  return SCIP_OKAY;
13696 }
13697 
13698 /** informs LP, that given formerly loose problem variable is now a column variable */
13700  SCIP_LP* lp, /**< current LP data */
13701  SCIP_SET* set, /**< global SCIP settings */
13702  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13703  )
13704 {
13705  assert(set != NULL);
13706 
13707  if( set->misc_exactsolve )
13708  {
13709  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13710  }
13711  else
13712  {
13713  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13714  }
13715 
13716  return SCIP_OKAY;
13717 }
13718 
13719 /** informs LP, that given formerly column problem variable is now again a loose variable */
13720 static
13722  SCIP_LP* lp, /**< current LP data */
13723  SCIP_SET* set, /**< global SCIP settings */
13724  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13725  )
13726 {
13727  SCIP_Real obj;
13728  SCIP_Real lb;
13729  SCIP_Real ub;
13730 
13731  assert(lp != NULL);
13732  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13733  assert(SCIPvarGetProbindex(var) >= 0);
13734  assert(lp->looseobjvalinf >= 0);
13735 
13736  obj = SCIPvarGetObj(var);
13737 
13738  /* update loose objective value corresponding to the addition of variable */
13739  if( SCIPsetIsPositive(set, obj) )
13740  {
13741  lb = SCIPvarGetLbLocal(var);
13742  if( SCIPsetIsInfinity(set, -lb) )
13743  lp->looseobjvalinf++;
13744  else
13745  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
13746  }
13747  else if( SCIPsetIsNegative(set, obj) )
13748  {
13749  ub = SCIPvarGetUbLocal(var);
13750  if( SCIPsetIsInfinity(set, ub) )
13751  lp->looseobjvalinf++;
13752  else
13753  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
13754  }
13755  lp->nloosevars++;
13756 
13757  assert(lp->looseobjvalinf >= 0);
13758 
13759  return SCIP_OKAY;
13760 }
13761 
13762 /** informs LP, that given formerly column problem variable is now again a loose variable
13763  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13764  */
13765 static
13767  SCIP_LP* lp, /**< current LP data */
13768  SCIP_SET* set, /**< global SCIP settings */
13769  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13770  )
13771 {
13772  SCIP_INTERVAL bd;
13773  SCIP_INTERVAL ob;
13774  SCIP_INTERVAL prod;
13775  SCIP_INTERVAL loose;
13776  SCIP_Real obj;
13777  SCIP_Real lb;
13778  SCIP_Real ub;
13779 
13780  assert(lp != NULL);
13781  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13782  assert(SCIPvarGetProbindex(var) >= 0);
13783 
13784  obj = SCIPvarGetObj(var);
13785 
13786  SCIPintervalSet(&loose, lp->looseobjval);
13787 
13788  /* update loose objective value corresponding to the deletion of variable */
13789  if( obj > 0.0 )
13790  {
13791  lb = SCIPvarGetLbLocal(var);
13792  if( SCIPsetIsInfinity(set, -lb) )
13793  lp->looseobjvalinf++;
13794  else
13795  {
13796  SCIPintervalSet(&bd, lb);
13797  SCIPintervalSet(&ob, obj);
13798  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13799  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
13800  }
13801  }
13802  else if( SCIPsetIsNegative(set, obj) )
13803  {
13804  ub = SCIPvarGetUbLocal(var);
13805  if( SCIPsetIsInfinity(set, ub) )
13806  lp->looseobjvalinf++;
13807  else
13808  {
13809  SCIPintervalSet(&bd, ub);
13810  SCIPintervalSet(&ob, obj);
13811  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13812  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
13813  }
13814  }
13815  lp->nloosevars++;
13816 
13817  lp->looseobjval = SCIPintervalGetInf(loose);
13818 
13819  return SCIP_OKAY;
13820 }
13821 
13822 /** informs LP, that given formerly column problem variable is now again a loose variable */
13824  SCIP_LP* lp, /**< current LP data */
13825  SCIP_SET* set, /**< global SCIP settings */
13826  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13827  )
13828 {
13829  assert(set != NULL);
13830 
13831  if( set->misc_exactsolve )
13832  {
13833  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
13834  }
13835  else
13836  {
13837  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
13838  }
13839 
13840  return SCIP_OKAY;
13841 }
13842 
13843 /** decrease the number of loose variables by one */
13845  SCIP_LP* lp /**< current LP data */
13846  )
13847 {
13848  assert(lp != NULL);
13849  assert(lp->nloosevars > 0);
13850 
13851  lp->nloosevars--;
13852 
13853  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13854  if( lp->nloosevars == 0 )
13855  {
13856  assert(lp->looseobjvalinf == 0);
13857  lp->looseobjval = 0.0;
13858  }
13859 }
13860 
13861 /** stores the LP solution in the columns and rows */
13863  SCIP_LP* lp, /**< current LP data */
13864  SCIP_SET* set, /**< global SCIP settings */
13865  SCIP_STAT* stat, /**< problem statistics */
13866  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
13867  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
13868  )
13869 {
13870  SCIP_COL** lpicols;
13871  SCIP_ROW** lpirows;
13872  SCIP_Real* primsol;
13873  SCIP_Real* dualsol;
13874  SCIP_Real* activity;
13875  SCIP_Real* redcost;
13876  SCIP_Real primalbound;
13877  SCIP_Real dualbound;
13878  SCIP_Bool stillprimalfeasible;
13879  SCIP_Bool stilldualfeasible;
13880  int* cstat;
13881  int* rstat;
13882  SCIP_Longint lpcount;
13883  int nlpicols;
13884  int nlpirows;
13885  int c;
13886  int r;
13887 
13888  assert(lp != NULL);
13889  assert(lp->flushed);
13890  assert(lp->solved);
13891  assert(set != NULL);
13892  assert(stat != NULL);
13893  assert(lp->validsollp <= stat->lpcount);
13894 
13895  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
13896  * corresponding flag immediately to FALSE to skip all checks
13897  */
13898  if( primalfeasible == NULL )
13899  stillprimalfeasible = FALSE;
13900  else
13901  {
13902  *primalfeasible = TRUE;
13903  stillprimalfeasible = TRUE;
13904  }
13905  if( dualfeasible == NULL )
13906  stilldualfeasible = FALSE;
13907  else
13908  {
13909  *dualfeasible = TRUE;
13910  stilldualfeasible = TRUE;
13911  }
13912 
13913  /* check if the values are already calculated */
13914  if( lp->validsollp == stat->lpcount )
13915  return SCIP_OKAY;
13916  lp->validsollp = stat->lpcount;
13917 
13918  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
13919  stat->lpcount, SCIPlpGetSolstat(lp));
13920 
13921  lpicols = lp->lpicols;
13922  lpirows = lp->lpirows;
13923  nlpicols = lp->nlpicols;
13924  nlpirows = lp->nlpirows;
13925  lpcount = stat->lpcount;
13926 
13927  /* get temporary memory */
13928  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
13929  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
13930  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
13931  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
13932  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
13933  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
13934 
13935  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
13936  if( lp->solisbasic )
13937  {
13938  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
13939  }
13940  else
13941  {
13942  BMSclearMemoryArray(cstat, nlpicols);
13943  BMSclearMemoryArray(rstat, nlpirows);
13944  }
13945 
13946  primalbound = 0.0;
13947  dualbound = 0.0;
13948 
13949  /* copy primal solution and reduced costs into columns */
13950  for( c = 0; c < nlpicols; ++c )
13951  {
13952  assert( 0 <= cstat[c] && cstat[c] < 4 );
13953  lpicols[c]->primsol = primsol[c];
13954  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
13955  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
13956  lpicols[c]->redcost = redcost[c];
13957  lpicols[c]->basisstatus = (unsigned int) cstat[c];
13958  lpicols[c]->validredcostlp = lpcount;
13959  if( stillprimalfeasible )
13960  {
13961  stillprimalfeasible =
13962  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
13963  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
13964  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
13965  }
13966  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13967  {
13968  double compslack;
13969 
13970  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13971  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
13972  * variables, which would magnify even the tiniest violation in the dual multiplier
13973  */
13974  if( stilldualfeasible )
13975  {
13976  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
13977  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13978  }
13979  if( stilldualfeasible )
13980  {
13981  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
13982  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13983  }
13984 
13985  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13986  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13987  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13988  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13989  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13990  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
13991  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
13992  dualfeasible != NULL ? stilldualfeasible : TRUE);
13993  }
13994  else
13995  {
13996  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
13997  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
13998  {
13999  lpicols[c]->redcost = 0.0;
14000  }
14001 
14002  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14003  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14004  * bounds, its reduced cost must be zero
14005  */
14006  if( stilldualfeasible
14007  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
14008  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14009  if( stilldualfeasible
14010  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
14011  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14012 
14013  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14014  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14015  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14016  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14017  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14018  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14019  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14020  dualfeasible != NULL ? stilldualfeasible : TRUE);
14021  }
14022 
14023  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14024  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14025  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14026  */
14027  if( stilldualfeasible )
14028  {
14029  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14030  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14031  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14032  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14033  }
14034  }
14035 
14036  /* copy dual solution and activities into rows */
14037  for( r = 0; r < nlpirows; ++r )
14038  {
14039  assert( 0 <= rstat[r] && rstat[r] < 4 );
14040  lpirows[r]->dualsol = dualsol[r];
14041  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14042  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14043  lpirows[r]->validactivitylp = lpcount;
14044  if( stillprimalfeasible )
14045  {
14046  stillprimalfeasible =
14047  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14048  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14049  }
14050  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14051  {
14052  double compslack;
14053 
14054  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14055  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14056  * variables, which would magnify even the tiniest violation in the dual multiplier
14057  */
14058  if( stilldualfeasible )
14059  {
14060  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14061  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14062  }
14063  if( stilldualfeasible )
14064  {
14065  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14066  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14067  }
14068 
14069  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14070  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14071  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14072  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14073  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14074  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14075  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14076  dualfeasible != NULL ? stilldualfeasible : TRUE);
14077  }
14078  else
14079  {
14080  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14081  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14082  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14083  */
14084  if( stilldualfeasible &&
14085  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
14086  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14087  if( stilldualfeasible &&
14088  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
14089  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14090 
14091  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14092  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14093  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14094  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14095  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14096  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14097  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14098  dualfeasible != NULL ? stilldualfeasible : TRUE);
14099  }
14100 
14101  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14102  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14103  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14104  */
14105  if( stilldualfeasible )
14106  {
14107  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14108  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14109  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14110  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14111  }
14112  }
14113 
14114  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14115  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14116  * infinity
14117  */
14118  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14119  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14120  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14121  {
14122  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14123  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14124  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14125  }
14126 
14127  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14128  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14129  */
14130  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14131  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14132  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14133  {
14134  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14135  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14136  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14137  }
14138 
14139  if( primalfeasible != NULL )
14140  *primalfeasible = stillprimalfeasible;
14141  if( dualfeasible != NULL )
14142  *dualfeasible = stilldualfeasible;
14143 
14144  /* free temporary memory */
14145  SCIPsetFreeBufferArray(set, &rstat);
14146  SCIPsetFreeBufferArray(set, &cstat);
14147  SCIPsetFreeBufferArray(set, &redcost);
14148  SCIPsetFreeBufferArray(set, &activity);
14149  SCIPsetFreeBufferArray(set, &dualsol);
14150  SCIPsetFreeBufferArray(set, &primsol);
14151 
14152  return SCIP_OKAY;
14153 }
14154 
14155 /** stores LP solution with infinite objective value in the columns and rows */
14157  SCIP_LP* lp, /**< current LP data */
14158  SCIP_SET* set, /**< global SCIP settings */
14159  SCIP_STAT* stat, /**< problem statistics */
14160  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14161  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14162  )
14163 {
14164  SCIP_COL** lpicols;
14165  SCIP_ROW** lpirows;
14166  SCIP_Real* primsol;
14167  SCIP_Real* activity;
14168  SCIP_Real* ray;
14169  SCIP_Real rayobjval;
14170  SCIP_Real rayscale;
14171  SCIP_Longint lpcount;
14172  int nlpicols;
14173  int nlpirows;
14174  int c;
14175  int r;
14176 
14177  assert(lp != NULL);
14178  assert(lp->flushed);
14179  assert(lp->solved);
14180  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14181  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14182  assert(set != NULL);
14183  assert(stat != NULL);
14184  assert(lp->validsollp <= stat->lpcount);
14185 
14186  if( primalfeasible != NULL )
14187  *primalfeasible = TRUE;
14188  if( rayfeasible != NULL )
14189  *rayfeasible = TRUE;
14190 
14191  /* check if the values are already calculated */
14192  if( lp->validsollp == stat->lpcount )
14193  return SCIP_OKAY;
14194 
14195  /* check if the LP solver is able to provide a primal unbounded ray */
14196  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14197  {
14198  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14199  return SCIP_LPERROR;
14200  }
14201 
14202  lp->validsollp = stat->lpcount;
14203 
14204  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14205 
14206  /* get temporary memory */
14207  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14208  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14209  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14210 
14211  /* get primal feasible point */
14212  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14213 
14214  /* get primal unbounded ray */
14215  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14216 
14217  lpicols = lp->lpicols;
14218  lpirows = lp->lpirows;
14219  nlpicols = lp->nlpicols;
14220  nlpirows = lp->nlpirows;
14221  lpcount = stat->lpcount;
14222 
14223  /* calculate the objective value decrease of the ray */
14224  rayobjval = 0.0;
14225  for( c = 0; c < nlpicols; ++c )
14226  {
14227  assert(lpicols[c] != NULL);
14228  assert(lpicols[c]->var != NULL);
14229 
14230  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14231  if( rayfeasible != NULL )
14232  *rayfeasible = *rayfeasible
14233  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -lpicols[c]->lb))
14234  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, lpicols[c]->ub));
14235 
14236  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14237  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14238  */
14239  if( primalfeasible != NULL )
14240  *primalfeasible = *primalfeasible
14241  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14242  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14243 
14244  if( !SCIPsetIsZero(set, ray[c]) )
14245  rayobjval += ray[c] * lpicols[c]->obj;
14246  }
14247 
14248  /* if the finite point is already infeasible, we do not have to add the ray */
14249  if( primalfeasible != NULL && !(*primalfeasible) )
14250  {
14251  rayscale = 0.0;
14252  }
14253  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14254  else if( rayfeasible != NULL && !(*rayfeasible) )
14255  {
14256  rayscale = 0.0;
14257  }
14258  /* due to numerical problems, the objective of the ray might be nonnegative,
14259  *
14260  * @todo How to check for negative objective value here?
14261  */
14262  else if( !SCIPsetIsNegative(set, rayobjval) )
14263  {
14264  if( rayfeasible != NULL )
14265  {
14266  *rayfeasible = FALSE;
14267  }
14268 
14269  rayscale = 0.0;
14270  }
14271  else
14272  {
14273  assert(rayobjval != 0.0);
14274 
14275  /* scale the ray, such that the resulting point has infinite objective value */
14276  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14277  assert(SCIPsetIsFeasPositive(set, rayscale));
14278 
14279  /* ensure that unbounded point does not violate the bounds of the variables */
14280  for( c = 0; c < nlpicols; ++c )
14281  {
14282  if( SCIPsetIsPositive(set, ray[c]) )
14283  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14284  else if( SCIPsetIsNegative(set, ray[c]) )
14285  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14286 
14287  assert(SCIPsetIsFeasPositive(set, rayscale));
14288  }
14289  }
14290 
14291  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14292 
14293  /* calculate the unbounded point: x' = x + rayscale * ray */
14294  for( c = 0; c < nlpicols; ++c )
14295  {
14296  if( SCIPsetIsZero(set, ray[c]) )
14297  lpicols[c]->primsol = primsol[c];
14298  else
14299  {
14300  SCIP_Real primsolval = primsol[c] + rayscale * ray[c];
14301  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14302  }
14303  lpicols[c]->redcost = SCIP_INVALID;
14304  lpicols[c]->validredcostlp = -1;
14305  }
14306 
14307  for( r = 0; r < nlpirows; ++r )
14308  {
14309  lpirows[r]->dualsol = SCIP_INVALID;
14310  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14311  lpirows[r]->validactivitylp = lpcount;
14312 
14313  /* check for feasibility of the rows */
14314  if( primalfeasible != NULL )
14315  *primalfeasible = *primalfeasible
14316  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14317  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14318  }
14319 
14320  /* free temporary memory */
14321  SCIPsetFreeBufferArray(set, &ray);
14322  SCIPsetFreeBufferArray(set, &activity);
14323  SCIPsetFreeBufferArray(set, &primsol);
14324 
14325  return SCIP_OKAY;
14326 }
14327 
14328 /** returns primal ray proving the unboundedness of the current LP */
14330  SCIP_LP* lp, /**< current LP data */
14331  SCIP_SET* set, /**< global SCIP settings */
14332  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14333  * so the size of this array should be at least number of active variables
14334  * (all entries have to be initialized to 0 before) */
14335  )
14336 {
14337  SCIP_COL** lpicols;
14338  SCIP_Real* lpiray;
14339  SCIP_VAR* var;
14340  int nlpicols;
14341  int c;
14342 
14343  assert(lp != NULL);
14344  assert(set != NULL);
14345  assert(ray != NULL);
14346  assert(lp->flushed);
14347  assert(lp->solved);
14348  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14349  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14350 
14351  /* check if the LP solver is able to provide a primal unbounded ray */
14352  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14353  {
14354  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14355  return SCIP_LPERROR;
14356  }
14357 
14358  /* get temporary memory */
14359  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14360 
14361  SCIPsetDebugMsg(set, "getting primal ray values\n");
14362 
14363  /* get primal unbounded ray */
14364  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14365 
14366  lpicols = lp->lpicols;
14367  nlpicols = lp->nlpicols;
14368 
14369  /* store the ray values of active problem variables */
14370  for( c = 0; c < nlpicols; c++ )
14371  {
14372  assert(lpicols[c] != NULL);
14373 
14374  var = lpicols[c]->var;
14375  assert(var != NULL);
14376  assert(SCIPvarGetProbindex(var) != -1);
14377  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14378  }
14379 
14380  SCIPsetFreeBufferArray(set, &lpiray);
14381 
14382  return SCIP_OKAY;
14383 }
14384 
14385 /** stores the dual Farkas multipliers for infeasibility proof in rows */
14387  SCIP_LP* lp, /**< current LP data */
14388  SCIP_SET* set, /**< global SCIP settings */
14389  SCIP_STAT* stat /**< problem statistics */
14390  )
14391 {
14392  SCIP_COL** lpicols;
14393  SCIP_ROW** lpirows;
14394  SCIP_Real* dualfarkas;
14395  int nlpicols;
14396  int nlpirows;
14397  int c;
14398  int r;
14399 
14400  assert(lp != NULL);
14401  assert(lp->flushed);
14402  assert(lp->solved);
14403  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14404  assert(set != NULL);
14405  assert(stat != NULL);
14406  assert(lp->validfarkaslp <= stat->lpcount);
14407 
14408  /* check if the values are already calculated */
14409  if( lp->validfarkaslp == stat->lpcount )
14410  return SCIP_OKAY;
14411  lp->validfarkaslp = stat->lpcount;
14412 
14413  /* get temporary memory */
14414  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14415 
14416  /* get dual Farkas infeasibility proof */
14417  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14418 
14419  lpicols = lp->lpicols;
14420  lpirows = lp->lpirows;
14421  nlpicols = lp->nlpicols;
14422  nlpirows = lp->nlpirows;
14423 
14424  /* store infeasibility proof in rows */
14425  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14426  for( r = 0; r < nlpirows; ++r )
14427  {
14428  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14429  lpirows[r]->dualfarkas = dualfarkas[r];
14430  lpirows[r]->dualsol = SCIP_INVALID;
14431  lpirows[r]->activity = 0.0;
14432  lpirows[r]->validactivitylp = -1L;
14433  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14434  }
14435 
14436  /* set columns as invalid */
14437  for( c = 0; c < nlpicols; ++c )
14438  {
14439  lpicols[c]->primsol = SCIP_INVALID;
14440  lpicols[c]->redcost = SCIP_INVALID;
14441  lpicols[c]->validredcostlp = -1L;
14442  lpicols[c]->validfarkaslp = -1L;
14443  }
14444 
14445  /* free temporary memory */
14446  SCIPsetFreeBufferArray(set, &dualfarkas);
14447 
14448  return SCIP_OKAY;
14449 }
14450 
14451 /** get number of iterations used in last LP solve */
14453  SCIP_LP* lp, /**< current LP data */
14454  int* iterations /**< pointer to store the iteration count */
14455  )
14456 {
14457  assert(lp != NULL);
14458 
14459  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14460 
14461  return SCIP_OKAY;
14462 }
14463 
14464 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14465  * resets age of non-zero columns and sharp rows
14466  */
14468  SCIP_LP* lp, /**< current LP data */
14469  SCIP_STAT* stat /**< problem statistics */
14470  )
14471 {
14472  SCIP_COL** lpicols;
14473  SCIP_ROW** lpirows;
14474  int nlpicols;
14475  int nlpirows;
14476  int c;
14477  int r;
14478 
14479  assert(lp != NULL);
14480  assert(lp->flushed);
14481  assert(lp->solved);
14482  assert(lp->nlpicols == lp->ncols);
14483  assert(lp->nlpirows == lp->nrows);
14484  assert(stat != NULL);
14485  assert(lp->validsollp == stat->lpcount);
14486 
14487  SCIPdebugMessage("updating LP ages\n");
14488 
14489  lpicols = lp->lpicols;
14490  lpirows = lp->lpirows;
14491  nlpicols = lp->nlpicols;
14492  nlpirows = lp->nlpirows;
14493 
14494  for( c = 0; c < nlpicols; ++c )
14495  {
14496  assert(lpicols[c] == lp->cols[c]);
14497  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14498  lpicols[c]->age++;
14499  else
14500  lpicols[c]->age = 0;
14501  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14502  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14503  }
14504 
14505  for( r = 0; r < nlpirows; ++r )
14506  {
14507  lpirows[r]->nlpsaftercreation++;
14508  assert(lpirows[r] == lp->rows[r]);
14509 
14510  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14511  {
14512  lpirows[r]->age++;
14513  }
14514  else
14515  {
14516  lpirows[r]->activeinlpcounter++;
14517  lpirows[r]->age = 0;
14518  }
14519  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14520  }
14521 
14522  return SCIP_OKAY;
14523 }
14524 
14525 /* deletes the marked columns from the LP and the LP interface */
14526 static
14528  SCIP_LP* lp, /**< current LP data */
14529  SCIP_SET* set, /**< global SCIP settings */
14530  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
14531  )
14532 {
14533  SCIP_COL* col;
14534  int ncols;
14535  int c;
14536 
14537  assert(lp != NULL);
14538  assert(lp->flushed);
14539  assert(lp->ncols == lp->nlpicols);
14540  assert(!lp->diving);
14541  assert(coldstat != NULL);
14542  assert(lp->nlazycols <= lp->ncols);
14543 
14544  ncols = lp->ncols;
14545 
14546  /* delete columns in LP solver */
14547  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
14548 
14549  /* update LP data respectively */
14550  for( c = 0; c < ncols; ++c )
14551  {
14552  col = lp->cols[c];
14553  assert(col != NULL);
14554  assert(col == lp->lpicols[c]);
14555  assert(coldstat[c] <= c);
14556  col->lppos = coldstat[c];
14557  if( coldstat[c] == -1 )
14558  {
14559  assert(col->removable);
14560 
14561  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
14562  * function vector norms
14563  */
14564  markColDeleted(col);
14565  colUpdateDelLP(col, set);
14566  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
14567  col->lpdepth = -1;
14568 
14569  lp->cols[c] = NULL;
14570  lp->lpicols[c] = NULL;
14571  lp->ncols--;
14572  lp->nremovablecols--;
14573  lp->nlpicols--;
14574  }
14575  else if( coldstat[c] < c )
14576  {
14577  assert(lp->cols[coldstat[c]] == NULL);
14578  assert(lp->lpicols[coldstat[c]] == NULL);
14579  lp->cols[coldstat[c]] = col;
14580  lp->lpicols[coldstat[c]] = col;
14581  lp->cols[coldstat[c]]->lppos = coldstat[c];
14582  lp->cols[coldstat[c]]->lpipos = coldstat[c];
14583  lp->cols[c] = NULL;
14584  lp->lpicols[c] = NULL;
14585  }
14586  }
14587 
14588  /* remove columns which are deleted from the lazy column array */
14589  c = 0;
14590  while( c < lp->nlazycols )
14591  {
14592  if( lp->lazycols[c]->lpipos < 0 )
14593  {
14594  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
14595  lp->nlazycols--;
14596  }
14597  else
14598  c++;
14599  }
14600 
14601  /* mark LP to be unsolved */
14602  if( lp->ncols < ncols )
14603  {
14604  assert(lp->ncols == lp->nlpicols);
14605  assert(lp->nchgcols == 0);
14606  assert(lp->flushed);
14607 
14608  lp->lpifirstchgcol = lp->nlpicols;
14609 
14610  /* mark the current solution invalid */
14611  lp->solved = FALSE;
14612  lp->primalfeasible = FALSE;
14613  lp->primalchecked = FALSE;
14614  lp->lpobjval = SCIP_INVALID;
14616  }
14617 
14618  checkLazyColArray(lp, set);
14619  checkLinks(lp);
14620 
14621  return SCIP_OKAY;
14622 }
14623 
14624 /* deletes the marked rows from the LP and the LP interface */
14625 static
14627  SCIP_LP* lp, /**< current LP data */
14628  BMS_BLKMEM* blkmem, /**< block memory buffers */
14629  SCIP_SET* set, /**< global SCIP settings */
14630  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14631  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14632  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
14633  )
14634 {
14635  SCIP_ROW* row;
14636  int nrows;
14637  int r;
14638 
14639  assert(lp != NULL);
14640  assert(lp->flushed);
14641  assert(lp->nrows == lp->nlpirows);
14642  assert(!lp->diving);
14643  assert(rowdstat != NULL);
14644 
14645  nrows = lp->nrows;
14646 
14647  /* delete rows in LP solver */
14648  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
14649 
14650  /* update LP data respectively */
14651  for( r = 0; r < nrows; ++r )
14652  {
14653  row = lp->rows[r];
14654  assert(row == lp->lpirows[r]);
14655  assert(rowdstat[r] <= r);
14656  assert(row != NULL);
14657  row->lppos = rowdstat[r];
14658  if( rowdstat[r] == -1 )
14659  {
14660  if( row->removable )
14661  lp->nremovablerows--;
14662 
14663  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
14664  markRowDeleted(row);
14665  rowUpdateDelLP(row);
14666  row->lpdepth = -1;
14667 
14668  /* check, if row deletion events are tracked
14669  * if so, issue ROWDELETEDLP event
14670  */
14671  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
14672  {
14673  SCIP_EVENT* event;
14674 
14675  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
14676  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
14677  }
14678 
14679  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
14680  SCIProwUnlock(lp->rows[r]);
14681  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
14682  assert(lp->lpirows[r] == NULL);
14683  assert(lp->rows[r] == NULL);
14684  lp->nrows--;
14685  lp->nlpirows--;
14686  }
14687  else if( rowdstat[r] < r )
14688  {
14689  assert(lp->rows[rowdstat[r]] == NULL);
14690  assert(lp->lpirows[rowdstat[r]] == NULL);
14691  lp->rows[rowdstat[r]] = row;
14692  lp->lpirows[rowdstat[r]] = row;
14693  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
14694  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
14695  lp->rows[r] = NULL;
14696  lp->lpirows[r] = NULL;
14697  }
14698  }
14699 
14700  /* mark LP to be unsolved */
14701  if( lp->nrows < nrows )
14702  {
14703  assert(lp->nrows == lp->nlpirows);
14704  assert(lp->nchgrows == 0);
14705  assert(lp->flushed);
14706 
14707  lp->lpifirstchgrow = lp->nlpirows;
14708 
14709  /* mark the current solution invalid */
14710  lp->solved = FALSE;
14711  lp->dualfeasible = FALSE;
14712  lp->dualchecked = FALSE;
14713  lp->lpobjval = SCIP_INVALID;
14715  }
14716 
14717  checkLinks(lp);
14718 
14719  return SCIP_OKAY;
14720 }
14721 
14722 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
14723 static
14725  SCIP_LP* lp, /**< current LP data */
14726  SCIP_SET* set, /**< global SCIP settings */
14727  SCIP_STAT* stat, /**< problem statistics */
14728  int firstcol /**< first column to check for clean up */
14729  )
14730 {
14731  SCIP_COL** cols;
14732 #ifndef NDEBUG
14733  SCIP_COL** lpicols;
14734 #endif
14735  int* coldstat;
14736  int ncols;
14737  int ndelcols;
14738  int c;
14739 
14740  assert(lp != NULL);
14741  assert(lp->flushed);
14742  assert(lp->ncols == lp->nlpicols);
14743  assert(lp->nremovablecols <= lp->ncols);
14744  assert(!lp->diving);
14745  assert(set != NULL);
14746  assert(stat != NULL);
14747 
14748  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
14749  return SCIP_OKAY;
14750 
14751  ncols = lp->ncols;
14752  cols = lp->cols;
14753 #ifndef NDEBUG
14754  lpicols = lp->lpicols;
14755 #endif
14756 
14757  /* get temporary memory */
14758  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14759 
14760  /* mark obsolete columns to be deleted */
14761  ndelcols = 0;
14762  BMSclearMemoryArray(coldstat, ncols);
14763  for( c = firstcol; c < ncols; ++c )
14764  {
14765  assert(cols[c] == lpicols[c]);
14766  assert(cols[c]->lppos == c);
14767  assert(cols[c]->lpipos == c);
14768  if( cols[c]->removable
14769  && 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 */
14770  && cols[c]->age > set->lp_colagelimit
14772  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14773  {
14774  assert(cols[c]->primsol == 0.0);
14775  coldstat[c] = 1;
14776  ndelcols++;
14777  cols[c]->obsoletenode = stat->nnodes;
14778  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
14779  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
14780  }
14781  }
14782 
14783  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
14784 
14785  /* delete the marked columns in the LP solver interface, update the LP respectively */
14786  if( ndelcols > 0 )
14787  {
14788  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14789  }
14790  assert(lp->ncols == ncols - ndelcols);
14791 
14792  /* release temporary memory */
14793  SCIPsetFreeBufferArray(set, &coldstat);
14794 
14795  return SCIP_OKAY;
14796 }
14797 
14798 /** removes all basic rows, that are too old, beginning with the given firstrow */
14799 static
14801  SCIP_LP* lp, /**< current LP data */
14802  BMS_BLKMEM* blkmem, /**< block memory buffers */
14803  SCIP_SET* set, /**< global SCIP settings */
14804  SCIP_STAT* stat, /**< problem statistics */
14805  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14806  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14807  int firstrow /**< first row to check for clean up */
14808  )
14809 {
14810  SCIP_ROW** rows;
14811 #ifndef NDEBUG
14812  SCIP_ROW** lpirows;
14813 #endif
14814  int* rowdstat;
14815  int nrows;
14816  int ndelrows;
14817  int r;
14818 
14819  assert(lp != NULL);
14820  assert(lp->flushed);
14821  assert(lp->nrows == lp->nlpirows);
14822  assert(lp->nremovablerows <= lp->nrows);
14823  assert(!lp->diving);
14824  assert(set != NULL);
14825  assert(stat != NULL);
14826 
14827  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
14828  return SCIP_OKAY;
14829 
14830  nrows = lp->nrows;
14831  rows = lp->rows;
14832 #ifndef NDEBUG
14833  lpirows = lp->lpirows;
14834 #endif
14835 
14836  /* get temporary memory */
14837  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14838 
14839  /* mark obsolete rows to be deleted */
14840  ndelrows = 0;
14841  BMSclearMemoryArray(rowdstat, nrows);
14842  for( r = firstrow; r < nrows; ++r )
14843  {
14844  assert(rows[r] == lpirows[r]);
14845  assert(rows[r]->lppos == r);
14846  assert(rows[r]->lpipos == r);
14847  if( rows[r]->removable
14848  && 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 */
14849  && rows[r]->age > set->lp_rowagelimit
14851  {
14852  rowdstat[r] = 1;
14853  ndelrows++;
14854  rows[r]->obsoletenode = stat->nnodes;
14855  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
14856  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
14857  }
14858  }
14859 
14860  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
14861 
14862  /* delete the marked rows in the LP solver interface, update the LP respectively */
14863  if( ndelrows > 0 )
14864  {
14865  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14866  }
14867  assert(lp->nrows == nrows - ndelrows);
14868 
14869  /* release temporary memory */
14870  SCIPsetFreeBufferArray(set, &rowdstat);
14871 
14872  return SCIP_OKAY;
14873 }
14874 
14875 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
14877  SCIP_LP* lp, /**< current LP data */
14878  BMS_BLKMEM* blkmem, /**< block memory buffers */
14879  SCIP_SET* set, /**< global SCIP settings */
14880  SCIP_STAT* stat, /**< problem statistics */
14881  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14882  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14883  )
14884 {
14885  assert(lp != NULL);
14886  assert(lp->solved);
14887  assert(!lp->diving);
14889  assert(set != NULL);
14890 
14891  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
14892  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
14893 
14894  if( lp->firstnewcol < lp->ncols )
14895  {
14896  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
14897  }
14898  if( lp->firstnewrow < lp->nrows )
14899  {
14900  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
14901  }
14902 
14903  return SCIP_OKAY;
14904 }
14905 
14906 /** removes all non-basic columns and basic rows in whole LP, that are too old */
14908  SCIP_LP* lp, /**< current LP data */
14909  BMS_BLKMEM* blkmem, /**< block memory buffers */
14910  SCIP_SET* set, /**< global SCIP settings */
14911  SCIP_STAT* stat, /**< problem statistics */
14912  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14913  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14914  )
14915 {
14916  assert(lp != NULL);
14917  assert(lp->solved);
14918  assert(!lp->diving);
14920  assert(set != NULL);
14921 
14922  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
14923 
14924  if( 0 < lp->ncols )
14925  {
14926  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
14927  }
14928  if( 0 < lp->nrows )
14929  {
14930  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
14931  }
14932 
14933  return SCIP_OKAY;
14934 }
14935 
14936 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
14937 static
14939  SCIP_LP* lp, /**< current LP data */
14940  SCIP_SET* set, /**< global SCIP settings */
14941  SCIP_STAT* stat, /**< problem statistics */
14942  int firstcol /**< first column to check for clean up */
14943  )
14944 {
14945  SCIP_COL** cols;
14946  SCIP_COL** lpicols;
14947  int* coldstat;
14948  int ncols;
14949  int ndelcols;
14950  int c;
14951 
14952  assert(lp != NULL);
14953  assert(lp->flushed);
14954  assert(lp->ncols == lp->nlpicols);
14955  assert(!lp->diving);
14956  assert(stat != NULL);
14957  assert(lp->validsollp == stat->lpcount);
14958  assert(0 <= firstcol && firstcol < lp->ncols);
14959 
14960  if( lp->nremovablecols == 0 || !lp->solisbasic )
14961  return SCIP_OKAY;
14962 
14963  ncols = lp->ncols;
14964  cols = lp->cols;
14965  lpicols = lp->lpicols;
14966 
14967  /* get temporary memory */
14968  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14969 
14970  /* mark unused columns to be deleted */
14971  ndelcols = 0;
14972  BMSclearMemoryArray(coldstat, ncols);
14973  for( c = firstcol; c < ncols; ++c )
14974  {
14975  assert(cols[c] == lpicols[c]);
14976  assert(cols[c]->lppos == c);
14977  assert(cols[c]->lpipos == c);
14978  if( lpicols[c]->removable
14979  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
14980  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
14981  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14982  {
14983  coldstat[c] = 1;
14984  ndelcols++;
14985  }
14986  }
14987 
14988  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
14989 
14990  /* delete the marked columns in the LP solver interface, update the LP respectively */
14991  if( ndelcols > 0 )
14992  {
14993  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14994  }
14995  assert(lp->ncols == ncols - ndelcols);
14996 
14997  /* release temporary memory */
14998  SCIPsetFreeBufferArray(set, &coldstat);
14999 
15000  return SCIP_OKAY;
15001 }
15002 
15003 /** removes all basic rows beginning with the given firstrow */
15004 static
15006  SCIP_LP* lp, /**< current LP data */
15007  BMS_BLKMEM* blkmem, /**< block memory buffers */
15008  SCIP_SET* set, /**< global SCIP settings */
15009  SCIP_STAT* stat, /**< problem statistics */
15010  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15011  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15012  int firstrow /**< first row to check for clean up */
15013  )
15014 {
15015 #ifndef NDEBUG
15016  SCIP_ROW** rows;
15017 #endif
15018  SCIP_ROW** lpirows;
15019  int* rowdstat;
15020  int nrows;
15021  int ndelrows;
15022  int r;
15023 
15024  assert(lp != NULL);
15025  assert(lp->flushed);
15026  assert(lp->ncols == lp->nlpicols);
15027  assert(lp->nrows == lp->nlpirows);
15028  assert(!lp->diving);
15029  assert(stat != NULL);
15030  assert(lp->validsollp == stat->lpcount);
15031  assert(0 <= firstrow && firstrow < lp->nrows);
15032 
15033  if( lp->nremovablerows == 0 || !lp->solisbasic )
15034  return SCIP_OKAY;
15035 
15036 #ifndef NDEBUG
15037  rows = lp->rows;
15038 #endif
15039  nrows = lp->nrows;
15040  lpirows = lp->lpirows;
15041 
15042  /* get temporary memory */
15043  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15044 
15045  /* mark unused rows to be deleted */
15046  ndelrows = 0;
15047  BMSclearMemoryArray(rowdstat, nrows);
15048  for( r = firstrow; r < nrows; ++r )
15049  {
15050  assert(rows[r] == lpirows[r]);
15051  assert(rows[r]->lppos == r);
15052  assert(rows[r]->lpipos == r);
15053  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15054  {
15055  rowdstat[r] = 1;
15056  ndelrows++;
15057  }
15058  }
15059 
15060  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15061 
15062  /* delete the marked rows in the LP solver interface, update the LP respectively */
15063  if( ndelrows > 0 )
15064  {
15065  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15066  }
15067  assert(lp->nrows == nrows - ndelrows);
15068 
15069  /* release temporary memory */
15070  SCIPsetFreeBufferArray(set, &rowdstat);
15071 
15072  return SCIP_OKAY;
15073 }
15074 
15075 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15077  SCIP_LP* lp, /**< current LP data */
15078  BMS_BLKMEM* blkmem, /**< block memory buffers */
15079  SCIP_SET* set, /**< global SCIP settings */
15080  SCIP_STAT* stat, /**< problem statistics */
15081  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15082  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15083  SCIP_Bool root /**< are we at the root node? */
15084  )
15085 {
15086  SCIP_Bool cleanupcols;
15087  SCIP_Bool cleanuprows;
15088 
15089  assert(lp != NULL);
15090  assert(lp->solved);
15091  assert(!lp->diving);
15093  assert(set != NULL);
15094 
15095  /* check, if we want to clean up the columns and rows */
15096  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15097  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15098 
15099  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15100  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15101 
15102  if( cleanupcols && lp->firstnewcol < lp->ncols )
15103  {
15104  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15105  }
15106  if( cleanuprows && lp->firstnewrow < lp->nrows )
15107  {
15108  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15109  }
15110 
15111  return SCIP_OKAY;
15112 }
15113 
15114 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15116  SCIP_LP* lp, /**< current LP data */
15117  BMS_BLKMEM* blkmem, /**< block memory buffers */
15118  SCIP_SET* set, /**< global SCIP settings */
15119  SCIP_STAT* stat, /**< problem statistics */
15120  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15121  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15122  SCIP_Bool root /**< are we at the root node? */
15123  )
15124 {
15125  SCIP_Bool cleanupcols;
15126  SCIP_Bool cleanuprows;
15127 
15128  assert(lp != NULL);
15129  assert(lp->solved);
15130  assert(!lp->diving);
15132  assert(set != NULL);
15133 
15134  /* check, if we want to clean up the columns and rows */
15135  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15136  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15137 
15138  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15139  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15140 
15141  if( cleanupcols && 0 < lp->ncols )
15142  {
15143  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15144  }
15145  if( cleanuprows && 0 < lp->nrows )
15146  {
15147  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15148  }
15149 
15150  return SCIP_OKAY;
15151 }
15152 
15153 /** removes all redundant rows that were added at the current node */
15155  SCIP_LP* lp, /**< current LP data */
15156  BMS_BLKMEM* blkmem, /**< block memory buffers */
15157  SCIP_SET* set, /**< global SCIP settings */
15158  SCIP_STAT* stat, /**< problem statistics */
15159  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15160  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15161  )
15162 {
15163 #ifndef NDEBUG
15164  SCIP_ROW** rows;
15165 #endif
15166  SCIP_ROW** lpirows;
15167  int* rowdstat;
15168  int nrows;
15169  int ndelrows;
15170  int r;
15171 
15172  assert(lp != NULL);
15173  assert(lp->flushed);
15174  assert(lp->ncols == lp->nlpicols);
15175  assert(lp->nrows == lp->nlpirows);
15176  assert(!lp->diving);
15177  assert(stat != NULL);
15178  assert(lp->validsollp == stat->lpcount);
15179  assert(lp->firstnewrow <= lp->nrows);
15180 
15181  if( lp->firstnewrow == lp->nrows )
15182  return SCIP_OKAY;
15183 
15184 #ifndef NDEBUG
15185  rows = lp->rows;
15186 #endif
15187  nrows = lp->nrows;
15188  lpirows = lp->lpirows;
15189 
15190  /* get temporary memory */
15191  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15192 
15193  /* mark redundant rows to be deleted (only delete basic rows!) */
15194  ndelrows = 0;
15195  BMSclearMemoryArray(rowdstat, nrows);
15196  for( r = lp->firstnewrow; r < nrows; ++r )
15197  {
15198  assert(rows[r] == lpirows[r]);
15199  assert(rows[r]->lppos == r);
15200  assert(rows[r]->lpipos == r);
15201  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15202  && SCIProwIsRedundant(lpirows[r], set, stat) )
15203  {
15204  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15205  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15206  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15207  rowdstat[r] = 1;
15208  ndelrows++;
15209  }
15210  }
15211 
15212  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15213 
15214  /* delete the marked rows in the LP solver interface, update the LP respectively */
15215  if( ndelrows > 0 )
15216  {
15217  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15218  }
15219  assert(lp->nrows == nrows - ndelrows);
15220 
15221  /* release temporary memory */
15222  SCIPsetFreeBufferArray(set, &rowdstat);
15223 
15224  return SCIP_OKAY;
15225 }
15226 
15227 /** initiates LP diving */
15229  SCIP_LP* lp, /**< current LP data */
15230  BMS_BLKMEM* blkmem, /**< block memory */
15231  SCIP_SET* set, /**< global SCIP settings */
15232  SCIP_STAT* stat /**< problem statistics */
15233  )
15234 {
15235  int c;
15236  int r;
15237 
15238  assert(lp != NULL);
15239  assert(lp->flushed || !lp->solved);
15240  assert(!lp->diving);
15241  assert(!lp->probing);
15242  assert(lp->divelpistate == NULL);
15243  assert(lp->divelpwasprimfeas);
15244  assert(lp->divelpwasdualfeas);
15245  assert(lp->validsollp <= stat->lpcount);
15246  assert(blkmem != NULL);
15247  assert(set != NULL);
15248  assert(lp->ndivechgsides == 0);
15249 
15250  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15251  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15252 
15253 #ifndef NDEBUG
15254  for( c = 0; c < lp->ncols; ++c )
15255  {
15256  assert(lp->cols[c] != NULL);
15257  assert(lp->cols[c]->var != NULL);
15258  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15259  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15260  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15261  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15262  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15263  }
15264 #endif
15265 
15266  /* save current LPI state (basis information) */
15267  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15269  lp->divelpwasdualfeas = lp->dualfeasible;
15272 
15273  /* save current LP values dependent on the solution */
15274  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15275  assert(lp->storedsolvals != NULL);
15276  if( !set->lp_resolverestore && lp->solved )
15277  {
15278  SCIP_Bool store = TRUE;
15279 
15280  switch ( lp->lpsolstat )
15281  {
15283  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15284  assert(lp->validsollp == stat->lpcount);
15285  break;
15287  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15288  assert(lp->validsollp == stat->lpcount);
15289  break;
15293  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15294  assert(lp->validsollp == stat->lpcount);
15295  break;
15297  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
15298  break;
15300  case SCIP_LPSOLSTAT_ERROR:
15301  default:
15302  store = FALSE;
15303  }
15304 
15305  if ( store )
15306  {
15307  for( c = 0; c < lp->ncols; ++c )
15308  {
15309  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15310  }
15311  for( r = 0; r < lp->nrows; ++r )
15312  {
15314  }
15315  }
15316  }
15317 
15318  /* store LPI iteration limit */
15320 
15321  /* remember the number of domain changes */
15322  lp->divenolddomchgs = stat->domchgcount;
15323 
15324  /* store current number of rows */
15325  lp->ndivingrows = lp->nrows;
15326 
15327  /* switch to diving mode */
15328  lp->diving = TRUE;
15329 
15330  return SCIP_OKAY;
15331 }
15332 
15333 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15335  SCIP_LP* lp, /**< current LP data */
15336  BMS_BLKMEM* blkmem, /**< block memory */
15337  SCIP_SET* set, /**< global SCIP settings */
15338  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15339  SCIP_STAT* stat, /**< problem statistics */
15340  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15341  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15342  SCIP_PROB* prob, /**< problem data */
15343  SCIP_VAR** vars, /**< array with all active variables */
15344  int nvars /**< number of active variables */
15345  )
15346 {
15347  SCIP_VAR* var;
15348  int v;
15349 
15350  assert(lp != NULL);
15351  assert(lp->diving);
15352  assert(blkmem != NULL);
15353  assert(nvars == 0 || vars != NULL);
15354 
15355  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15356 
15357  /* reset all columns' objective values and bounds to its original values */
15358  for( v = 0; v < nvars; ++v )
15359  {
15360  var = vars[v];
15361  assert(var != NULL);
15363  {
15364  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15365  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15366  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15367  }
15368  }
15369 
15370  /* remove rows which were added in diving mode */
15371  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15372 
15373  /* undo changes to left hand sides and right hand sides */
15374  while( lp->ndivechgsides > 0 )
15375  {
15376  SCIP_Real oldside;
15377  SCIP_SIDETYPE sidetype;
15378  SCIP_ROW* row;
15379 
15380  lp->ndivechgsides--;
15381  oldside = lp->divechgsides[lp->ndivechgsides];
15382  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15383  row = lp->divechgrows[lp->ndivechgsides];
15384 
15385  if( sidetype == SCIP_SIDETYPE_LEFT )
15386  {
15387  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15388  }
15389  else
15390  {
15391  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15392  }
15393  }
15394 
15395  /* restore LPI iteration limit */
15397 
15398  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15399  * happens
15400  */
15401  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15403  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15404  lp->divelpwasprimfeas = TRUE;
15405  lp->divelpwasdualfeas = TRUE;
15406  lp->divelpwasprimchecked = TRUE;
15407  lp->divelpwasdualchecked = TRUE;
15408  assert(lp->divelpistate == NULL);
15409 
15410  /* switch to standard (non-diving) mode */
15411  lp->diving = FALSE;
15412  lp->divingobjchg = FALSE;
15413 
15414  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15415  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15416  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15417  * the parameter resolverestore to TRUE
15418  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15419  */
15420  assert(lp->storedsolvals != NULL);
15421  if( lp->storedsolvals->lpissolved
15422  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
15423  {
15424  SCIP_Bool lperror;
15425 
15426  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15427  if( lperror )
15428  {
15429  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
15430  lp->resolvelperror = TRUE;
15431  }
15436  {
15437  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15438  "LP was not resolved to a sufficient status after diving\n");
15439  lp->resolvelperror = TRUE;
15440  }
15441  }
15442  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15443  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15444  * re-solve as above can lead to a different LP status
15445  */
15446  else
15447  {
15448  int c;
15449  int r;
15450 
15451  /* if there are lazy bounds, remove them from the LP */
15452  if( lp->nlazycols > 0 )
15453  {
15454  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15455  * first resolve LP?
15456  */
15457  SCIP_CALL( updateLazyBounds(lp, set) );
15458  assert(lp->diving == lp->divinglazyapplied);
15459 
15460  /* flush changes to the LP solver */
15461  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15462  }
15463 
15464  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15465  SCIPstatIncrement(stat, set, lpcount);
15466 
15467  /* restore LP solution values in lp data, columns and rows */
15468  if( lp->storedsolvals->lpissolved &&
15475  )
15476  {
15477  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15478 
15479  for( c = 0; c < lp->ncols; ++c )
15480  {
15481  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15482  }
15483  for( r = 0; r < lp->nrows; ++r )
15484  {
15485  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15486  }
15487  }
15488  else
15489  {
15490  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15491  }
15492  }
15493 
15494 #ifndef NDEBUG
15495  {
15496  int c;
15497  for( c = 0; c < lp->ncols; ++c )
15498  {
15499  assert(lp->cols[c] != NULL);
15500  assert(lp->cols[c]->var != NULL);
15501  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15502  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15503  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15504  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15505  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15506  }
15507  }
15508 #endif
15509 
15510  return SCIP_OKAY;
15511 }
15512 
15513 #define DIVESTACKGROWFACT 1.5
15514 
15515 /** records a current row side such that any change will be undone after diving */
15517  SCIP_LP* lp, /**< LP data object */
15518  SCIP_ROW* row, /**< row affected by the change */
15519  SCIP_SIDETYPE sidetype /**< side type */
15520  )
15521 {
15522  assert(lp != NULL);
15523  assert(row != NULL);
15524 
15525  if( lp->ndivechgsides == lp->divechgsidessize )
15526  {
15528  }
15529  assert(lp->ndivechgsides < lp->divechgsidessize);
15530 
15531  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
15532  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
15533  lp->divechgrows[lp->ndivechgsides] = row;
15534  lp->ndivechgsides++;
15535 
15536  return SCIP_OKAY;
15537 }
15538 
15539 /** informs the LP that probing mode was initiated */
15541  SCIP_LP* lp /**< current LP data */
15542  )
15543 {
15544  assert(lp != NULL);
15545  assert(!lp->probing);
15546  assert(!lp->strongbranching);
15547  assert(!lp->strongbranchprobing);
15548 
15549  lp->probing = TRUE;
15550 
15551  return SCIP_OKAY;
15552 }
15553 
15554 /** informs the LP that probing mode was finished */
15556  SCIP_LP* lp /**< current LP data */
15557  )
15558 {
15559  assert(lp != NULL);
15560  assert(lp->probing);
15561  assert(!lp->strongbranching);
15562  assert(!lp->strongbranchprobing);
15563 
15564  lp->probing = FALSE;
15565 
15566  return SCIP_OKAY;
15567 }
15568 
15569 /** informs the LP that the probing mode is now used for strongbranching */
15571  SCIP_LP* lp /**< current LP data */
15572  )
15573 {
15574  assert(lp != NULL);
15575  assert(lp->probing);
15576  assert(!lp->strongbranching);
15577  assert(!lp->strongbranchprobing);
15578 
15579  lp->strongbranchprobing = TRUE;
15580 }
15581 
15582 /** informs the LP that the probing mode is not used for strongbranching anymore */
15584  SCIP_LP* lp /**< current LP data */
15585  )
15586 {
15587  assert(lp != NULL);
15588  assert(lp->probing);
15589  assert(!lp->strongbranching);
15590  assert(lp->strongbranchprobing);
15591 
15592  lp->strongbranchprobing = FALSE;
15593 }
15594 
15595 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
15596  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
15597  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
15598  * we have only left hand sides):
15599  * min{cx | b <= Ax, lb <= x <= ub}
15600  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
15601  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
15602  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
15603  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
15604  */
15605 static
15607  SCIP_LP* lp, /**< current LP data */
15608  SCIP_SET* set, /**< global SCIP settings */
15609  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
15610  SCIP_Real* bound /**< result of interval arithmetic minimization */
15611  )
15612 {
15613  SCIP_INTERVAL* yinter;
15614  SCIP_INTERVAL b;
15615  SCIP_INTERVAL ytb;
15616  SCIP_INTERVAL prod;
15617  SCIP_INTERVAL diff;
15618  SCIP_INTERVAL x;
15619  SCIP_INTERVAL minprod;
15620  SCIP_INTERVAL a;
15621  SCIP_ROW* row;
15622  SCIP_COL* col;
15623  SCIP_Real y;
15624  SCIP_Real c;
15625  int i;
15626  int j;
15627 
15628  assert(lp != NULL);
15629  assert(lp->solved);
15630  assert(set != NULL);
15631  assert(bound != NULL);
15632 
15633  /* allocate buffer for storing y in interval arithmetic */
15634  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
15635 
15636  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
15637  SCIPintervalSet(&ytb, 0.0);
15638  for( j = 0; j < lp->nrows; ++j )
15639  {
15640  row = lp->rows[j];
15641  assert(row != NULL);
15642 
15643  y = (usefarkas ? row->dualfarkas : row->dualsol);
15644 
15645  if( SCIPsetIsFeasPositive(set, y) )
15646  {
15647  SCIPintervalSet(&yinter[j], y);
15648  SCIPintervalSet(&b, row->lhs - row->constant);
15649  }
15650  else if( SCIPsetIsFeasNegative(set, y) )
15651  {
15652  SCIPintervalSet(&yinter[j], y);
15653  SCIPintervalSet(&b, row->rhs - row->constant);
15654  }
15655  else
15656  {
15657  SCIPintervalSet(&yinter[j], 0.0);
15658  SCIPintervalSet(&b, 0.0);
15659  }
15660 
15661  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
15662  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
15663  }
15664 
15665  /* calculate min{(c^T - y^TA)x} */
15666  SCIPintervalSet(&minprod, 0.0);
15667  for( j = 0; j < lp->ncols; ++j )
15668  {
15669  col = lp->cols[j];
15670  assert(col != NULL);
15671  assert(col->nunlinked == 0);
15672 
15674 
15675  c = usefarkas ? 0.0 : col->obj;
15676  SCIPintervalSet(&diff, c);
15677 
15678  for( i = 0; i < col->nlprows; ++i )
15679  {
15680  assert(col->rows[i] != NULL);
15681  assert(col->rows[i]->lppos >= 0);
15682  assert(col->linkpos[i] >= 0);
15683  SCIPintervalSet(&a, col->vals[i]);
15684  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
15685  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
15686  }
15687 
15688 #ifndef NDEBUG
15689  for( i = col->nlprows; i < col->len; ++i )
15690  {
15691  assert(col->rows[i] != NULL);
15692  assert(col->rows[i]->lppos == -1);
15693  assert(col->rows[i]->dualsol == 0.0);
15694  assert(col->rows[i]->dualfarkas == 0.0);
15695  assert(col->linkpos[i] >= 0);
15696  }
15697 #endif
15698 
15699  SCIPintervalSetBounds(&x, col->lb, col->ub);
15700  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
15701  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
15702  }
15703 
15704  /* add y^Tb */
15705  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
15706 
15707  /* free buffer for storing y in interval arithmetic */
15708  SCIPsetFreeBufferArray(set, &yinter);
15709 
15710  *bound = SCIPintervalGetInf(minprod);
15711 
15712  return SCIP_OKAY;
15713 }
15714 
15715 /** gets proven lower (dual) bound of last LP solution */
15717  SCIP_LP* lp, /**< current LP data */
15718  SCIP_SET* set, /**< global SCIP settings */
15719  SCIP_Real* bound /**< pointer to store proven dual bound */
15720  )
15721 {
15722  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
15723 
15724  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
15725 
15726  return SCIP_OKAY;
15727 }
15728 
15729 /** gets proven dual bound of last LP solution */
15731  SCIP_LP* lp, /**< current LP data */
15732  SCIP_SET* set, /**< global SCIP settings */
15733  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
15734  )
15735 {
15736  SCIP_Real bound;
15737 
15738  assert(proved != NULL);
15739 
15740  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
15741 
15742  *proved = (bound > 0.0);
15743 
15744  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
15745 
15746  return SCIP_OKAY;
15747 }
15748 
15749 
15750 
15751 /** writes LP to a file */
15753  SCIP_LP* lp, /**< current LP data */
15754  const char* fname /**< file name */
15755  )
15756 {
15757  assert(lp != NULL);
15758  assert(lp->flushed);
15759  assert(fname != NULL);
15760 
15761  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
15762 
15763  return SCIP_OKAY;
15764 }
15765 
15766 /** writes MIP relaxation of the current B&B node to a file */
15768  SCIP_LP* lp, /**< current LP data */
15769  SCIP_SET* set, /**< global SCIP settings */
15770  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15771  const char* fname, /**< file name */
15772  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
15773  * troubles with reserved symbols? */
15774  SCIP_Bool origobj, /**< should the original objective function be used? */
15775  SCIP_OBJSENSE objsense, /**< objective sense */
15776  SCIP_Real objscale, /**< objective scaling factor */
15777  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
15778  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
15779  )
15780 {
15781  FILE* file;
15782  int i;
15783  int j;
15784  char rowname[SCIP_MAXSTRLEN];
15785  SCIP_Real coeff;
15786 
15787  assert(lp != NULL);
15788  assert(lp->flushed);
15789  assert(fname != NULL);
15790 
15791  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
15792  file = fopen(fname, "w");
15793  if( file == NULL )
15794  {
15795  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
15796  SCIPprintSysError(fname);
15797  return SCIP_FILECREATEERROR;
15798  }
15799 
15800  /* print comments */
15801  if( genericnames )
15802  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
15803  else
15804  {
15805  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
15806  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
15807  }
15808 
15809  if( origobj && objoffset != 0.0 )
15810  {
15811  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
15812  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
15813  }
15814 
15815  /* print objective function */
15816  /**@note the transformed problem in SCIP is always a minimization problem */
15817  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
15818  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
15819  else
15820  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
15821 
15822  /* print objective */
15823  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
15824  j = 0;
15825  for( i = 0; i < lp->ncols; ++i )
15826  {
15827  if( lp->cols[i]->obj != 0.0 )
15828  {
15829  coeff = lp->cols[i]->obj;
15830  if( origobj )
15831  {
15832  coeff *= (SCIP_Real) objsense;
15833  coeff *= objscale;
15834  }
15835 
15836  if( genericnames )
15837  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
15838  else
15839  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
15840 
15841  ++j;
15842  if( j % 10 == 0 )
15843  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15844  }
15845  }
15846  /* add artificial variable 'objoffset' to transfer objective offset */
15847  if( origobj && objoffset != 0.0 )
15848  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
15849 
15850  /* print constraint section */
15851  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
15852  for( i = 0; i < lp->nrows; i++ )
15853  {
15854  char type = 'i';
15855 
15856  /* skip removable rows if we want to write them as lazy constraints */
15857  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
15858  continue;
15859 
15860  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15861  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15862  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15863  * type 'i' means: lhs and rhs are both infinite */
15864  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15865  type = 'r';
15866  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15867  type = 'l';
15868  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15869  type = 'e';
15870  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15871  type = 'b';
15872 
15873  /* print name of row */
15874  if( genericnames )
15875  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15876  else
15877  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15878 
15879  WRITEROW:
15880  switch( type )
15881  {
15882  case 'r':
15883  case 'l':
15884  case 'e':
15885  if( strlen(rowname) > 0 )
15886  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15887  break;
15888  case 'i':
15889  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15890  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15891  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
15892  type = 'b';
15893  /*lint -fallthrough*/
15894  case 'b':
15895  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15896  break;
15897  default:
15898  assert(type == 'B');
15899  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15900  break;
15901  }
15902 
15903  /* print coefficients and variables */
15904  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15905  {
15906  if( genericnames )
15907  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15908  else
15909  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15910 
15911  if( (j+1) % 10 == 0 )
15912  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15913  }
15914 
15915  /* print right hand side */
15916  switch( type )
15917  {
15918  case 'b':
15919  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15920  type = 'B';
15921  goto WRITEROW;
15922  case 'l':
15923  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15924  break;
15925  case 'B':
15926  case 'r':
15927  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15928  break;
15929  case 'e':
15930  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15931  break;
15932  default:
15933  SCIPerrorMessage("Undefined row type!\n");
15934  return SCIP_ERROR;
15935  }
15936  }
15937 
15938  if ( lazyconss )
15939  {
15940  /* print lazy constraint section */
15941  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
15942  for( i = 0; i < lp->nrows; i++ )
15943  {
15944  char type = 'i';
15945 
15946  /* skip non-removable rows if we want to write lazy constraints */
15947  if ( ! SCIProwIsRemovable(lp->rows[i]) )
15948  continue;
15949 
15950  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15951  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15952  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15953  * type 'i' means: lhs and rhs are both infinite */
15954  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15955  type = 'r';
15956  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15957  type = 'l';
15958  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15959  type = 'e';
15960  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15961  type = 'b';
15962 
15963  /* print name of row */
15964  if( genericnames )
15965  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15966  else
15967  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15968 
15969  WRITELAZYROW:
15970  switch( type )
15971  {
15972  case 'r':
15973  case 'l':
15974  case 'e':
15975  if( strlen(rowname) > 0 )
15976  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15977  break;
15978  case 'i':
15979  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15980  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15981  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
15982  type = 'b';
15983  /*lint -fallthrough*/
15984  case 'b':
15985  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15986  break;
15987  default:
15988  assert(type == 'B');
15989  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15990  break;
15991  }
15992 
15993  /* print coefficients and variables */
15994  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15995  {
15996  if( genericnames )
15997  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15998  else
15999  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16000 
16001  if( (j+1) % 10 == 0 )
16002  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16003  }
16004 
16005  /* print right hand side */
16006  switch( type )
16007  {
16008  case 'b':
16009  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16010  type = 'B';
16011  goto WRITELAZYROW;
16012  case 'l':
16013  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16014  break;
16015  case 'B':
16016  case 'r':
16017  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16018  break;
16019  case 'e':
16020  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16021  break;
16022  default:
16023  SCIPerrorMessage("Undefined row type!\n");
16024  return SCIP_ERROR;
16025  }
16026  }
16027  }
16028 
16029  /* print variable bounds */
16030  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16031  for( i = 0; i < lp->ncols; ++i )
16032  {
16033  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16034  {
16035  /* print lower bound as far this one is not infinity */
16036  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16037  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16038 
16039  /* print variable name */
16040  if( genericnames )
16041  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16042  else
16043  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16044 
16045  /* print upper bound as far this one is not infinity */
16046  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16047  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16048  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16049  }
16050  }
16051  if( origobj && objoffset != 0.0 )
16052  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16053 
16054  /* print integer variables */
16055  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16056  j = 0;
16057  for( i = 0; i < lp->ncols; ++i )
16058  {
16059  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16060  {
16061  /* print variable name */
16062  if( genericnames )
16063  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16064  else
16065  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16066 
16067  j++;
16068  if( j % 10 == 0 )
16069  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16070  }
16071  }
16072 
16073  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16074  fclose(file);
16075 
16076  return SCIP_OKAY;
16077 }
16078 
16079 /*
16080  * simple functions implemented as defines
16081  */
16082 
16083 /* In debug mode, the following methods are implemented as function calls to ensure
16084  * type validity.
16085  * In optimized mode, the methods are implemented as defines to improve performance.
16086  * However, we want to have them in the library anyways, so we have to undef the defines.
16087  */
16088 
16089 #undef SCIPcolGetObj
16090 #undef SCIPcolGetLb
16091 #undef SCIPcolGetUb
16092 #undef SCIPcolGetBestBound
16093 #undef SCIPcolGetPrimsol
16094 #undef SCIPcolGetMinPrimsol
16095 #undef SCIPcolGetMaxPrimsol
16096 #undef SCIPcolGetBasisStatus
16097 #undef SCIPcolGetVar
16098 #undef SCIPcolGetIndex
16099 #undef SCIPcolIsIntegral
16100 #undef SCIPcolIsRemovable
16101 #undef SCIPcolGetLPPos
16102 #undef SCIPcolGetLPDepth
16103 #undef SCIPcolIsInLP
16104 #undef SCIPcolGetNNonz
16105 #undef SCIPcolGetNLPNonz
16106 #undef SCIPcolGetRows
16107 #undef SCIPcolGetVals
16108 #undef SCIPcolGetStrongbranchNode
16109 #undef SCIPcolGetNStrongbranchs
16110 #undef SCIPboundtypeOpposite
16111 #undef SCIProwGetNNonz
16112 #undef SCIProwGetNLPNonz
16113 #undef SCIProwGetCols
16114 #undef SCIProwGetVals
16115 #undef SCIProwGetConstant
16116 #undef SCIProwGetNorm
16117 #undef SCIProwGetSumNorm
16118 #undef SCIProwGetLhs
16119 #undef SCIProwGetRhs
16120 #undef SCIProwGetDualsol
16121 #undef SCIProwGetDualfarkas
16122 #undef SCIProwGetBasisStatus
16123 #undef SCIProwGetName
16124 #undef SCIProwGetIndex
16125 #undef SCIProwGetAge
16126 #undef SCIProwGetRank
16127 #undef SCIProwIsIntegral
16128 #undef SCIProwIsLocal
16129 #undef SCIProwIsModifiable
16130 #undef SCIProwIsRemovable
16131 #undef SCIProwGetOrigintype
16132 #undef SCIProwGetOriginCons
16133 #undef SCIProwGetOriginSepa
16134 #undef SCIProwIsInGlobalCutpool
16135 #undef SCIProwGetLPPos
16136 #undef SCIProwGetLPDepth
16137 #undef SCIProwIsInLP
16138 #undef SCIProwGetActiveLPCount
16139 #undef SCIProwGetNLPsAfterCreation
16140 #undef SCIProwChgRank
16141 #undef SCIPlpGetCols
16142 #undef SCIPlpGetNCols
16143 #undef SCIPlpGetRows
16144 #undef SCIPlpGetNRows
16145 #undef SCIPlpGetNewcols
16146 #undef SCIPlpGetNNewcols
16147 #undef SCIPlpGetNewrows
16148 #undef SCIPlpGetNNewrows
16149 #undef SCIPlpGetObjNorm
16150 #undef SCIPlpGetRootObjval
16151 #undef SCIPlpGetRootColumnObjval
16152 #undef SCIPlpGetRootLooseObjval
16153 #undef SCIPlpGetLPI
16154 #undef SCIPlpSetIsRelax
16155 #undef SCIPlpIsRelax
16156 #undef SCIPlpIsSolved
16157 #undef SCIPlpIsSolBasic
16158 #undef SCIPlpDiving
16159 #undef SCIPlpDivingObjChanged
16160 #undef SCIPlpMarkDivingObjChanged
16161 #undef SCIPlpUnmarkDivingObjChanged
16162 #undef SCIPlpDivingRowsChanged
16163 
16164 /** gets objective value of column */
16166  SCIP_COL* col /**< LP column */
16167  )
16168 {
16169  assert(col != NULL);
16170 
16171  return col->obj;
16172 }
16173 
16174 /** gets lower bound of column */
16176  SCIP_COL* col /**< LP column */
16177  )
16178 {
16179  assert(col != NULL);
16180 
16181  return col->lb;
16182 }
16183 
16184 /** gets upper bound of column */
16186  SCIP_COL* col /**< LP column */
16187  )
16188 {
16189  assert(col != NULL);
16190 
16191  return col->ub;
16192 }
16193 
16194 /** gets best bound of column with respect to the objective function */
16196  SCIP_COL* col /**< LP column */
16197  )
16198 {
16199  assert(col != NULL);
16200 
16201  if( col->obj >= 0.0 )
16202  return col->lb;
16203  else
16204  return col->ub;
16205 }
16206 
16207 /** gets the primal LP solution of a column */
16209  SCIP_COL* col /**< LP column */
16210  )
16211 {
16212  assert(col != NULL);
16213 
16214  if( col->lppos >= 0 )
16215  return col->primsol;
16216  else
16217  return 0.0;
16218 }
16219 
16220 /** gets the minimal LP solution value, this column ever assumed */
16222  SCIP_COL* col /**< LP column */
16223  )
16224 {
16225  assert(col != NULL);
16226 
16227  return col->minprimsol;
16228 }
16229 
16230 /** gets the maximal LP solution value, this column ever assumed */
16232  SCIP_COL* col /**< LP column */
16233  )
16234 {
16235  assert(col != NULL);
16236 
16237  return col->maxprimsol;
16238 }
16239 
16240 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16241  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16242  */
16244  SCIP_COL* col /**< LP column */
16245  )
16246 {
16247  assert(col != NULL);
16248  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16249 
16250  return (SCIP_BASESTAT)col->basisstatus;
16251 }
16252 
16253 /** gets variable this column represents */
16255  SCIP_COL* col /**< LP column */
16256  )
16257 {
16258  assert(col != NULL);
16259 
16260  return col->var;
16261 }
16262 
16263 /** gets unique index of col */
16265  SCIP_COL* col /**< LP col */
16266  )
16267 {
16268  assert(col != NULL);
16269 
16270  return col->index;
16271 }
16272 
16273 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16275  SCIP_COL* col /**< LP column */
16276  )
16277 {
16278  assert(col != NULL);
16279  assert(SCIPvarIsIntegral(col->var) == col->integral);
16280 
16281  return col->integral;
16282 }
16283 
16284 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16286  SCIP_COL* col /**< LP column */
16287  )
16288 {
16289  assert(col != NULL);
16290 
16291  return col->removable;
16292 }
16293 
16294 /** gets position of column in current LP, or -1 if it is not in LP */
16296  SCIP_COL* col /**< LP column */
16297  )
16298 {
16299  assert(col != NULL);
16300  assert((col->lppos == -1) == (col->lpdepth == -1));
16301 
16302  return col->lppos;
16303 }
16304 
16305 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16307  SCIP_COL* col /**< LP column */
16308  )
16309 {
16310  assert(col != NULL);
16311  assert((col->lppos == -1) == (col->lpdepth == -1));
16312 
16313  return col->lpdepth;
16314 }
16315 
16316 /** returns TRUE iff column is member of current LP */
16318  SCIP_COL* col /**< LP column */
16319  )
16320 {
16321  assert(col != NULL);
16322  assert((col->lppos == -1) == (col->lpdepth == -1));
16323 
16324  return (col->lppos >= 0);
16325 }
16326 
16327 /** get number of nonzero entries in column vector */
16329  SCIP_COL* col /**< LP column */
16330  )
16331 {
16332  assert(col != NULL);
16333 
16334  return col->len;
16335 }
16336 
16337 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16338  *
16339  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16340  * 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
16341  */
16343  SCIP_COL* col /**< LP column */
16344  )
16345 {
16346  assert(col != NULL);
16347  assert(col->nunlinked == 0);
16348 
16349  return col->nlprows;
16350 }
16351 
16352 /** gets array with rows of nonzero entries */
16354  SCIP_COL* col /**< LP column */
16355  )
16356 {
16357  assert(col != NULL);
16358 
16359  return col->rows;
16360 }
16361 
16362 /** gets array with coefficients of nonzero entries */
16364  SCIP_COL* col /**< LP column */
16365  )
16366 {
16367  assert(col != NULL);
16368 
16369  return col->vals;
16370 }
16371 
16372 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16373  * given column, or -1 if strong branching was never applied to the column in current run
16374  */
16376  SCIP_COL* col /**< LP column */
16377  )
16378 {
16379  assert(col != NULL);
16380 
16381  return col->sbnode;
16382 }
16383 
16384 /** gets number of times, strong branching was applied in current run on the given column */
16386  SCIP_COL* col /**< LP column */
16387  )
16388 {
16389  assert(col != NULL);
16390 
16391  return col->nsbcalls;
16392 }
16393 
16394 /** gets opposite bound type of given bound type */
16396  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16397  )
16398 {
16399  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16400 
16402 }
16403 
16404 /** get number of nonzero entries in row vector */
16406  SCIP_ROW* row /**< LP row */
16407  )
16408 {
16409  assert(row != NULL);
16410 
16411  return row->len;
16412 }
16413 
16414 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16415  *
16416  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16417  * 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
16418  */
16420  SCIP_ROW* row /**< LP row */
16421  )
16422 {
16423  assert(row != NULL);
16424  assert(row->nunlinked == 0);
16425 
16426  return row->nlpcols;
16427 }
16428 
16429 /** gets array with columns of nonzero entries */
16431  SCIP_ROW* row /**< LP row */
16432  )
16433 {
16434  assert(row != NULL);
16435 
16436  return row->cols;
16437 }
16438 
16439 /** gets array with coefficients of nonzero entries */
16441  SCIP_ROW* row /**< LP row */
16442  )
16443 {
16444  assert(row != NULL);
16445 
16446  return row->vals;
16447 }
16448 
16449 /** gets constant shift of row */
16451  SCIP_ROW* row /**< LP row */
16452  )
16453 {
16454  assert(row != NULL);
16455 
16456  return row->constant;
16457 }
16458 
16459 /** gets Euclidean norm of row vector */
16461  SCIP_ROW* row /**< LP row */
16462  )
16463 {
16464  assert(row != NULL);
16465 
16466  checkRowSqrnorm(row);
16467 
16468  return sqrt(row->sqrnorm);
16469 }
16470 
16471 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16473  SCIP_ROW* row /**< LP row */
16474  )
16475 {
16476  assert(row != NULL);
16477 
16478  checkRowSumnorm(row);
16479 
16480  return row->sumnorm;
16481 }
16482 
16483 /** returns the left hand side of the row */
16485  SCIP_ROW* row /**< LP row */
16486  )
16487 {
16488  assert(row != NULL);
16489 
16490  return row->lhs;
16491 }
16492 
16493 /** returns the right hand side of the row */
16495  SCIP_ROW* row /**< LP row */
16496  )
16497 {
16498  assert(row != NULL);
16499 
16500  return row->rhs;
16501 }
16502 
16503 /** gets the dual LP solution of a row */
16505  SCIP_ROW* row /**< LP row */
16506  )
16507 {
16508  assert(row != NULL);
16509 
16510  if( row->lppos >= 0 )
16511  return row->dualsol;
16512  else
16513  return 0.0;
16514 }
16515 
16516 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16518  SCIP_ROW* row /**< LP row */
16519  )
16520 {
16521  assert(row != NULL);
16522 
16523  if( row->lppos >= 0 )
16524  return row->dualfarkas;
16525  else
16526  return 0.0;
16527 }
16528 
16529 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16530  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
16531  */
16533  SCIP_ROW* row /**< LP row */
16534  )
16535 {
16536  assert(row != NULL);
16537  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
16538 
16539  return (SCIP_BASESTAT)row->basisstatus;
16540 }
16541 
16542 /** returns the name of the row */
16543 const char* SCIProwGetName(
16544  SCIP_ROW* row /**< LP row */
16545  )
16546 {
16547  assert(row != NULL);
16548 
16549  return row->name;
16550 }
16551 
16552 /** gets unique index of row */
16554  SCIP_ROW* row /**< LP row */
16555  )
16556 {
16557  assert(row != NULL);
16558 
16559  return row->index;
16560 }
16561 
16562 /** gets age of row */
16564  SCIP_ROW* row /**< LP row */
16565  )
16566 {
16567  assert(row != NULL);
16568 
16569  return row->age;
16570 }
16571 
16572 /** gets rank of row */
16574  SCIP_ROW* row /**< LP row */
16575  )
16576 {
16577  assert(row != NULL);
16578 
16579  return row->rank;
16580 }
16581 
16582 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
16584  SCIP_ROW* row /**< LP row */
16585  )
16586 {
16587  assert(row != NULL);
16588 
16589  return row->integral;
16590 }
16591 
16592 /** returns TRUE iff row is only valid locally */
16594  SCIP_ROW* row /**< LP row */
16595  )
16596 {
16597  assert(row != NULL);
16598 
16599  return row->local;
16600 }
16601 
16602 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
16604  SCIP_ROW* row /**< LP row */
16605  )
16606 {
16607  assert(row != NULL);
16608 
16609  return row->modifiable;
16610 }
16611 
16612 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
16614  SCIP_ROW* row /**< LP row */
16615  )
16616 {
16617  assert(row != NULL);
16618 
16619  return row->removable;
16620 }
16621 
16622 /** returns type of origin that created the row */
16624  SCIP_ROW* row /**< LP row */
16625  )
16626 {
16627  assert( row != NULL );
16628 
16629  return (SCIP_ROWORIGINTYPE) row->origintype;
16630 }
16631 
16632 /** returns origin constraint handler that created the row (NULL if not available) */
16634  SCIP_ROW* row /**< LP row */
16635  )
16636 {
16637  assert( row != NULL );
16638 
16640  {
16641  assert( row->origin != NULL );
16642  return (SCIP_CONSHDLR*) row->origin;
16643  }
16644  return NULL;
16645 }
16646 
16647 /** returns origin separator that created the row (NULL if not available) */
16649  SCIP_ROW* row /**< LP row */
16650  )
16651 {
16652  assert( row != NULL );
16653 
16655  {
16656  assert( row->origin != NULL );
16657  return (SCIP_SEPA*) row->origin;
16658  }
16659  return NULL;
16660 }
16661 
16662 /** returns TRUE iff row is member of the global cut pool */
16664  SCIP_ROW* row /**< LP row */
16665  )
16666 {
16667  assert(row != NULL);
16668 
16669  return row->inglobalcutpool;
16670 }
16671 
16672 /** gets position of row in current LP, or -1 if it is not in LP */
16674  SCIP_ROW* row /**< LP row */
16675  )
16676 {
16677  assert(row != NULL);
16678  assert((row->lppos == -1) == (row->lpdepth == -1));
16679 
16680  return row->lppos;
16681 }
16682 
16683 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
16685  SCIP_ROW* row /**< LP row */
16686  )
16687 {
16688  assert(row != NULL);
16689  assert((row->lppos == -1) == (row->lpdepth == -1));
16690 
16691  return row->lpdepth;
16692 }
16693 
16694 /** returns TRUE iff row is member of current LP */
16696  SCIP_ROW* row /**< LP row */
16697  )
16698 {
16699  assert(row != NULL);
16700  assert((row->lppos == -1) == (row->lpdepth == -1));
16701 
16702  return (row->lppos >= 0);
16703 }
16704 
16705 /** changes the rank of LP row */
16707  SCIP_ROW* row, /**< LP row */
16708  int rank /**< new value for rank */
16709  )
16710 {
16711  assert(row != NULL);
16712 
16713  row->rank = rank;
16714 }
16715 
16716 /** returns the number of times that this row has been sharp in an optimal LP solution */
16718  SCIP_ROW* row /**< row */
16719  )
16720 {
16721  assert(row != NULL);
16722 
16723  return row->activeinlpcounter;
16724 }
16725 
16726 /** returns the number of LPs since this row has been created */
16728  SCIP_ROW* row /**< row */
16729  )
16730 {
16731  assert(row != NULL);
16732 
16733  return row->nlpsaftercreation;
16734 }
16735 
16736 /** gets array with columns of the LP */
16738  SCIP_LP* lp /**< current LP data */
16739  )
16740 {
16741  assert(lp != NULL);
16742 
16743  return lp->cols;
16744 }
16745 
16746 /** gets current number of columns in LP */
16748  SCIP_LP* lp /**< current LP data */
16749  )
16750 {
16751  assert(lp != NULL);
16752 
16753  return lp->ncols;
16754 }
16755 
16756 /** gets array with rows of the LP */
16758  SCIP_LP* lp /**< current LP data */
16759  )
16760 {
16761  assert(lp != NULL);
16762 
16763  return lp->rows;
16764 }
16765 
16766 /** gets current number of rows in LP */
16768  SCIP_LP* lp /**< current LP data */
16769  )
16770 {
16771  assert(lp != NULL);
16772 
16773  return lp->nrows;
16774 }
16775 
16776 /** gets array with newly added columns after the last mark */
16778  SCIP_LP* lp /**< current LP data */
16779  )
16780 {
16781  assert(lp != NULL);
16782  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16783 
16784  return &(lp->cols[lp->firstnewcol]);
16785 }
16786 
16787 /** gets number of newly added columns after the last mark */
16789  SCIP_LP* lp /**< current LP data */
16790  )
16791 {
16792  assert(lp != NULL);
16793  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16794 
16795  return lp->ncols - lp->firstnewcol;
16796 }
16797 
16798 /** gets array with newly added rows after the last mark */
16800  SCIP_LP* lp /**< current LP data */
16801  )
16802 {
16803  assert(lp != NULL);
16804  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16805 
16806  return &(lp->rows[lp->firstnewrow]);
16807 }
16808 
16809 /** gets number of newly added rows after the last mark */
16811  SCIP_LP* lp /**< current LP data */
16812  )
16813 {
16814  assert(lp != NULL);
16815  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16816 
16817  return lp->nrows - lp->firstnewrow;
16818 }
16819 
16820 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
16822  SCIP_SET* set, /**< global SCIP settings */
16823  SCIP_LP* lp /**< LP data */
16824  )
16825 {
16826  if( lp->objsqrnormunreliable )
16827  {
16828  SCIP_COL** cols;
16829  int c;
16830 
16831  cols = lp->cols;
16832  assert(cols != NULL || lp->ncols == 0);
16833 
16834  lp->objsqrnorm = 0.0;
16835 
16836  for( c = lp->ncols - 1; c >= 0; --c )
16837  {
16838  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
16839  }
16840  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
16841 
16842  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
16843  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
16844 
16846  }
16847  return;
16848 }
16849 
16850 /** gets Euclidean norm of objective function vector of column variables, only use this method if
16851  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
16853  SCIP_LP* lp /**< LP data */
16854  )
16855 {
16856  assert(lp != NULL);
16857  assert(!lp->objsqrnormunreliable);
16858  assert(lp->objsqrnorm >= 0.0);
16859 
16860  return SQRT(lp->objsqrnorm);
16861 }
16862 
16863 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16865  SCIP_LP* lp, /**< LP data */
16866  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
16867  )
16868 {
16869  assert(lp != NULL);
16870 
16871  lp->rootlpisrelax = isrelax;
16872 }
16873 
16874 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16876  SCIP_LP* lp /**< LP data */
16877  )
16878 {
16879  assert(lp != NULL);
16880 
16881  return lp->rootlpisrelax;
16882 }
16883 
16884 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
16886  SCIP_LP* lp /**< LP data */
16887  )
16888 {
16889  assert(lp != NULL);
16890 
16891  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
16892 }
16893 
16894 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
16895  * returns SCIP_INVALID if the root node LP was not (yet) solved
16896  */
16898  SCIP_LP* lp /**< LP data */
16899  )
16900 {
16901  assert(lp != NULL);
16902 
16903  return lp->rootlpobjval;
16904 }
16905 
16906 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
16907  * returns SCIP_INVALID if the root node LP was not (yet) solved
16908  */
16910  SCIP_LP* lp /**< LP data */
16911  )
16912 {
16913  assert(lp != NULL);
16914 
16915  return lp->rootlooseobjval;
16916 }
16917 
16918 /** gets the LP solver interface */
16920  SCIP_LP* lp /**< current LP data */
16921  )
16922 {
16923  assert(lp != NULL);
16924 
16925  return lp->lpi;
16926 }
16927 
16928 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
16930  SCIP_LP* lp, /**< LP data */
16931  SCIP_Bool relax /**< is the current lp a relaxation? */
16932  )
16933 {
16934  assert(lp != NULL);
16935 
16936  lp->isrelax = relax;
16937 }
16938 
16939 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
16940  * solution value a valid local lower bound?
16941  */
16943  SCIP_LP* lp /**< LP data */
16944  )
16945 {
16946  assert(lp != NULL);
16947 
16948  return lp->isrelax;
16949 }
16950 
16951 /** returns whether the current LP is flushed and solved */
16953  SCIP_LP* lp /**< current LP data */
16954  )
16955 {
16956  assert(lp != NULL);
16957 
16958  return lp->flushed && lp->solved;
16959 }
16960 
16961 /** return whether the current LP solution passed the primal feasibility check */
16963  SCIP_LP* lp /**< current LP data */
16964  )
16965 {
16966  assert(lp != NULL);
16967 
16968  return (lp->primalchecked && lp->primalfeasible);
16969 }
16970 
16971 /** return whether the current LP solution passed the dual feasibility check */
16973  SCIP_LP* lp /**< current LP data */
16974  )
16975 {
16976  assert(lp != NULL);
16977 
16978  return (lp->dualchecked && lp->dualfeasible);
16979 }
16980 
16981 /** returns whether the current LP solution is a basic solution */
16983  SCIP_LP* lp /**< current LP data */
16984  )
16985 {
16986  assert(lp != NULL);
16987 
16988  return lp->solisbasic;
16989 }
16990 
16991 /** returns whether the LP is in diving mode */
16993  SCIP_LP* lp /**< current LP data */
16994  )
16995 {
16996  assert(lp != NULL);
16997 
16998  return lp->diving;
16999 }
17000 
17001 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17003  SCIP_LP* lp /**< current LP data */
17004  )
17005 {
17006  assert(lp != NULL);
17007 
17008  return lp->divingobjchg;
17009 }
17010 
17011 /** marks the diving LP to have a changed objective function */
17013  SCIP_LP* lp /**< current LP data */
17014  )
17015 {
17016  assert(lp != NULL);
17017  assert(lp->diving || lp->probing);
17018 
17019  lp->divingobjchg = TRUE;
17020 }
17021 
17022 /** marks the diving LP to not have a changed objective function anymore */
17024  SCIP_LP* lp /**< current LP data */
17025  )
17026 {
17027  assert(lp != NULL);
17028  assert(lp->diving || lp->probing);
17029 
17030  lp->divingobjchg = FALSE;
17031 }
17032 
17033 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17035  SCIP_LP* lp /**< current LP data */
17036  )
17037 {
17038  assert(lp != NULL);
17039  assert(lp->diving || lp->ndivechgsides == 0);
17040 
17041  return (lp->ndivechgsides > 0);
17042 }
17043 
17044 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17045 static
17047  SCIP_LPI* lpi, /**< auxiliary LP interface */
17048  SCIP_SET* set, /**< global SCIP settings */
17049  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17050  SCIP_LP* lp, /**< LP data */
17051  SCIP_PROB* prob, /**< problem data */
17052  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17053  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17054  SCIP_Real timelimit, /**< time limit for LP solver */
17055  int iterlimit, /**< iteration limit for LP solver */
17056  SCIP_Real* point, /**< array to store relative interior point on exit */
17057  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17058  )
17059 {
17060  SCIP_RETCODE retcode;
17061  SCIP_Real* primal;
17062  SCIP_Real* obj;
17063  SCIP_Real* lb;
17064  SCIP_Real* ub;
17065  SCIP_Real* matvals;
17066  SCIP_Real* matlhs;
17067  SCIP_Real* matrhs;
17068  SCIP_Real objval;
17069  SCIP_Real alpha;
17070  int* matinds;
17071  int* matbeg;
17072 #ifndef NDEBUG
17073  int nslacks;
17074 #endif
17075  int nnewcols;
17076  int ntotnonz = 0;
17077  int ntotrows = 0;
17078  int matrowidx;
17079  int matidx;
17080  int cnt;
17081  int j;
17082  int i;
17083 
17084  assert(lpi != NULL);
17085 
17087  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17088  {
17089  SCIP_CALL( retcode );
17090  }
17091 
17093  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17094  {
17095  SCIP_CALL( retcode );
17096  }
17097 
17098  /* get storage */
17099  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17100  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17101  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17102  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17103 
17104  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17105  for( j = 0; j < lp->ncols; ++j )
17106  {
17107  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17108  obj[j] = 0.0;
17109  lb[j] = -SCIPlpiInfinity(lpi);
17110  ub[j] = SCIPlpiInfinity(lpi);
17111  /* note: we could also use the original bounds - free variables seem to be faster. */
17112  }
17113 
17114  /* add artificial alpha variable */
17115  nnewcols = lp->ncols;
17116  obj[nnewcols] = 0.0;
17117  lb[nnewcols] = 1.0;
17118  ub[nnewcols] = SCIPlpiInfinity(lpi);
17119  ++nnewcols;
17120 
17121  /* create slacks for rows */
17122  for( i = 0; i < lp->nrows; ++i )
17123  {
17124  SCIP_ROW* row;
17125 
17126  row = lp->rows[i];
17127  assert( row != NULL );
17128 
17129  if( SCIProwIsModifiable(row) )
17130  continue;
17131 
17132  /* make sure row is sorted */
17133  rowSortLP(row);
17134  assert( row->lpcolssorted );
17135 
17136  /* check whether we have an equation */
17137  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17138  {
17139  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17140  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17141  ntotnonz += row->nlpcols + 1;
17142  ++ntotrows;
17143  }
17144  else
17145  {
17146  /* otherwise add slacks for each side if necessary */
17147  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17148  {
17149  if ( relaxrows )
17150  {
17151  lb[nnewcols] = 0.0;
17152  ub[nnewcols] = 1.0;
17153  obj[nnewcols++] = 1.0;
17154  ntotnonz += row->nlpcols + 2;
17155  }
17156  else
17157  ntotnonz += row->nlpcols + 1;
17158  ++ntotrows;
17159  }
17160  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17161  {
17162  if ( relaxrows )
17163  {
17164  lb[nnewcols] = 0.0;
17165  ub[nnewcols] = 1.0;
17166  obj[nnewcols++] = 1.0;
17167  ntotnonz += row->nlpcols + 2;
17168  }
17169  else
17170  ntotnonz += row->nlpcols + 1;
17171  ++ntotrows;
17172  }
17173  }
17174  }
17175 
17176  /* create slacks for objective cutoff row */
17177  if( inclobjcutoff && relaxrows )
17178  {
17179  /* add slacks for right hand side */
17180  lb[nnewcols] = 0.0;
17181  ub[nnewcols] = 1.0;
17182  obj[nnewcols++] = 1.0;
17183  ntotnonz += lp->ncols + 2;
17184  ++ntotrows;
17185  }
17186 
17187  /* create slacks for bounds */
17188  for( j = 0; j < lp->ncols; ++j )
17189  {
17190  SCIP_COL* col;
17191 
17192  col = lp->cols[j];
17193  assert( col != NULL );
17194 
17195  /* no slacks for fixed variables */
17196  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17197  {
17198  ++ntotrows;
17199  ntotnonz += 2;
17200  }
17201  else
17202  {
17203  /* add slacks for each bound if necessary */
17204  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17205  {
17206  lb[nnewcols] = 0.0;
17207  ub[nnewcols] = 1.0;
17208  obj[nnewcols++] = 1.0;
17209  ntotnonz += 3;
17210  ++ntotrows;
17211  }
17212  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
17213  {
17214  lb[nnewcols] = 0.0;
17215  ub[nnewcols] = 1.0;
17216  obj[nnewcols++] = 1.0;
17217  ntotnonz += 3;
17218  ++ntotrows;
17219  }
17220  }
17221  }
17222 #ifndef NDEBUG
17223  nslacks = nnewcols - lp->ncols - 1;
17224  assert( nslacks >= 0 );
17225  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17226 #endif
17227 
17228  /* add columns */
17229  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17230 
17231  /* free storage */
17232  SCIPsetFreeBufferArray(set, &obj);
17233  SCIPsetFreeBufferArray(set, &ub);
17234  SCIPsetFreeBufferArray(set, &lb);
17235 
17236  /* prepare storage for rows */
17237  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
17238  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
17239  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
17240  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
17241  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
17242 
17243  /* create rows arising from original rows */
17244  cnt = 0;
17245  matrowidx = 0;
17246  matidx = 0;
17247  for( i = 0; i < lp->nrows; ++i )
17248  {
17249  SCIP_ROW* row;
17250  SCIP_COL** rowcols;
17251  SCIP_Real* rowvals;
17252  SCIP_Real lhs;
17253  SCIP_Real rhs;
17254  int nnonz;
17255 
17256  row = lp->rows[i];
17257  assert( row != NULL );
17258 
17259  if( SCIProwIsModifiable(row) )
17260  continue;
17261  assert( row->lpcolssorted );
17262 
17263  /* get row data */
17264  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17265  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17266  nnonz = row->nlpcols;
17267  assert( nnonz <= lp->ncols );
17268  rowcols = row->cols;
17269  rowvals = row->vals;
17270 
17271  /* if we have an equation */
17272  if( SCIPsetIsEQ(set, lhs, rhs) )
17273  {
17274  /* set up indices */
17275  matbeg[matrowidx] = matidx;
17276  for( j = 0; j < nnonz; ++j )
17277  {
17278  assert( rowcols[j] != NULL );
17279  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17280  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17281  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17282  matinds[matidx] = rowcols[j]->lppos;
17283  matvals[matidx++] = rowvals[j];
17284  assert( matidx <= ntotnonz );
17285  }
17286 
17287  /* add artificial variable */
17288  if ( ! SCIPsetIsZero(set, rhs) )
17289  {
17290  matinds[matidx] = lp->ncols;
17291  matvals[matidx++] = -rhs;
17292  assert( matidx <= ntotnonz );
17293  }
17294 
17295  matlhs[matrowidx] = 0.0;
17296  matrhs[matrowidx++] = 0.0;
17297  assert( matrowidx <= ntotrows );
17298  }
17299  else
17300  {
17301  SCIP_Real abslhs = REALABS(lhs);
17302  SCIP_Real absrhs = REALABS(rhs);
17303 
17304  assert(!SCIPsetIsEQ(set, lhs, rhs));
17305 
17306  /* treat lhs */
17307  if( !SCIPsetIsInfinity(set, abslhs) )
17308  {
17309  /* set up indices */
17310  matbeg[matrowidx] = matidx;
17311  for( j = 0; j < nnonz; ++j )
17312  {
17313  assert( rowcols[j] != NULL );
17314  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17315  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17316  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17317  matinds[matidx] = rowcols[j]->lppos;
17318  matvals[matidx++] = rowvals[j];
17319  assert( matidx <= ntotnonz );
17320  }
17321 
17322  /* add artificial variable */
17323  if ( ! SCIPsetIsZero(set, lhs) )
17324  {
17325  matinds[matidx] = lp->ncols;
17326  matvals[matidx++] = -lhs;
17327  assert( matidx <= ntotnonz );
17328  }
17329 
17330  if( relaxrows )
17331  {
17332  /* add slack variable */
17333  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
17334  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17335  assert( matidx <= ntotnonz );
17336  ++cnt;
17337  }
17338 
17339  matlhs[matrowidx] = 0.0;
17340  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
17341  assert( matrowidx <= ntotrows );
17342  }
17343 
17344  /* treat rhs */
17345  if( !SCIPsetIsInfinity(set, absrhs) )
17346  {
17347  /* set up indices */
17348  matbeg[matrowidx] = matidx;
17349  for( j = 0; j < nnonz; ++j )
17350  {
17351  assert( rowcols[j] != NULL );
17352  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17353  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17354  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17355  matinds[matidx] = rowcols[j]->lppos;
17356  matvals[matidx++] = rowvals[j];
17357  assert( matidx <= ntotnonz );
17358  }
17359 
17360  /* add artificial variable */
17361  if ( ! SCIPsetIsZero(set, rhs) )
17362  {
17363  matinds[matidx] = lp->ncols;
17364  matvals[matidx++] = -rhs;
17365  assert( matidx <= ntotnonz );
17366  }
17367 
17368  if( relaxrows )
17369  {
17370  /* add slack variable */
17371  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
17372  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17373  ++cnt;
17374  }
17375 
17376  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
17377  matrhs[matrowidx++] = 0.0;
17378  assert( matrowidx <= ntotrows );
17379  }
17380  }
17381  }
17382 
17383  /* create row arising from objective cutoff */
17384  if( inclobjcutoff )
17385  {
17386  SCIP_Real rhs;
17387 
17388  /* get row data */
17389  assert(lp->looseobjvalinf == 0);
17390  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17391 
17392  /* set up indices and coefficients */
17393  matbeg[matrowidx] = matidx;
17394  for( j = 0; j < lp->ncols; ++j )
17395  {
17396  assert( lp->cols[j] != NULL );
17397  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17398  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17399 
17400  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
17401  {
17402  matinds[matidx] = lp->cols[j]->lppos;
17403  matvals[matidx++] = lp->cols[j]->obj;
17404  assert( matidx <= ntotnonz );
17405  }
17406  }
17407 
17408  /* treat rhs */
17409 
17410  /* add artificial variable */
17411  if ( ! SCIPsetIsZero(set, rhs) )
17412  {
17413  matinds[matidx] = lp->ncols;
17414  matvals[matidx++] = -rhs;
17415  assert( matidx <= ntotnonz );
17416  }
17417 
17418  if( relaxrows )
17419  {
17420  SCIP_Real absrhs = REALABS(rhs);
17421 
17422  /* add slack variable */
17423  matvals[matidx] = MAX(1.0, absrhs);
17424  matinds[matidx++] = lp->ncols + 1 + cnt;
17425  assert( matidx <= ntotnonz );
17426  ++cnt;
17427  }
17428  matlhs[matrowidx] = -SCIPsetInfinity(set);
17429  matrhs[matrowidx++] = 0.0;
17430  assert( matrowidx <= ntotrows );
17431  }
17432 
17433  /* create rows arising from bounds */
17434  for( j = 0; j < lp->ncols; ++j )
17435  {
17436  SCIP_COL* col;
17437  SCIP_Real abscollb;
17438  SCIP_Real abscolub;
17439 
17440  col = lp->cols[j];
17441  assert( col != NULL );
17442  assert( col->lppos == j );
17443 
17444  /* fixed variable */
17445  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17446  {
17447  /* set up index of column */
17448  matbeg[matrowidx] = matidx;
17449 
17450  matinds[matidx] = j;
17451  matvals[matidx++] = 1.0;
17452  assert( matidx <= ntotnonz );
17453 
17454  /* add artificial variable */
17455  if ( ! SCIPsetIsZero(set, col->ub) )
17456  {
17457  matinds[matidx] = lp->ncols;
17458  matvals[matidx++] = -col->lb;
17459  assert( matidx <= ntotnonz );
17460  }
17461 
17462  matlhs[matrowidx] = 0.0;
17463  matrhs[matrowidx++] = 0.0;
17464  assert( matrowidx <= ntotrows );
17465 
17466  continue;
17467  }
17468 
17469  abscollb = REALABS(col->lb);
17470  abscolub = REALABS(col->ub);
17471 
17472  /* lower bound */
17473  if ( ! SCIPsetIsInfinity(set, abscollb) )
17474  {
17475  /* set up index of column */
17476  matbeg[matrowidx] = matidx;
17477 
17478  matinds[matidx] = j;
17479  matvals[matidx++] = 1.0;
17480  assert( matidx <= ntotnonz );
17481 
17482  /* add artificial variable */
17483  if ( ! SCIPsetIsZero(set, col->lb) )
17484  {
17485  matinds[matidx] = lp->ncols;
17486  matvals[matidx++] = -col->lb;
17487  assert( matidx <= ntotnonz );
17488  }
17489 
17490  /* add slack variable */
17491  matvals[matidx] = -MAX(1.0, abscollb);
17492  matinds[matidx++] = lp->ncols + 1 + cnt;
17493  assert( matidx <= ntotnonz );
17494  ++cnt;
17495 
17496  matlhs[matrowidx] = 0.0;
17497  matrhs[matrowidx++] = SCIPsetInfinity(set);
17498  assert( matrowidx <= ntotrows );
17499  }
17500 
17501  /* upper bound */
17502  if ( ! SCIPsetIsInfinity(set, abscolub) )
17503  {
17504  /* set up index of column */
17505  matbeg[matrowidx] = matidx;
17506 
17507  matinds[matidx] = j;
17508  matvals[matidx++] = 1.0;
17509  assert( matidx <= ntotnonz );
17510 
17511  /* add artificial variable */
17512  if ( ! SCIPsetIsZero(set, col->ub) )
17513  {
17514  matinds[matidx] = lp->ncols;
17515  matvals[matidx++] = -col->ub;
17516  assert( matidx <= ntotnonz );
17517  }
17518 
17519  /* add slack variable */
17520  matvals[matidx] = MAX(1.0, abscolub);
17521  matinds[matidx++] = lp->ncols + 1 + cnt;
17522  assert( matidx <= ntotnonz );
17523  ++cnt;
17524 
17525  matlhs[matrowidx] = -SCIPsetInfinity(set);
17526  matrhs[matrowidx++] = 0.0;
17527  assert( matrowidx <= ntotrows );
17528  }
17529  }
17530  assert( cnt == nslacks );
17531  assert( matrowidx == ntotrows );
17532 
17533  /* add rows */
17534  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
17535 
17536  SCIPsetFreeBufferArray(set, &matrhs);
17537  SCIPsetFreeBufferArray(set, &matlhs);
17538  SCIPsetFreeBufferArray(set, &matbeg);
17539  SCIPsetFreeBufferArray(set, &matvals);
17540  SCIPsetFreeBufferArray(set, &matinds);
17541 
17542 #ifdef SCIP_OUTPUT
17543  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
17544 #endif
17545 
17546 #ifndef NDEBUG
17547  {
17548  int ncols;
17549  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
17550  assert( ncols == nnewcols );
17551  }
17552 #endif
17553 
17554  /* set time limit */
17555  if( SCIPsetIsInfinity(set, timelimit) )
17556  timelimit = SCIPlpiInfinity(lpi);
17557  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
17558 
17559  /* check, if parameter is unknown */
17560  if ( retcode == SCIP_PARAMETERUNKNOWN )
17561  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
17562 
17563  /* set iteration limit */
17564  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
17565 
17566  /* check, if parameter is unknown */
17567  if ( retcode == SCIP_PARAMETERUNKNOWN )
17568  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
17569 
17570  /* solve and store point */
17571  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
17572  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
17573 
17574 #ifndef NDEBUG
17575  if ( SCIPlpiIsIterlimExc(lpi) )
17576  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
17577  if ( SCIPlpiIsTimelimExc(lpi) )
17578  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
17579 #endif
17580 
17581  if( SCIPlpiIsOptimal(lpi) )
17582  {
17583  /* get primal solution */
17584  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
17585  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
17586  alpha = primal[lp->ncols];
17587  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
17588 
17589  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
17590 
17591  /* construct relative interior point */
17592  for( j = 0; j < lp->ncols; ++j )
17593  point[j] = primal[j]/alpha;
17594 
17595 #ifdef SCIP_DEBUG
17596  /* check whether the point is a relative interior point */
17597  cnt = 0;
17598  if( relaxrows )
17599  {
17600  for( i = 0; i < lp->nrows; ++i )
17601  {
17602  SCIP_ROW* row;
17603  SCIP_COL** rowcols;
17604  SCIP_Real* rowvals;
17605  SCIP_Real lhs;
17606  SCIP_Real rhs;
17607  SCIP_Real sum;
17608  int nnonz;
17609 
17610  row = lp->rows[i];
17611  assert( row != NULL );
17612 
17613  /* get row data */
17614  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17615  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17616  nnonz = row->nlpcols;
17617  assert( nnonz <= lp->ncols );
17618  rowcols = row->cols;
17619  rowvals = row->vals;
17620 
17621  sum = 0.0;
17622  for( j = 0; j < nnonz; ++j )
17623  sum += rowvals[j] * primal[rowcols[j]->lppos];
17624  sum /= alpha;
17625 
17626  /* if we have an equation */
17627  if( SCIPsetIsEQ(set, lhs, rhs) )
17628  {
17629  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
17630  }
17631  else
17632  {
17633  /* treat lhs */
17634  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
17635  {
17636  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
17637  ++cnt;
17638  }
17639  /* treat rhs */
17640  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
17641  {
17642  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17643  ++cnt;
17644  }
17645  }
17646  }
17647  if( inclobjcutoff )
17648  {
17649  SCIP_Real sum;
17650 #ifndef NDEBUG
17651  SCIP_Real rhs;
17652 
17653  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17654 #endif
17655  sum = 0.0;
17656  for( j = 0; j < lp->ncols; ++j )
17657  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
17658  sum /= alpha;
17659 
17660  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17661  ++cnt;
17662  }
17663  }
17664  /* check bounds */
17665  for( j = 0; j < lp->ncols; ++j )
17666  {
17667  SCIP_COL* col;
17668 #ifndef NDEBUG
17669  SCIP_Real val;
17670 #endif
17671 
17672  col = lp->cols[j];
17673  assert( col != NULL );
17674 #ifndef NDEBUG
17675  val = primal[col->lppos] / alpha;
17676 #endif
17677  /* if the variable is not fixed */
17678  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
17679  {
17680  /* treat lb */
17681  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17682  {
17683  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
17684  ++cnt;
17685  }
17686  /* treat rhs */
17687  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17688  {
17689  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
17690  ++cnt;
17691  }
17692  }
17693  }
17694 #endif
17695 
17696  /* free */
17697  SCIPsetFreeBufferArray(set, &primal);
17698 
17699  *success = TRUE;
17700  }
17701 
17702  return SCIP_OKAY;
17703 }
17704 
17705 /** compute relative interior point
17706  *
17707  * We use the approach of@par
17708  * R. Freund, R. Roundy, M. J. Todd@par
17709  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
17710  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
17711  *
17712  * to compute a relative interior point for the current LP.
17713  *
17714  * Assume the original LP looks as follows:
17715  * \f[
17716  * \begin{array}{rrl}
17717  * \min & c^T x &\\
17718  * & A x & \geq a\\
17719  * & B x & \leq b\\
17720  * & D x & = d.
17721  * \end{array}
17722  * \f]
17723  * Note that bounds should be included in the system.
17724  *
17725  * To find an interior point the following LP does the job:
17726  * \f[
17727  * \begin{array}{rrl}
17728  * \max & 1^T y &\\
17729  * & A x - y - \alpha a & \geq 0\\
17730  * & B x + y - \alpha b & \leq 0\\
17731  * & D x - \alpha d & = 0\\
17732  * & 0 \leq y & \leq 1\\
17733  * & \alpha & \geq 1.
17734  * \end{array}
17735  * \f]
17736  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
17737  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
17738  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
17739  */
17741  SCIP_SET* set, /**< global SCIP settings */
17742  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17743  SCIP_LP* lp, /**< LP data */
17744  SCIP_PROB* prob, /**< problem data */
17745  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17746  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17747  SCIP_Real timelimit, /**< time limit for LP solver */
17748  int iterlimit, /**< iteration limit for LP solver */
17749  SCIP_Real* point, /**< array to store relative interior point on exit */
17750  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17751  )
17752 {
17753  SCIP_LPI* lpi;
17754 
17755  SCIP_RETCODE retcode;
17756 
17757  assert(set != NULL);
17758  assert(lp != NULL);
17759  assert(point != NULL);
17760  assert(success != NULL);
17761 
17762  *success = FALSE;
17763 
17764  /* check time and iteration limits */
17765  if ( timelimit <= 0.0 || iterlimit <= 0 )
17766  return SCIP_OKAY;
17767 
17768  /* exit if there are no columns */
17769  assert(lp->nrows >= 0);
17770  assert(lp->ncols >= 0);
17771  if( lp->ncols == 0 )
17772  return SCIP_OKAY;
17773 
17774  /* disable objective cutoff if we have none */
17775  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
17776  inclobjcutoff = FALSE;
17777 
17778  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
17779 
17780  /* if there are no rows, we return the zero point */
17781  if( lp->nrows == 0 && !inclobjcutoff )
17782  {
17783  /* create zero point */
17784  BMSclearMemoryArray(point, lp->ncols);
17785  *success = TRUE;
17786 
17787  return SCIP_OKAY;
17788  }
17789 
17790  /* create auxiliary LP */
17791  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
17792 
17793  /* catch return code and ensure that lpi is freed, anyway */
17794  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
17795 
17796  SCIP_CALL( SCIPlpiFree(&lpi) );
17797 
17798  return retcode;
17799 }
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:16613
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:17046
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:15716
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:12703
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:13238
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8741
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:9944
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17034
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:16810
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:13542
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:16992
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:9489
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:16929
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:16563
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1358
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:16648
#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:15583
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:14938
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:17740
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:9656
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:14907
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:16864
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:16243
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:16821
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:13115
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16363
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16375
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:16405
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:14527
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14452
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:11648
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16543
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:8706
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:16717
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12782
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13433
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13721
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:11178
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:9883
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:16419
#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:13405
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16484
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:15752
#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:16982
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:13474
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:16274
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:16185
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:16532
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16165
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:15730
#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:9817
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:16897
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15570
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:15513
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:16306
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:14876
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:8862
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:15334
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:12048
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:11966
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:16757
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:13156
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12814
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:15115
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:9958
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:14467
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:9924
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:16623
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:15555
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:8836
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:16504
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:11087
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12615
#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:13634
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:16875
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:15516
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:16747
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11939
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11230
#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:11233
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:16695
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:16885
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:15076
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:9841
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:16788
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13501
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16472
#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:13766
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:15228
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16208
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:15540
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:15767
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:16962
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16395
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:13844
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:16972
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:16353
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:9234
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:9417
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:16737
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16593
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:15005
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:9731
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:9574
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5711
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16175
#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:16583
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:14156
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:9293
internal miscellaneous methods
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:16633
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:10037
SCIP_Bool isrelax
Definition: struct_lp.h:355
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:16852
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:14386
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:16767
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:17012
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:16494
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8182
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11169
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:16919
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12631
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:16603
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:16430
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:8814
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8666
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:11679
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:16264
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:9600
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:16440
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:16909
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9555
#define SCIP_Bool
Definition: def.h:61
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12714
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:14626
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:9159
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16195
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:16799
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:9634
#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:17002
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:8879
#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:16285
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:8882
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9617
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:9586
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16517
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:15154
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:9900
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:12028
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:16573
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:12942
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:148
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16221
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:9203
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:13074
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:10950
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:12670
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:15606
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:12844
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:16450
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:14724
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12690
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16328
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:16254
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8780
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:9968
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:16706
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8538
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:13351
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:14800
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:156
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13587
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:16385
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:16673
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:16952
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:13823
#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:16942
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:10014
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:2978
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:16684
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14329
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:9682
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:16553
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:9707
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13699
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:12884
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:13563
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:16777
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16231
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:13862
#define SCIP_ALLOC(x)
Definition: def.h:361
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12659
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:16342
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:16295
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:10352
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:16727
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:16460
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:10178
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17023
#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:16317
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:11850
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9364
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:16663
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:726