Scippy

SCIP

Solving Constraint Integer Programs

lp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lp.c
17  * @brief LP management methods and data structures
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Marc Pfetsch
21  * @author Kati Wolter
22  * @author Gerald Gamrath
23  *
24  * In LP management, we have to differ between the current LP and the SCIP_LP
25  * stored in the LP solver. All LP methods affect the current LP only.
26  * Before solving the current LP with the LP solver or setting an LP state,
27  * the LP solvers data has to be updated to the current LP with a call to
28  * lpFlush().
29  */
30 
31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32 
33 
34 #include <assert.h>
35 #include <math.h>
36 #include <limits.h>
37 #include <string.h>
38 
39 #include "scip/def.h"
40 #include "scip/set.h"
41 #include "scip/stat.h"
42 #include "scip/intervalarith.h"
43 #include "scip/clock.h"
44 #include "scip/misc.h"
45 #include "scip/lp.h"
46 #include "scip/var.h"
47 #include "scip/prob.h"
48 #include "scip/sol.h"
49 #include "scip/solve.h"
50 #include "scip/event.h"
51 #include "scip/pub_message.h"
52 #include "lpi/lpi.h"
53 
54 
55 
56 /*
57  * debug messages
58  */
59 
60 #ifdef SCIP_DEBUG
61 /** method is to print in row in case SCIP_DEBUG is defined */
62 static
63 void debugRowPrint(
64  SCIP_SET* set, /**< global SCIP settings */
65  SCIP_ROW* row /**< LP row */
66  )
67 {
68  int i;
69 
70  assert(row != NULL);
71 
72  /* print row name */
73  if( row->name != NULL && row->name[0] != '\0' )
74  {
75  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
76  }
77 
78  /* print left hand side */
79  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
80 
81  /* print coefficients */
82  if( row->len == 0 )
83  {
84  SCIPsetDebugMsgPrint(set, "0 ");
85  }
86  for( i = 0; i < row->len; ++i )
87  {
88  assert(row->cols[i] != NULL);
89  assert(row->cols[i]->var != NULL);
90  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
91  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
92  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
93  }
94 
95  /* print constant */
97  {
98  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
99  }
100 
101  /* print right hand side */
102  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
103 }
104 #else
105 #define debugRowPrint(x,y) /**/
106 #endif
107 
108 #ifdef SCIP_DEBUG
109 /** method to output column if SCIP_DEBUG is define */
110 static
111 void debugColPrint(
112  SCIP_SET* set, /**< global SCIP settings */
113  SCIP_COL* col /**< LP column */
114  )
115 {
116  int r;
117 
118  assert(col != NULL);
119  assert(col->var != NULL);
120 
121  /* print bounds */
122  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
123 
124  /* print coefficients */
125  if( col->len == 0 )
126  {
127  SCIPsetDebugMsgPrint(set, "<empty>");
128  }
129  for( r = 0; r < col->len; ++r )
130  {
131  assert(col->rows[r] != NULL);
132  assert(col->rows[r]->name != NULL);
133  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
134  }
135  SCIPsetDebugMsgPrint(set, "\n");
136 }
137 #else
138 #define debugColPrint(x,y) /**/
139 #endif
140 
141 /*
142  * memory growing methods for dynamically allocated arrays
143  */
144 
145 /** ensures, that chgcols array can store at least num entries */
146 static
148  SCIP_LP* lp, /**< current LP data */
149  SCIP_SET* set, /**< global SCIP settings */
150  int num /**< minimum number of entries to store */
151  )
152 {
153  assert(lp->nchgcols <= lp->chgcolssize);
154 
155  if( num > lp->chgcolssize )
156  {
157  int newsize;
158 
159  newsize = SCIPsetCalcMemGrowSize(set, num);
160  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
161  lp->chgcolssize = newsize;
162  }
163  assert(num <= lp->chgcolssize);
164 
165  return SCIP_OKAY;
166 }
167 
168 /** ensures, that chgrows array can store at least num entries */
169 static
171  SCIP_LP* lp, /**< current LP data */
172  SCIP_SET* set, /**< global SCIP settings */
173  int num /**< minimum number of entries to store */
174  )
175 {
176  assert(lp->nchgrows <= lp->chgrowssize);
177 
178  if( num > lp->chgrowssize )
179  {
180  int newsize;
181 
182  newsize = SCIPsetCalcMemGrowSize(set, num);
183  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
184  lp->chgrowssize = newsize;
185  }
186  assert(num <= lp->chgrowssize);
187 
188  return SCIP_OKAY;
189 }
190 
191 /** ensures, that lpicols array can store at least num entries */
192 static
194  SCIP_LP* lp, /**< current LP data */
195  SCIP_SET* set, /**< global SCIP settings */
196  int num /**< minimum number of entries to store */
197  )
198 {
199  assert(lp->nlpicols <= lp->lpicolssize);
200 
201  if( num > lp->lpicolssize )
202  {
203  int newsize;
204 
205  newsize = SCIPsetCalcMemGrowSize(set, num);
206  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
207  lp->lpicolssize = newsize;
208  }
209  assert(num <= lp->lpicolssize);
210 
211  return SCIP_OKAY;
212 }
213 
214 /** ensures, that lpirows array can store at least num entries */
215 static
217  SCIP_LP* lp, /**< current LP data */
218  SCIP_SET* set, /**< global SCIP settings */
219  int num /**< minimum number of entries to store */
220  )
221 {
222  assert(lp->nlpirows <= lp->lpirowssize);
223 
224  if( num > lp->lpirowssize )
225  {
226  int newsize;
227 
228  newsize = SCIPsetCalcMemGrowSize(set, num);
229  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
230  lp->lpirowssize = newsize;
231  }
232  assert(num <= lp->lpirowssize);
233 
234  return SCIP_OKAY;
235 }
236 
237 /** ensures, that cols array can store at least num entries */
238 static
240  SCIP_LP* lp, /**< current LP data */
241  SCIP_SET* set, /**< global SCIP settings */
242  int num /**< minimum number of entries to store */
243  )
244 {
245  assert(lp->ncols <= lp->colssize);
246 
247  if( num > lp->colssize )
248  {
249  int newsize;
250 
251  newsize = SCIPsetCalcMemGrowSize(set, num);
252  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
253  lp->colssize = newsize;
254  }
255  assert(num <= lp->colssize);
256 
257  return SCIP_OKAY;
258 }
259 
260 /** ensures, that lazy cols array can store at least num entries */
261 static
263  SCIP_LP* lp, /**< current LP data */
264  SCIP_SET* set, /**< global SCIP settings */
265  int num /**< minimum number of entries to store */
266  )
267 {
268  assert(lp->nlazycols <= lp->lazycolssize);
269 
270  if( num > lp->lazycolssize )
271  {
272  int newsize;
273 
274  newsize = SCIPsetCalcMemGrowSize(set, num);
275  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
276  lp->lazycolssize = newsize;
277  }
278  assert(num <= lp->lazycolssize);
279 
280  return SCIP_OKAY;
281 }
282 
283 /** ensures, that rows array can store at least num entries */
284 static
286  SCIP_LP* lp, /**< current LP data */
287  SCIP_SET* set, /**< global SCIP settings */
288  int num /**< minimum number of entries to store */
289  )
290 {
291  assert(lp->nrows <= lp->rowssize);
292 
293  if( num > lp->rowssize )
294  {
295  int newsize;
296 
297  newsize = SCIPsetCalcMemGrowSize(set, num);
298  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
299  lp->rowssize = newsize;
300  }
301  assert(num <= lp->rowssize);
302 
303  return SCIP_OKAY;
304 }
305 
306 /** ensures, that row array of column can store at least num entries */
307 static
309  SCIP_COL* col, /**< LP column */
310  BMS_BLKMEM* blkmem, /**< block memory */
311  SCIP_SET* set, /**< global SCIP settings */
312  int num /**< minimum number of entries to store */
313  )
314 {
315  assert(col != NULL);
316  assert(col->len <= col->size);
317 
318  if( num > col->size )
319  {
320  int newsize;
321 
322  newsize = SCIPsetCalcMemGrowSize(set, num);
323  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
324  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
325  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
326  col->size = newsize;
327  }
328  assert(num <= col->size);
329 
330  return SCIP_OKAY;
331 }
332 
333 /** save current LP values dependent on the solution */
334 static
336  SCIP_LP* lp, /**< LP data */
337  SCIP_STAT* stat, /**< problem statistics */
338  BMS_BLKMEM* blkmem /**< block memory */
339  )
340 {
341  SCIP_LPSOLVALS* storedsolvals;
342 
343  assert(lp != NULL);
344  assert(stat != NULL);
345  assert(blkmem != NULL);
346 
347  /* allocate memory for storage */
348  if( lp->storedsolvals == NULL )
349  {
351  }
352  storedsolvals = lp->storedsolvals;
353 
354  /* store values */
355  storedsolvals->lpsolstat = lp->lpsolstat;
356  storedsolvals->lpobjval = lp->lpobjval;
357  storedsolvals->primalfeasible = lp->primalfeasible;
358  storedsolvals->primalchecked = lp->primalchecked;
359  storedsolvals->dualfeasible = lp->dualfeasible;
360  storedsolvals->dualchecked = lp->dualchecked;
361  storedsolvals->solisbasic = lp->solisbasic;
362  storedsolvals->lpissolved = lp->solved;
363 
364  return SCIP_OKAY;
365 }
366 
367 /** restore LP solution values in column */
368 static
370  SCIP_LP* lp, /**< LP data */
371  BMS_BLKMEM* blkmem, /**< block memory */
372  SCIP_Longint validlp /**< number of lp for which restored values are valid */
373  )
374 {
375  SCIP_LPSOLVALS* storedsolvals;
376 
377  assert(lp != NULL);
378  assert(blkmem != NULL);
379 
380  /* if stored values are available, restore them */
381  storedsolvals = lp->storedsolvals;
382  if( storedsolvals != NULL )
383  {
384  lp->solved = storedsolvals->lpissolved;
385  lp->validsollp = validlp;
386 
387  lp->lpsolstat = storedsolvals->lpsolstat;
388  lp->lpobjval = storedsolvals->lpobjval;
389  lp->primalfeasible = storedsolvals->primalfeasible;
390  lp->primalchecked = storedsolvals->primalchecked;
391  lp->dualfeasible = storedsolvals->dualfeasible;
392  lp->dualchecked = storedsolvals->dualchecked;
393  lp->solisbasic = storedsolvals->solisbasic;
394 
395  /* solution values are stored only for LPs solved to optimality or unboundedness */
396  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
402  lp->validsollp == -1);
403  }
404  /* no values available, mark LP as unsolved */
405  else
406  {
407  lp->solved = FALSE;
408  lp->validsollp = -1;
409 
411  lp->lpobjval = SCIP_INVALID;
412  lp->primalfeasible = FALSE;
413  lp->primalchecked = FALSE;
414  lp->dualfeasible = FALSE;
415  lp->dualchecked = FALSE;
416  lp->solisbasic = FALSE;
417  lp->validfarkaslp = -1;
418  }
419 
420  /* intentionally keep storage space allocated */
421 
422  return SCIP_OKAY;
423 }
424 
425 /** save current LP solution values stored in each column */
426 static
428  SCIP_COL* col, /**< LP column */
429  BMS_BLKMEM* blkmem /**< block memory */
430  )
431 {
432  SCIP_COLSOLVALS* storedsolvals;
433 
434  assert(col != NULL);
435  assert(blkmem != NULL);
436 
437  /* allocate memory for storage */
438  if( col->storedsolvals == NULL )
439  {
440  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
441  }
442  storedsolvals = col->storedsolvals;
443 
444  /* store values */
445  storedsolvals->primsol = col->primsol;
446  storedsolvals->redcost = col->redcost;
447  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
448 
449  return SCIP_OKAY;
450 }
451 
452 /** restore LP solution values in column */
453 static
455  SCIP_COL* col, /**< LP column */
456  BMS_BLKMEM* blkmem, /**< block memory */
457  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
458  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
459  )
460 {
461  SCIP_COLSOLVALS* storedsolvals;
462 
463  assert(col != NULL);
464  assert(blkmem != NULL);
465 
466  /* if stored values are available, restore them */
467  storedsolvals = col->storedsolvals;
468  if( storedsolvals != NULL )
469  {
470  col->primsol = storedsolvals->primsol;
471  col->redcost = storedsolvals->redcost;
472  col->validredcostlp = validlp;
473  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
474 
475  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
476  col->validfarkaslp = -1;
477  }
478  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
479  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
480  */
481  else
482  {
483  col->primsol = 0.0;
484  col->validredcostlp = -1;
485  col->validfarkaslp = -1;
486  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
487  }
488 
489  /* free memory */
490  if( freebuffer )
491  {
492  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
493  assert(col->storedsolvals == NULL);
494  }
495 
496  return SCIP_OKAY;
497 }
498 
499 /** save current LP solution values stored in each column */
500 static
502  SCIP_ROW* row, /**< LP row */
503  BMS_BLKMEM* blkmem, /**< block memory */
504  SCIP_Bool infeasible /**< is the solution infeasible? */
505  )
506 {
507  SCIP_ROWSOLVALS* storedsolvals;
508 
509  assert(row != NULL);
510  assert(blkmem != NULL);
511 
512  /* allocate memory for storage */
513  if( row->storedsolvals == NULL )
514  {
515  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
516  }
517  storedsolvals = row->storedsolvals;
518 
519  /* store values */
520  if ( infeasible )
521  {
522  storedsolvals->dualsol = row->dualfarkas;
523  storedsolvals->activity = SCIP_INVALID;
524  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
525  }
526  else
527  {
528  storedsolvals->dualsol = row->dualsol;
529  storedsolvals->activity = row->activity;
530  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
531  }
532 
533  return SCIP_OKAY;
534 }
535 
536 /** restore LP solution values in row */
537 static
539  SCIP_ROW* row, /**< LP column */
540  BMS_BLKMEM* blkmem, /**< block memory */
541  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
542  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
543  SCIP_Bool infeasible /**< is the solution infeasible? */
544  )
545 {
546  SCIP_ROWSOLVALS* storedsolvals;
547 
548  assert(row != NULL);
549  assert(blkmem != NULL);
550 
551  /* if stored values are available, restore them */
552  storedsolvals = row->storedsolvals;
553  if( storedsolvals != NULL )
554  {
555  if ( infeasible )
556  row->dualfarkas = storedsolvals->dualsol;
557  else
558  row->dualsol = storedsolvals->dualsol;
559  row->activity = storedsolvals->activity;
560  row->validactivitylp = validlp;
561  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
562  }
563  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
564  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
565  */
566  else
567  {
568  row->dualsol = 0.0;
569  row->dualfarkas = 0.0;
570  row->activity = SCIP_INVALID;
571  row->validactivitylp = -1;
572  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
573  }
574 
575  /* free memory */
576  if( freebuffer )
577  {
578  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
579  assert(row->storedsolvals == NULL);
580  }
581 
582  return SCIP_OKAY;
583 }
584 
585 /** ensures, that column array of row can store at least num entries */
587  SCIP_ROW* row, /**< LP row */
588  BMS_BLKMEM* blkmem, /**< block memory */
589  SCIP_SET* set, /**< global SCIP settings */
590  int num /**< minimum number of entries to store */
591  )
592 {
593  assert(row != NULL);
594  assert(row->len <= row->size);
595 
596  if( num > row->size )
597  {
598  int newsize;
599 
600  newsize = SCIPsetCalcMemGrowSize(set, num);
601  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
602  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
603  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
604  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
605  row->size = newsize;
606  }
607  assert(num <= row->size);
608 
609  return SCIP_OKAY;
610 }
611 
612 
613 #if 0 /* enable this to check the sortings within rows (for debugging, very slow!) */
614 static SCIP_Bool msgdisp_checkrow = FALSE;
615 
616 static
617 void checkRow(
618  SCIP_ROW* row
619  )
620 {
621  int i;
622 
623  if( !msgdisp_checkrow )
624  {
625  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
626  msgdisp_checkrow = TRUE;
627  }
628 
629  /* validate sorting of LP part of row */
630  if( row->lpcolssorted && row->nlpcols > 0)
631  {
632  assert(row->cols_index[0] == row->cols[0]->index);
633  for( i = 1; i < row->nlpcols; ++i )
634  {
635  assert(row->cols_index[i] == row->cols[i]->index);
636  assert(row->cols_index[i] >= row->cols_index[i-1]);
637  }
638  }
639 
640  /* validate sorting of non-LP part of row */
641  if( row->nonlpcolssorted && row->len > row->nlpcols )
642  {
643  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
644  for( i = row->nlpcols + 1; i < row->len; ++i )
645  {
646  assert(row->cols_index[i] == row->cols[i]->index);
647  assert(row->cols_index[i] >= row->cols_index[i-1]);
648  }
649  }
650 }
651 #else
652 #define checkRow(row) /**/
653 #endif
654 
655 #if 0 /* enable this to check norms of rows (for debugging, very slow!) */
656 static
657 void checkRowSqrnorm(
658  SCIP_ROW* row
659  )
660 {
661  SCIP_COL** cols;
662  SCIP_Real sqrnorm;
663  int c;
664 
665  cols = row->cols;
666  assert(cols != NULL || row->len == 0);
667 
668  sqrnorm = 0.0;
669 
670  for( c = row->len - 1; c >= 0; --c )
671  {
672  if( cols[c]->lppos >= 0 )
673  sqrnorm += SQR(row->vals[c]);
674  }
675 
676  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
677 }
678 
679 static
680 void checkRowSumnorm(
681  SCIP_ROW* row
682  )
683 {
684  SCIP_COL** cols;
685  SCIP_Real sumnorm;
686  int c;
687 
688  cols = row->cols;
689  assert(cols != NULL || row->len == 0);
690 
691  sumnorm = 0.0;
692 
693  for( c = row->len - 1; c >= 0; --c )
694  {
695  if( cols[c]->lppos >= 0 )
696  sumnorm += REALABS(row->vals[c]);
697  }
698 
699  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
700 }
701 
702 static
703 void checkRowObjprod(
704  SCIP_ROW* row
705  )
706 {
707  SCIP_COL** cols;
708  SCIP_Real objprod;
709  int c;
710 
711  cols = row->cols;
712  assert(cols != NULL || row->len == 0);
713 
714  objprod = 0.0;
715 
716  for( c = row->len - 1; c >= 0; --c )
717  {
718  if( cols[c]->lppos >= 0 )
719  objprod += row->vals[c] * cols[c]->unchangedobj;
720  }
721 
722  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
723 }
724 #else
725 #define checkRowSqrnorm(row) /**/
726 #define checkRowSumnorm(row) /**/
727 #define checkRowObjprod(row) /**/
728 #endif
729 
730 /*
731  * Local methods for pseudo and loose objective values
732  */
733 
734 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
735 static
737  SCIP_LP* lp, /**< current LP data */
738  SCIP_SET* set, /**< global SCIP settings */
739  SCIP_PROB* prob /**< problem data */
740  )
741 {
742  SCIP_VAR** vars;
743  SCIP_Real obj;
744  int nvars;
745  int v;
746 
747  assert(lp != NULL);
748  assert(set != NULL);
749  assert(prob != NULL);
750  assert(!lp->looseobjvalid);
751 
752  vars = prob->vars;
753  nvars = prob->nvars;
754  lp->looseobjval = 0.0;
755 
756  /* iterate over all variables in the problem */
757  for( v = 0; v < nvars; ++v )
758  {
759  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
760  {
761  obj = SCIPvarGetObj(vars[v]);
762 
763  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
764  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
765  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
766  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
767  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
768  }
769  }
770 
771  /* the recomputed value is reliable */
772  lp->rellooseobjval = lp->looseobjval;
773  lp->looseobjvalid = TRUE;
774 }
775 
776 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
777 static
779  SCIP_LP* lp, /**< current LP data */
780  SCIP_SET* set, /**< global SCIP settings */
781  SCIP_PROB* prob /**< problem data */
782  )
783 {
784  SCIP_VAR** vars;
785  int nvars;
786  int v;
787 
788  assert(lp != NULL);
789  assert(set != NULL);
790  assert(prob != NULL);
791  assert(!lp->pseudoobjvalid);
792 
793  vars = prob->vars;
794  nvars = prob->nvars;
795  lp->pseudoobjval = 0.0;
796 
797  /* iterate over all variables in the problem */
798  for( v = 0; v < nvars; ++v )
799  {
800  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
801  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
802  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
803  {
804  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
805  }
806  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
807  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
808  {
809  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
810  }
811  }
812 
813  /* the recomputed value is reliable */
814  lp->relpseudoobjval = lp->pseudoobjval;
815  lp->pseudoobjvalid = TRUE;
816 }
817 
818 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
819 static
821  SCIP_LP* lp, /**< current LP data */
822  SCIP_SET* set, /**< global SCIP settings */
823  SCIP_PROB* prob /**< problem data */
824  )
825 {
826  SCIP_VAR** vars;
827  int nvars;
828  int v;
829 
830  assert(lp != NULL);
831  assert(set != NULL);
832  assert(prob != NULL);
833  assert(!lp->glbpseudoobjvalid);
834 
835  vars = prob->vars;
836  nvars = prob->nvars;
837  lp->glbpseudoobjval = 0.0;
838 
839  /* iterate over all variables in the problem */
840  for( v = 0; v < nvars; ++v )
841  {
842  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
843  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
844  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
845  {
846  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
847  }
848  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
849  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
850  {
851  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
852  }
853  }
854 
855  /* the recomputed value is reliable */
857  lp->glbpseudoobjvalid = TRUE;
858 }
859 
860 /** gets finite part of objective value of current LP that results from LOOSE variables only */
861 static
863  SCIP_LP* lp, /**< current LP data */
864  SCIP_SET* set, /**< global SCIP settings */
865  SCIP_PROB* prob /**< problem data */
866  )
867 {
868  assert(lp != NULL);
869  assert(set != NULL);
870  assert(prob != NULL);
871  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
872  assert(lp->flushed);
873  assert(lp->looseobjvalinf == 0);
874 
875  /* recalculate the loose objective value, if needed */
876  if( !lp->looseobjvalid )
877  recomputeLooseObjectiveValue(lp, set, prob);
878 
879  return lp->looseobjval;
880 }
881 
882 /** gets finite part of pseudo objective value of current LP */
883 static
885  SCIP_LP* lp, /**< current LP data */
886  SCIP_SET* set, /**< global SCIP settings */
887  SCIP_PROB* prob /**< problem data */
888  )
889 {
890  assert(lp != NULL);
891  assert(set != NULL);
892  assert(prob != NULL);
893 
894  /* recalculate the pseudo objective value, if needed */
895  if( !lp->pseudoobjvalid )
896  recomputePseudoObjectiveValue(lp, set, prob);
897 
898  return lp->pseudoobjval;
899 }
900 
901 /*
902  * Sorting and searching rows and columns
903  */
904 
905 
906 /** comparison method for sorting rows by non-decreasing index */
908 {
909  assert(elem1 != NULL);
910  assert(elem2 != NULL);
911 
912  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
913  return -1;
914  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
915  return +1;
916  else
917  {
918  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
919  return 0;
920  }
921 }
922 
923 
924 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
925 static
927  SCIP_COL* col /**< column to be sorted */
928  )
929 {
930  int i;
931 
932  assert(col != NULL);
933 
934  /* check, if column is already sorted in the LP part */
935  if( col->lprowssorted )
936  return;
937 
938  /* sort coefficients */
939  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
940 
941  /* update links */
942  for( i = 0; i < col->nlprows; ++i )
943  {
944  if( col->linkpos[i] >= 0 )
945  {
946  assert(col->rows[i]->cols[col->linkpos[i]] == col);
947  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
948  col->rows[i]->linkpos[col->linkpos[i]] = i;
949  }
950  }
951 
952  col->lprowssorted = TRUE;
953 }
954 
955 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
956  * ones
957  */
958 static
960  SCIP_COL* col /**< column to be sorted */
961  )
962 {
963  int i;
964 
965  assert(col != NULL);
966 
967  /* check, if column is already sorted in the non-LP part */
968  if( col->nonlprowssorted )
969  return;
970 
971  /* sort coefficients */
972  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
973 
974  /* update links */
975  for( i = col->nlprows; i < col->len; ++i )
976  {
977  if( col->linkpos[i] >= 0 )
978  {
979  assert(col->rows[i]->cols[col->linkpos[i]] == col);
980  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
981  col->rows[i]->linkpos[col->linkpos[i]] = i;
982  }
983  }
984 
985  col->nonlprowssorted = TRUE;
986 }
987 
988 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
989 static
991  SCIP_ROW* row /**< row to be sorted */
992  )
993 {
994  int i;
995 
996  assert(row != NULL);
997 
998  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
999  if( row->lpcolssorted || row->delaysort )
1000  return;
1001 
1002  /* sort coefficients */
1003  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1004 
1005  /* update links */
1006  for( i = 0; i < row->nlpcols; ++i )
1007  {
1008  if( row->linkpos[i] >= 0 )
1009  {
1010  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1011  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1012  row->cols[i]->linkpos[row->linkpos[i]] = i;
1013  }
1014  }
1015 
1016  row->lpcolssorted = TRUE;
1017 }
1018 
1019 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1020  * higher ones
1021  */
1022 static
1024  SCIP_ROW* row /**< row to be sorted */
1025  )
1026 {
1027  int i;
1028 
1029  assert(row != NULL);
1030 
1031  checkRow(row);
1032 
1033  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1034  if( row->nonlpcolssorted || row->delaysort )
1035  return;
1036 
1037  /* sort coefficients */
1038  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1039 
1040  /* update links */
1041  for( i = row->nlpcols; i < row->len; ++i )
1042  {
1043  if( row->linkpos[i] >= 0 )
1044  {
1045  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1046  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1047  row->cols[i]->linkpos[row->linkpos[i]] = i;
1048  }
1049  }
1050 
1051  checkRow(row);
1052 
1053  row->nonlpcolssorted = TRUE;
1054 }
1055 
1056 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1057 static
1059  SCIP_COL* col, /**< column to be searched in */
1060  const SCIP_ROW* row, /**< coefficient to be searched for */
1061  int minpos, /**< first position of search range */
1062  int maxpos /**< last position of search range */
1063  )
1064 {
1065  int pos;
1066  int idx;
1067  int searchidx;
1068 
1069  assert(col != NULL);
1070  assert(row != NULL);
1071 
1072  /* binary search */
1073  searchidx = row->index;
1074  while(minpos <= maxpos)
1075  {
1076  pos = (minpos + maxpos)/2;
1077  assert(0 <= pos && pos < col->len);
1078  assert(col->rows[pos] != NULL);
1079  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1080  idx = col->rows[pos]->index;
1081  if( searchidx == idx )
1082  return pos;
1083  else if( searchidx < idx )
1084  maxpos = pos-1;
1085  else
1086  minpos = pos+1;
1087  }
1088 
1089  return -1;
1090 }
1091 
1092 /** searches coefficient in column, returns position in col vector or -1 if not found */
1093 static
1095  SCIP_COL* col, /**< column to be searched in */
1096  const SCIP_ROW* row /**< coefficient to be searched for */
1097  )
1098 {
1099  int pos;
1100 
1101  assert(col != NULL);
1102  assert(row != NULL);
1103 
1104  pos = -1;
1105 
1106  /* search in the linked LP rows */
1107  if( row->lppos >= 0 )
1108  {
1109  /* column has to be sorted, such that binary search works */
1110  colSortLP(col);
1111  assert(col->lprowssorted);
1112 
1113  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1114  if( pos >= 0 )
1115  return pos;
1116  }
1117 
1118  /* search in the non-LP/unlinked rows */
1119  if( row->lppos == -1 || col->nunlinked > 0 )
1120  {
1121  /* column has to be sorted, such that binary search works */
1122  colSortNonLP(col);
1123  assert(col->nonlprowssorted);
1124 
1125  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1126  }
1127 
1128  return pos;
1129 }
1130 
1131 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1132 static
1134  SCIP_ROW* row, /**< row to be searched in */
1135  const SCIP_COL* col, /**< coefficient to be searched for */
1136  int minpos, /**< first position of search range */
1137  int maxpos /**< last position of search range */
1138  )
1139 {
1140  int pos;
1141  int idx;
1142  int searchidx;
1143 
1144  assert(row != NULL);
1145  assert(col != NULL);
1146 
1147  /* binary search */
1148  searchidx = col->index;
1149  while(minpos <= maxpos)
1150  {
1151  pos = (minpos + maxpos)/2;
1152  assert(0 <= pos && pos < row->len);
1153  assert(row->cols[pos] != NULL);
1154  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1155  assert(row->cols_index[pos] == row->cols[pos]->index);
1156  idx = row->cols_index[pos];
1157  if( searchidx == idx )
1158  return pos;
1159  else if( searchidx < idx )
1160  maxpos = pos-1;
1161  else
1162  minpos = pos+1;
1163  }
1164 
1165  return -1;
1166 }
1167 
1168 /** searches coefficient in row, returns position in row vector or -1 if not found;
1169  * if the sorting of the row is delayed, returns -1
1170  */
1171 static
1173  SCIP_ROW* row, /**< row to be searched in */
1174  const SCIP_COL* col /**< coefficient to be searched for */
1175  )
1176 {
1177  int pos;
1178 
1179  assert(row != NULL);
1180  assert(col != NULL);
1181 
1182  if( row->delaysort )
1183  return -1;
1184 
1185  pos = -1;
1186 
1187  /* search in the linked LP columns */
1188  if( col->lppos >= 0 )
1189  {
1190  /* row has to be sorted, such that binary search works */
1191  rowSortLP(row);
1192  assert(row->lpcolssorted);
1193 
1194  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1195  }
1196 
1197  /* search in the non-LP/unlinked columns */
1198  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1199  {
1200  /* row has to be sorted, such that binary search works */
1201  rowSortNonLP(row);
1202  assert(row->nonlpcolssorted);
1203 
1204  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1205  }
1206 
1207 #ifndef NDEBUG
1208  /* validate result */
1209  assert(-1 <= pos && pos < row->len);
1210  if( pos >= 0 )
1211  assert(row->cols[pos] == col);
1212  else
1213  {
1214  int i;
1215  for( i = 0; i < row->len; ++i )
1216  assert(row->cols[i] != col);
1217  }
1218 #endif
1219 
1220  return pos;
1221 }
1222 
1223 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1224 static
1226  SCIP_COL* col, /**< LP column */
1227  int oldpos, /**< old position of coefficient */
1228  int newpos /**< new position of coefficient */
1229  )
1230 {
1231  assert(col != NULL);
1232  assert(0 <= oldpos && oldpos < col->len);
1233  assert(0 <= newpos && newpos < col->len);
1234  assert(col->rows[oldpos] != NULL);
1235 
1236  if( oldpos == newpos )
1237  return;
1238 
1239  col->rows[newpos] = col->rows[oldpos];
1240  col->vals[newpos] = col->vals[oldpos];
1241  col->linkpos[newpos] = col->linkpos[oldpos];
1242 
1243  /* update link position in row */
1244  if( col->linkpos[newpos] >= 0 )
1245  {
1246  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1247  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1248 
1249  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1250  }
1251 
1252  /* update sorted flags */
1253  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1254  col->lprowssorted = FALSE;
1255  else
1256  col->nonlprowssorted = FALSE;
1257 }
1258 
1259 /** swaps two coefficients in a column, and updates all corresponding data structures */
1260 static
1262  SCIP_COL* col, /**< LP column */
1263  int pos1, /**< position of first coefficient */
1264  int pos2 /**< position of second coefficient */
1265  )
1266 {
1267  SCIP_ROW* tmprow;
1268  SCIP_Real tmpval;
1269  int tmplinkpos;
1270 
1271  assert(col != NULL);
1272  assert(0 <= pos1 && pos1 < col->len);
1273  assert(0 <= pos2 && pos2 < col->len);
1274  assert(col->rows[pos1] != NULL);
1275 
1276  if( pos1 == pos2 )
1277  return;
1278 
1279  /* swap coefficients */
1280  tmprow = col->rows[pos2];
1281  tmpval = col->vals[pos2];
1282  tmplinkpos = col->linkpos[pos2];
1283 
1284  col->rows[pos2] = col->rows[pos1];
1285  col->vals[pos2] = col->vals[pos1];
1286  col->linkpos[pos2] = col->linkpos[pos1];
1287 
1288  col->rows[pos1] = tmprow;
1289  col->vals[pos1] = tmpval;
1290  col->linkpos[pos1] = tmplinkpos;
1291 
1292  /* update link position in rows */
1293  if( col->linkpos[pos1] >= 0 )
1294  {
1295  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1296  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1297 
1298  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1299  }
1300  if( col->linkpos[pos2] >= 0 )
1301  {
1302  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1303  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1304 
1305  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1306  }
1307 
1308  /* update sorted flags */
1309  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1310  col->lprowssorted = FALSE;
1311  else
1312  col->nonlprowssorted = FALSE;
1313  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1314  col->lprowssorted = FALSE;
1315  else
1316  col->nonlprowssorted = FALSE;
1317 }
1318 
1319 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1320 static
1322  SCIP_ROW* row, /**< LP row */
1323  int oldpos, /**< old position of coefficient */
1324  int newpos /**< new position of coefficient */
1325  )
1326 {
1327  assert(row != NULL);
1328  assert(0 <= oldpos && oldpos < row->len);
1329  assert(0 <= newpos && newpos < row->len);
1330  assert(row->cols[oldpos] != NULL);
1331 
1332  if( oldpos == newpos )
1333  return;
1334 
1335  row->cols[newpos] = row->cols[oldpos];
1336  row->cols_index[newpos] = row->cols_index[oldpos];
1337  row->vals[newpos] = row->vals[oldpos];
1338  row->linkpos[newpos] = row->linkpos[oldpos];
1339 
1340  /* update link position in column */
1341  if( row->linkpos[newpos] >= 0 )
1342  {
1343  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1344  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1345 
1346  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1347  }
1348 
1349  /* update sorted flags */
1350  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1351  row->lpcolssorted = FALSE;
1352  else
1353  row->nonlpcolssorted = FALSE;
1354 }
1355 
1356 /** swaps two coefficients in a row, and updates all corresponding data structures */
1357 static
1359  SCIP_ROW* row, /**< LP row */
1360  int pos1, /**< position of first coefficient */
1361  int pos2 /**< position of second coefficient */
1362  )
1363 {
1364  SCIP_COL* tmpcol;
1365  SCIP_Real tmpval;
1366  int tmpindex;
1367  int tmplinkpos;
1368 
1369  assert(row != NULL);
1370  assert(0 <= pos1 && pos1 < row->len);
1371  assert(0 <= pos2 && pos2 < row->len);
1372  assert(row->cols[pos1] != NULL);
1373  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1374 
1375  if( pos1 == pos2 )
1376  return;
1377 
1378  /* swap coefficients */
1379  tmpcol = row->cols[pos2];
1380  tmpindex = row->cols_index[pos2];
1381  tmpval = row->vals[pos2];
1382  tmplinkpos = row->linkpos[pos2];
1383 
1384  row->cols[pos2] = row->cols[pos1];
1385  row->cols_index[pos2] = row->cols_index[pos1];
1386  row->vals[pos2] = row->vals[pos1];
1387  row->linkpos[pos2] = row->linkpos[pos1];
1388 
1389  row->cols[pos1] = tmpcol;
1390  row->cols_index[pos1] = tmpindex;
1391  row->vals[pos1] = tmpval;
1392  row->linkpos[pos1] = tmplinkpos;
1393 
1394  /* update link position in columns */
1395  if( row->linkpos[pos1] >= 0 )
1396  {
1397  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1398  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1399 
1400  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1401  }
1402  if( row->linkpos[pos2] >= 0 )
1403  {
1404  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1405  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1406 
1407  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1408  }
1409 
1410  /* update sorted flags */
1411  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1412  row->lpcolssorted = FALSE;
1413  else
1414  row->nonlpcolssorted = FALSE;
1415  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1416  row->lpcolssorted = FALSE;
1417  else
1418  row->nonlpcolssorted = FALSE;
1419 }
1420 
1421 /** issues a ROWCOEFCHANGED event on the given row */
1422 static
1424  SCIP_ROW* row, /**< row which coefficient has changed */
1425  BMS_BLKMEM* blkmem, /**< block memory */
1426  SCIP_SET* set, /**< global SCIP settings */
1427  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1428  SCIP_COL* col, /**< the column which coefficient has changed */
1429  SCIP_Real oldval, /**< old value of the coefficient */
1430  SCIP_Real newval /**< new value of the coefficient */
1431  )
1432 {
1433  assert(row != NULL);
1434  assert(row->eventfilter != NULL);
1435  assert(col != NULL);
1436 
1437  /* check, if the row is being tracked for coefficient changes
1438  * if so, issue ROWCOEFCHANGED event
1439  */
1440  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1441  {
1442  SCIP_EVENT* event;
1443 
1444  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1445  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1446  }
1447 
1448  return SCIP_OKAY;
1449 }
1450 
1451 /** issues a ROWCONSTCHANGED event on the given row */
1452 static
1454  SCIP_ROW* row, /**< row which coefficient has changed */
1455  BMS_BLKMEM* blkmem, /**< block memory */
1456  SCIP_SET* set, /**< global SCIP settings */
1457  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1458  SCIP_Real oldval, /**< old value of the constant */
1459  SCIP_Real newval /**< new value of the constant */
1460  )
1461 {
1462  assert(row != NULL);
1463  assert(row->eventfilter != NULL);
1464 
1465  /* check, if the row is being tracked for coefficient changes
1466  * if so, issue ROWCONSTCHANGED event
1467  */
1468  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED) != 0) )
1469  {
1470  SCIP_EVENT* event;
1471 
1472  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1473  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1474  }
1475 
1476  return SCIP_OKAY;
1477 }
1478 
1479 /** issues a ROWSIDECHANGED event on the given row */
1480 static
1482  SCIP_ROW* row, /**< row which coefficient has changed */
1483  BMS_BLKMEM* blkmem, /**< block memory */
1484  SCIP_SET* set, /**< global SCIP settings */
1485  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1486  SCIP_SIDETYPE side, /**< the side that has changed */
1487  SCIP_Real oldval, /**< old value of side */
1488  SCIP_Real newval /**< new value of side */
1489  )
1490 {
1491  assert(row != NULL);
1492  assert(row->eventfilter != NULL);
1493 
1494  /* check, if the row is being tracked for coefficient changes
1495  * if so, issue ROWSIDECHANGED event
1496  */
1497  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED) != 0) )
1498  {
1499  SCIP_EVENT* event;
1500 
1501  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1502  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1503  }
1504 
1505  return SCIP_OKAY;
1506 }
1507 
1508 #if 0 /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1509 
1510 #ifdef NDEBUG
1511 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1512 #else
1513 #define ASSERT(x) assert(x)
1514 #endif
1515 
1516 static SCIP_Bool msgdisp_checklinks = FALSE;
1517 
1518 
1519 static
1520 void checkLinks(
1521  SCIP_LP* lp /**< current LP data */
1522  )
1523 {
1524  SCIP_COL* col;
1525  SCIP_ROW* row;
1526  int i;
1527  int j;
1528 
1529  ASSERT(lp != NULL);
1530 
1531  if( !msgdisp_checklinks )
1532  {
1533  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1534  msgdisp_checklinks = TRUE;
1535  }
1536 
1537  for( i = 0; i < lp->ncols; ++i )
1538  {
1539  col = lp->cols[i];
1540  ASSERT(col != NULL);
1541  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1542  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1543  ASSERT(col->nlprows <= col->len);
1544  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1545 
1546  for( j = 0; j < col->len; ++j )
1547  {
1548  row = col->rows[j];
1549  ASSERT(row != NULL);
1550  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1551  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1552  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1553  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1554  }
1555  }
1556 
1557  for( i = 0; i < lp->nrows; ++i )
1558  {
1559  row = lp->rows[i];
1560  ASSERT(row != NULL);
1561  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1562  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1563  ASSERT(row->nlpcols <= row->len);
1564  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1565 
1566  for( j = 0; j < row->len; ++j )
1567  {
1568  col = row->cols[j];
1569  ASSERT(col != NULL);
1570  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1571  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1572  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1573  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1574  }
1575  }
1576 }
1577 
1578 #undef ASSERT
1579 
1580 #else
1581 #define checkLinks(lp) /**/
1582 #endif
1583 
1584 /*
1585  * Changing announcements
1586  */
1587 
1588 /** announces, that the given coefficient in the constraint matrix changed */
1589 static
1591  SCIP_ROW* row, /**< LP row */
1592  SCIP_COL* col, /**< LP col */
1593  SCIP_LP* lp /**< current LP data */
1594  )
1595 {
1596  assert(row != NULL);
1597  assert(col != NULL);
1598  assert(lp != NULL);
1599 
1600  if( row->lpipos >= 0 && col->lpipos >= 0 )
1601  {
1602  assert(row->lpipos < lp->nlpirows);
1603  assert(col->lpipos < lp->nlpicols);
1604 
1605  /* we have to remember the change only in the row or in the column,
1606  * because the readdition of one vector would change the other automatically.
1607  */
1608  if( row->lpipos >= lp->lpifirstchgrow )
1609  row->coefchanged = TRUE;
1610  else if( col->lpipos >= lp->lpifirstchgcol )
1611  col->coefchanged = TRUE;
1612  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1613  {
1614  row->coefchanged = TRUE;
1615  lp->lpifirstchgrow = row->lpipos;
1616  }
1617  else
1618  {
1619  col->coefchanged = TRUE;
1620  lp->lpifirstchgcol = col->lpipos;
1621  }
1622 
1623  /* mark the current LP unflushed */
1624  lp->flushed = FALSE;
1625  }
1626 
1628  row->minactivity = SCIP_INVALID;
1629  row->maxactivity = SCIP_INVALID;
1630  row->validpsactivitydomchg = -1;
1631  row->validactivitybdsdomchg = -1;
1632 }
1633 
1634 
1635 
1636 /*
1637  * local column changing methods
1638  */
1639 
1640 /* forward declaration for colAddCoef() */
1641 static
1643  SCIP_ROW* row, /**< LP row */
1644  BMS_BLKMEM* blkmem, /**< block memory */
1645  SCIP_SET* set, /**< global SCIP settings */
1646  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1647  SCIP_LP* lp, /**< current LP data */
1648  SCIP_COL* col, /**< LP column */
1649  SCIP_Real val, /**< value of coefficient */
1650  int linkpos /**< position of row in the column's row array, or -1 */
1651  );
1652 
1653 /** adds a previously non existing coefficient to an LP column */
1654 static
1656  SCIP_COL* col, /**< LP column */
1657  BMS_BLKMEM* blkmem, /**< block memory */
1658  SCIP_SET* set, /**< global SCIP settings */
1659  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1660  SCIP_LP* lp, /**< current LP data */
1661  SCIP_ROW* row, /**< LP row */
1662  SCIP_Real val, /**< value of coefficient */
1663  int linkpos /**< position of column in the row's col array, or -1 */
1664  )
1665 {
1666  int pos;
1667 
1668  assert(blkmem != NULL);
1669  assert(col != NULL);
1670  assert(col->nlprows <= col->len);
1671  assert(col->var != NULL);
1672  assert(row != NULL);
1673  assert(!SCIPsetIsZero(set, val));
1674  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1675 
1676  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1677  assert(col->rows != NULL);
1678  assert(col->vals != NULL);
1679  assert(col->linkpos != NULL);
1680 
1681  pos = col->len;
1682  col->len++;
1683 
1684  /* if the row is in current LP and is linked to the column, we have to insert it at the end of the linked LP rows
1685  * part of the column's arrays
1686  */
1687  if( row->lppos >= 0 && linkpos >= 0 )
1688  {
1689  /* move the first non-LP/not linked row to the end */
1690  if( col->nlprows < pos )
1691  {
1692  colMoveCoef(col, col->nlprows, pos);
1693  pos = col->nlprows;
1694  }
1695  col->nlprows++;
1696  }
1697 
1698  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1699  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1700 
1701  /* insert the row at the correct position and update the links */
1702  col->rows[pos] = row;
1703  col->vals[pos] = val;
1704  col->linkpos[pos] = linkpos;
1705  if( linkpos == -1 )
1706  {
1707  col->nunlinked++;
1708 
1709  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1710  * of the row is not complete
1711  */
1712  if( col->lppos >= 0 )
1713  {
1714  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1715  * has to be updated
1716  */
1717  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1718  if( row->lppos >= 0 )
1719  pos = col->nlprows-1;
1720  linkpos = col->linkpos[pos];
1721 
1722  assert(0 <= linkpos && linkpos < row->len);
1723  assert(row->cols[linkpos] == col);
1724  assert(col->rows[pos] == row);
1725  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1726  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1727  }
1728  }
1729  else
1730  {
1731  assert(row->linkpos[linkpos] == -1);
1732  assert(row->nunlinked > 0);
1733  row->linkpos[linkpos] = pos;
1734  row->nunlinked--;
1735 
1736  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1737  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1738  */
1739  if( col->lppos >= 0 )
1740  {
1741  row->nlpcols++;
1742  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1743 
1744  /* if no swap was necessary, mark nonlpcols to be unsorted */
1745  if( linkpos == row->nlpcols-1 )
1746  row->lpcolssorted = FALSE;
1747  }
1748  }
1749 
1750  /* update the sorted flags */
1751  if( row->lppos >= 0 && linkpos >= 0 )
1752  {
1753  assert(col->nlprows >= 1);
1754  assert(col->rows[col->nlprows-1] == row);
1755  if( col->nlprows > 1 )
1756  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1757  }
1758  else
1759  {
1760  assert(col->len - col->nlprows >= 1);
1761  assert(col->rows[col->len-1] == row);
1762  if( col->len - col->nlprows > 1 )
1763  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1764  }
1765 
1766  coefChanged(row, col, lp);
1767 
1768  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1769  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1770 
1771  return SCIP_OKAY;
1772 }
1773 
1774 /** deletes coefficient at given position from column */
1775 static
1777  SCIP_COL* col, /**< column to be changed */
1778  SCIP_SET* set, /**< global SCIP settings */
1779  SCIP_LP* lp, /**< current LP data */
1780  int pos /**< position in column vector to delete */
1781  )
1782 {
1783  SCIP_ROW* row;
1784 
1785  assert(col != NULL);
1786  assert(col->var != NULL);
1787  assert(set != NULL);
1788  assert(0 <= pos && pos < col->len);
1789  assert(col->rows[pos] != NULL);
1790  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1791  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1792 
1793  row = col->rows[pos];
1794  assert((row->lppos >= 0) == (pos < col->nlprows));
1795 
1796  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1797  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1798 
1799  if( col->linkpos[pos] == -1 )
1800  col->nunlinked--;
1801 
1802  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1803  if( pos < col->nlprows )
1804  {
1805  colMoveCoef(col, col->nlprows-1, pos);
1806  col->nlprows--;
1807  pos = col->nlprows;
1808  }
1809 
1810  /* move last coefficient to position of empty slot */
1811  colMoveCoef(col, col->len-1, pos);
1812  col->len--;
1813 
1814  coefChanged(row, col, lp);
1815 
1816  return SCIP_OKAY;
1817 }
1818 
1819 /** changes a coefficient at given position of an LP column */
1820 static
1822  SCIP_COL* col, /**< LP column */
1823  SCIP_SET* set, /**< global SCIP settings */
1824  SCIP_LP* lp, /**< current LP data */
1825  int pos, /**< position in column vector to change */
1826  SCIP_Real val /**< value of coefficient */
1827  )
1828 {
1829  assert(col != NULL);
1830  assert(col->var != NULL);
1831  assert(0 <= pos && pos < col->len);
1832  assert(col->rows[pos] != NULL);
1833  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1834 
1835  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1836  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1837 
1838  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1839  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1840 
1841  if( SCIPsetIsZero(set, val) )
1842  {
1843  /* delete existing coefficient */
1844  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1845  }
1846  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1847  {
1848  /* change existing coefficient */
1849  col->vals[pos] = val;
1850  coefChanged(col->rows[pos], col, lp);
1851  }
1852 
1853  return SCIP_OKAY;
1854 }
1855 
1856 
1857 
1858 
1859 /*
1860  * local row changing methods
1861  */
1862 
1863 /** update row norms after addition of coefficient */
1864 static
1866  SCIP_ROW* row, /**< LP row */
1867  SCIP_SET* set, /**< global SCIP settings */
1868  SCIP_COL* col, /**< column of added coefficient */
1869  SCIP_Real val, /**< value of added coefficient */
1870  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1871  )
1872 {
1873  SCIP_Real absval;
1874 
1875  assert(row != NULL);
1876  assert(row->nummaxval >= 0);
1877  assert(row->numminval >= 0);
1878  assert(set != NULL);
1879  assert(col != NULL);
1880 
1881  absval = REALABS(val);
1882  assert(!SCIPsetIsZero(set, absval));
1883 
1884  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1885  if( col->lppos >= 0 )
1886  {
1887  /* update squared Euclidean norm and sum norm */
1888  row->sqrnorm += SQR(absval);
1889  row->sumnorm += absval;
1890 
1891  /* update objective function scalar product */
1892  row->objprod += val * col->unchangedobj;
1893  }
1894 
1895  if( updateidxvals )
1896  {
1897  /* update min/maxidx */
1898  row->minidx = MIN(row->minidx, col->index);
1899  row->maxidx = MAX(row->maxidx, col->index);
1900 
1901  /* update maximal and minimal non-zero value */
1902  if( row->nummaxval > 0 )
1903  {
1904  if( SCIPsetIsGT(set, absval, row->maxval) )
1905  {
1906  row->maxval = absval;
1907  row->nummaxval = 1;
1908  }
1909  else if( SCIPsetIsGE(set, absval, row->maxval) )
1910  row->nummaxval++;
1911  }
1912  if( row->numminval > 0 )
1913  {
1914  if( SCIPsetIsLT(set, absval, row->minval) )
1915  {
1916  row->minval = absval;
1917  row->numminval = 1;
1918  }
1919  else if( SCIPsetIsLE(set, absval, row->minval) )
1920  row->numminval++;
1921  }
1922  }
1923  else
1924  {
1925  assert(row->minidx <= col->index);
1926  assert(row->maxidx >= col->index);
1927  assert(row->numminval <= 0 || SCIPsetIsGE(set, absval, row->minval));
1928  assert(row->nummaxval <= 0 || SCIPsetIsLE(set, absval, row->maxval));
1929  }
1930 }
1931 
1932 /** update row norms after deletion of coefficient */
1933 static
1935  SCIP_ROW* row, /**< LP row */
1936  SCIP_SET* set, /**< global SCIP settings */
1937  SCIP_COL* col, /**< column of deleted coefficient */
1938  SCIP_Real val, /**< value of deleted coefficient */
1939  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1940  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1941  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1942  )
1943 {
1944  SCIP_Real absval;
1945 
1946  assert(row != NULL);
1947  assert(row->nummaxval >= 0);
1948  assert(row->numminval >= 0);
1949  assert(set != NULL);
1950  assert(col != NULL);
1951 
1952  absval = REALABS(val);
1953  assert(!SCIPsetIsZero(set, absval));
1954  assert(row->nummaxval == 0 || SCIPsetIsGE(set, row->maxval, absval));
1955  assert(row->numminval == 0 || SCIPsetIsLE(set, row->minval, absval));
1956 
1957  /* update min/maxidx validity */
1958  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
1959  row->validminmaxidx = FALSE;
1960 
1961  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1962  if( forcenormupdate || col->lppos >= 0 )
1963  {
1964  /* update squared Euclidean norm and sum norm */
1965  row->sqrnorm -= SQR(absval);
1966  row->sqrnorm = MAX(row->sqrnorm, 0.0);
1967  row->sumnorm -= absval;
1968  row->sumnorm = MAX(row->sumnorm, 0.0);
1969 
1970  /* update objective function scalar product */
1971  row->objprod -= val * col->unchangedobj;
1972  }
1973 
1974  if( updateval )
1975  {
1976  /* update maximal and minimal non-zero value */
1977  if( row->nummaxval > 0 )
1978  {
1979  if( SCIPsetIsGE(set, absval, row->maxval) )
1980  row->nummaxval--;
1981  }
1982  if( row->numminval > 0 )
1983  {
1984  if( SCIPsetIsLE(set, absval, row->minval) )
1985  row->numminval--;
1986  }
1987  }
1988 }
1989 
1990 /** adds a previously non existing coefficient to an LP row */
1991 static
1993  SCIP_ROW* row, /**< LP row */
1994  BMS_BLKMEM* blkmem, /**< block memory */
1995  SCIP_SET* set, /**< global SCIP settings */
1996  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1997  SCIP_LP* lp, /**< current LP data */
1998  SCIP_COL* col, /**< LP column */
1999  SCIP_Real val, /**< value of coefficient */
2000  int linkpos /**< position of row in the column's row array, or -1 */
2001  )
2002 {
2003  int pos;
2004 
2005  assert(row != NULL);
2006  assert(row->nlpcols <= row->len);
2007  assert(blkmem != NULL);
2008  assert(col != NULL);
2009  assert(col->var != NULL);
2010  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2011  assert(!SCIPsetIsZero(set, val));
2012  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2013 
2014  if( row->nlocks > 0 )
2015  {
2016  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2017  return SCIP_INVALIDDATA;
2018  }
2019 
2020  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2021  assert(row->cols != NULL);
2022  assert(row->vals != NULL);
2023 
2024  pos = row->len;
2025  row->len++;
2026 
2027  /* 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
2028  * part of the row's arrays
2029  */
2030  if( col->lppos >= 0 && linkpos >= 0 )
2031  {
2032  /* move the first non-LP/not linked column to the end */
2033  if( row->nlpcols < pos )
2034  {
2035  rowMoveCoef(row, row->nlpcols, pos);
2036  pos = row->nlpcols;
2037  }
2038  row->nlpcols++;
2039  }
2040 
2041  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2042  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2043 
2044  /* insert the column at the correct position and update the links */
2045  row->cols[pos] = col;
2046  row->cols_index[pos] = col->index;
2047  row->vals[pos] = val;
2048  row->linkpos[pos] = linkpos;
2049  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2050  if( linkpos == -1 )
2051  {
2052  row->nunlinked++;
2053 
2054  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2055  * of the column is not complete
2056  */
2057  if( row->lppos >= 0 )
2058  {
2059  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2060  * has to be updated
2061  */
2062  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2063  if( col->lppos >= 0 )
2064  pos = row->nlpcols-1;
2065  linkpos = row->linkpos[pos];
2066 
2067  assert(0 <= linkpos && linkpos < col->len);
2068  assert(col->rows[linkpos] == row);
2069  assert(row->cols[pos] == col);
2070  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2071  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2072  }
2073  }
2074  else
2075  {
2076  assert(col->linkpos[linkpos] == -1);
2077  assert(col->nunlinked > 0);
2078  col->linkpos[linkpos] = pos;
2079  col->nunlinked--;
2080 
2081  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2082  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2083  */
2084  if( row->lppos >= 0 )
2085  {
2086  col->nlprows++;
2087  colSwapCoefs(col, linkpos, col->nlprows-1);
2088 
2089  /* if no swap was necessary, mark lprows to be unsorted */
2090  if( linkpos == col->nlprows-1 )
2091  col->lprowssorted = FALSE;
2092  }
2093  }
2094 
2095  /* update the sorted flags */
2096  if( col->lppos >= 0 && linkpos >= 0 )
2097  {
2098  assert(row->nlpcols >= 1);
2099  assert(row->cols[row->nlpcols-1] == col);
2100  if( row->nlpcols > 1 )
2101  {
2102  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2103  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2104  }
2105  }
2106  else
2107  {
2108  assert(row->len - row->nlpcols >= 1);
2109  assert(row->cols[row->len-1] == col);
2110  if( row->len - row->nlpcols > 1 )
2111  {
2112  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2113  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2114  }
2115  }
2116 
2117  /* update row norm */
2118  rowAddNorms(row, set, col, val, TRUE);
2119 
2120  coefChanged(row, col, lp);
2121 
2122  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2123  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2124 
2125  /* issue row coefficient changed event */
2126  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2127 
2128  return SCIP_OKAY;
2129 }
2130 
2131 /** deletes coefficient at given position from row */
2132 static
2134  SCIP_ROW* row, /**< row to be changed */
2135  BMS_BLKMEM* blkmem, /**< block memory */
2136  SCIP_SET* set, /**< global SCIP settings */
2137  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2138  SCIP_LP* lp, /**< current LP data */
2139  int pos /**< position in row vector to delete */
2140  )
2141 {
2142  SCIP_COL* col;
2143  SCIP_Real val;
2144 
2145  assert(row != NULL);
2146  assert(set != NULL);
2147  assert(0 <= pos && pos < row->len);
2148  assert(row->cols[pos] != NULL);
2149  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2150 
2151  col = row->cols[pos];
2152  val = row->vals[pos];
2153  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2154 
2155  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2156  val, SCIPvarGetName(col->var), pos, row->name);*/
2157 
2158  if( row->nlocks > 0 )
2159  {
2160  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2161  return SCIP_INVALIDDATA;
2162  }
2163 
2164  if( row->linkpos[pos] == -1 )
2165  row->nunlinked--;
2166 
2167  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2168  if( pos < row->nlpcols )
2169  {
2170  rowMoveCoef(row, row->nlpcols-1, pos);
2171  assert(!row->lpcolssorted);
2172  row->nlpcols--;
2173  pos = row->nlpcols;
2174  }
2175 
2176  /* move last coefficient to position of empty slot */
2177  rowMoveCoef(row, row->len-1, pos);
2178  row->len--;
2179 
2180  /* update norms */
2181  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2182 
2183  coefChanged(row, col, lp);
2184 
2185  /* issue row coefficient changed event */
2186  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2187 
2188  return SCIP_OKAY;
2189 }
2190 
2191 /** changes a coefficient at given position of an LP row */
2192 static
2194  SCIP_ROW* row, /**< LP row */
2195  BMS_BLKMEM* blkmem, /**< block memory */
2196  SCIP_SET* set, /**< global SCIP settings */
2197  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2198  SCIP_LP* lp, /**< current LP data */
2199  int pos, /**< position in row vector to change */
2200  SCIP_Real val /**< value of coefficient */
2201  )
2202 {
2203  SCIP_COL* col;
2204 
2205  assert(row != NULL);
2206  assert(0 <= pos && pos < row->len);
2207 
2208  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2209  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2210 
2211  if( row->nlocks > 0 )
2212  {
2213  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2214  return SCIP_INVALIDDATA;
2215  }
2216 
2217  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2218  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2219  col = row->cols[pos];
2220  assert(row->cols[pos] != NULL);
2221 
2222  if( SCIPsetIsZero(set, val) )
2223  {
2224  /* delete existing coefficient */
2225  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2226  }
2227  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2228  {
2229  SCIP_Real oldval;
2230 
2231  oldval = row->vals[pos];
2232 
2233  /* change existing coefficient */
2234  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2235  row->vals[pos] = val;
2236  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2237  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2238  coefChanged(row, col, lp);
2239 
2240  /* issue row coefficient changed event */
2241  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2242  }
2243 
2244  return SCIP_OKAY;
2245 }
2246 
2247 /** notifies LP row, that its sides were changed */
2248 static
2250  SCIP_ROW* row, /**< LP row */
2251  SCIP_SET* set, /**< global SCIP settings */
2252  SCIP_LP* lp, /**< current LP data */
2253  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2254  )
2255 {
2256  assert(row != NULL);
2257  assert(lp != NULL);
2258 
2259  if( row->lpipos >= 0 )
2260  {
2261  /* insert row in the chgrows list (if not already there) */
2262  if( !row->lhschanged && !row->rhschanged )
2263  {
2264  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2265  lp->chgrows[lp->nchgrows] = row;
2266  lp->nchgrows++;
2267  }
2268 
2269  /* mark side change in the row */
2270  switch( sidetype )
2271  {
2272  case SCIP_SIDETYPE_LEFT:
2273  row->lhschanged = TRUE;
2274  break;
2275  case SCIP_SIDETYPE_RIGHT:
2276  row->rhschanged = TRUE;
2277  break;
2278  default:
2279  SCIPerrorMessage("unknown row side type\n");
2280  SCIPABORT();
2281  return SCIP_INVALIDDATA; /*lint !e527*/
2282  }
2283 
2284  /* mark the current LP unflushed */
2285  lp->flushed = FALSE;
2286 
2287  assert(lp->nchgrows > 0);
2288  }
2289 
2290  return SCIP_OKAY;
2291 }
2292 
2293 
2294 
2295 
2296 /*
2297  * double linked coefficient matrix methods
2298  */
2299 
2300 /** insert column coefficients in corresponding rows */
2301 static
2303  SCIP_COL* col, /**< column data */
2304  BMS_BLKMEM* blkmem, /**< block memory */
2305  SCIP_SET* set, /**< global SCIP settings */
2306  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2307  SCIP_LP* lp /**< current LP data */
2308  )
2309 {
2310  int i;
2311 
2312  assert(col != NULL);
2313  assert(col->var != NULL);
2314  assert(blkmem != NULL);
2315  assert(set != NULL);
2316  assert(lp != NULL);
2317 
2318  if( col->nunlinked > 0 )
2319  {
2320  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2321 
2322  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2323  for( i = col->nlprows; i < col->len; ++i )
2324  {
2325  assert(!SCIPsetIsZero(set, col->vals[i]));
2326  if( col->linkpos[i] == -1 )
2327  {
2328  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2329  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2330  }
2331  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2332  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2333  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2334  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2335  }
2336  }
2337  assert(col->nunlinked == 0);
2338 
2339  checkLinks(lp);
2340 
2341  return SCIP_OKAY;
2342 }
2343 
2344 /** removes column coefficients from corresponding rows */
2345 static
2347  SCIP_COL* col, /**< column data */
2348  BMS_BLKMEM* blkmem, /**< block memory */
2349  SCIP_SET* set, /**< global SCIP settings */
2350  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2351  SCIP_LP* lp /**< current LP data */
2352  )
2353 {
2354  int i;
2355 
2356  assert(col != NULL);
2357  assert(col->var != NULL);
2358  assert(blkmem != NULL);
2359  assert(set != NULL);
2360  assert(lp != NULL);
2361 
2362  if( col->nunlinked < col->len )
2363  {
2364  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2365  for( i = 0; i < col->len; ++i )
2366  {
2367  if( col->linkpos[i] >= 0 )
2368  {
2369  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2370  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2371  col->linkpos[i] = -1;
2372  col->nunlinked++;
2373  }
2374  }
2375  }
2376  assert(col->nunlinked == col->len);
2377 
2378  checkLinks(lp);
2379 
2380  return SCIP_OKAY;
2381 }
2382 
2383 /** insert row coefficients in corresponding columns */
2384 static
2386  SCIP_ROW* row, /**< row data */
2387  BMS_BLKMEM* blkmem, /**< block memory */
2388  SCIP_SET* set, /**< global SCIP settings */
2389  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2390  SCIP_LP* lp /**< current LP data */
2391  )
2392 {
2393  int i;
2394 
2395  assert(row != NULL);
2396  assert(blkmem != NULL);
2397  assert(set != NULL);
2398  assert(lp != NULL);
2399 
2400  if( row->nunlinked > 0 )
2401  {
2402  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2403 
2404  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2405  for( i = row->nlpcols; i < row->len; ++i )
2406  {
2407  assert(!SCIPsetIsZero(set, row->vals[i]));
2408  if( row->linkpos[i] == -1 )
2409  {
2410  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2411  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2412  }
2413  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2414  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2415  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2416  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2417  }
2418  }
2419  assert(row->nunlinked == 0);
2420 
2421  checkLinks(lp);
2422 
2423  return SCIP_OKAY;
2424 }
2425 
2426 /** removes row coefficients from corresponding columns */
2427 static
2429  SCIP_ROW* row, /**< row data */
2430  SCIP_SET* set, /**< global SCIP settings */
2431  SCIP_LP* lp /**< current LP data */
2432  )
2433 {
2434  int i;
2435 
2436  assert(row != NULL);
2437  assert(set != NULL);
2438  assert(lp != NULL);
2439 
2440  if( row->nunlinked < row->len )
2441  {
2442  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2443  for( i = 0; i < row->len; ++i )
2444  {
2445  if( row->linkpos[i] >= 0 )
2446  {
2447  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2448  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2449  row->nunlinked++;
2450  }
2451  }
2452  }
2453  assert(row->nunlinked == row->len);
2454 
2455  return SCIP_OKAY;
2456 }
2457 
2458 
2459 
2460 
2461 /*
2462  * local LP parameter methods
2463  */
2464 
2465 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2466 static
2468  SCIP_LP* lp, /**< current LP data */
2469  SCIP_LPPARAM lpparam, /**< LP parameter */
2470  int value, /**< value to set parameter to */
2471  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2472  )
2473 {
2474  SCIP_RETCODE retcode;
2475 
2476  assert(lp != NULL);
2477  assert(success != NULL);
2478 
2479  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2480 
2481  /* check, if parameter is unknown */
2482  if( retcode == SCIP_PARAMETERUNKNOWN )
2483  {
2484  *success = FALSE;
2485  return SCIP_OKAY;
2486  }
2487  *success = TRUE;
2488 
2489  return retcode;
2490 }
2491 
2492 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2493 static
2495  SCIP_LP* lp, /**< current LP data */
2496  SCIP_LPPARAM lpparam, /**< LP parameter */
2497  SCIP_Bool value, /**< value to set parameter to */
2498  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2499  )
2500 {
2501  return lpSetIntpar(lp, lpparam, (int)value, success);
2502 }
2503 
2504 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2505 static
2507  SCIP_LP* lp, /**< current LP data */
2508  SCIP_LPPARAM lpparam, /**< LP parameter */
2509  SCIP_Real value, /**< value to set parameter to */
2510  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2511  )
2512 {
2513  SCIP_RETCODE retcode;
2514 
2515  assert(lp != NULL);
2516  assert(success != NULL);
2517 
2518  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2519 
2520  /* check, if parameter is unknown */
2521  if( retcode == SCIP_PARAMETERUNKNOWN )
2522  {
2523  *success = FALSE;
2524  return SCIP_OKAY;
2525  }
2526  *success = TRUE;
2527 
2528  return retcode;
2529 }
2530 
2531 #ifndef NDEBUG
2532 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2533 static
2535  SCIP_LP* lp, /**< current LP data */
2536  SCIP_LPPARAM lpparam, /**< LP parameter */
2537  int value /**< value parameter should have */
2538  )
2539 {
2540  SCIP_RETCODE retcode;
2541  int lpivalue;
2542 
2543  assert(lp != NULL);
2544 
2545  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2546 
2547  /* ignore unknown parameter error */
2548  if( retcode == SCIP_PARAMETERUNKNOWN )
2549  return SCIP_OKAY;
2550 
2551  /* check value */
2552  assert(lpivalue == value);
2553 
2554  return retcode;
2555 }
2556 
2557 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2558 static
2560  SCIP_LP* lp, /**< current LP data */
2561  SCIP_LPPARAM lpparam, /**< LP parameter */
2562  SCIP_Bool value /**< value parameter should have */
2563  )
2564 {
2565  return lpCheckIntpar(lp, lpparam, (int)value);
2566 }
2567 
2568 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2569 static
2571  SCIP_LP* lp, /**< current LP data */
2572  SCIP_LPPARAM lpparam, /**< LP parameter */
2573  SCIP_Real value /**< value parameter should have */
2574  )
2575 {
2576  SCIP_RETCODE retcode;
2577  SCIP_Real lpivalue;
2578 
2579  assert(lp != NULL);
2580 
2581  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2582 
2583  /* ignore unknown parameter error */
2584  if( retcode == SCIP_PARAMETERUNKNOWN )
2585  return SCIP_OKAY;
2586 
2587  /* check value */
2588  assert(lpivalue == value); /*lint !e777*/
2589 
2590  return retcode;
2591 }
2592 #else
2593 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2594 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2595 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2596 #endif
2597 
2598 /** should the objective limit of the LP solver be disabled */
2599 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2600 
2601 /** sets the upper objective limit of the LP solver */
2602 static
2604  SCIP_LP* lp, /**< current LP data */
2605  SCIP_SET* set, /**< global SCIP settings */
2606  SCIP_Real uobjlim /**< new feasibility tolerance */
2607  )
2608 {
2609  assert(lp != NULL);
2610  assert(set != NULL);
2611 
2612  /* we disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2613  * solver's objective limit handling, so we return here and do not apply the objective limit
2614  */
2615  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2616  return SCIP_OKAY;
2617 
2618  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2619  if( SCIPsetIsInfinity(set, uobjlim) )
2620  uobjlim = SCIPlpiInfinity(lp->lpi);
2621 
2623 
2624  if( uobjlim != lp->lpiuobjlim ) /*lint !e777*/
2625  {
2626  SCIP_Bool success;
2627 
2628  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_UOBJLIM, uobjlim, &success) );
2629  if( success )
2630  {
2631  /* mark the current solution invalid */
2632  lp->solved = FALSE;
2633  lp->primalfeasible = FALSE;
2634  lp->primalchecked = FALSE;
2635  lp->lpobjval = SCIP_INVALID;
2637  lp->lpiuobjlim = uobjlim;
2638  }
2639  }
2640 
2641  return SCIP_OKAY;
2642 }
2643 
2644 /** sets the feasibility tolerance of the LP solver */
2645 static
2647  SCIP_LP* lp, /**< current LP data */
2648  SCIP_Real feastol, /**< new feasibility tolerance */
2649  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2650  )
2651 {
2652  assert(lp != NULL);
2653  assert(feastol >= 0.0);
2654  assert(success != NULL);
2655 
2657 
2658  if( feastol != lp->lpifeastol ) /*lint !e777*/
2659  {
2660  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2661  if( *success )
2662  {
2663  if( lp->nrows > 0 && feastol < lp->lpifeastol )
2664  {
2665  /* mark the current solution invalid */
2666  lp->solved = FALSE;
2667  lp->primalfeasible = FALSE;
2668  lp->primalchecked = FALSE;
2669  lp->lpobjval = SCIP_INVALID;
2671  }
2672  lp->lpifeastol = feastol;
2673  }
2674  }
2675  else
2676  *success = FALSE;
2677 
2678  return SCIP_OKAY;
2679 }
2680 
2681 /** sets the reduced costs feasibility tolerance of the LP solver */
2682 static
2684  SCIP_LP* lp, /**< current LP data */
2685  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2686  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2687  )
2688 {
2689  assert(lp != NULL);
2690  assert(dualfeastol >= 0.0);
2691  assert(success != NULL);
2692 
2694 
2695  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2696  {
2697  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2698  if( *success )
2699  {
2700  if( lp->nrows > 0 && dualfeastol < lp->lpidualfeastol )
2701  {
2702  /* mark the current solution invalid */
2703  lp->solved = FALSE;
2704  lp->dualfeasible = FALSE;
2705  lp->dualchecked = FALSE;
2706  lp->lpobjval = SCIP_INVALID;
2708  }
2709  lp->lpidualfeastol = dualfeastol;
2710  }
2711  }
2712  else
2713  *success = FALSE;
2714 
2715  return SCIP_OKAY;
2716 }
2717 
2718 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2719 static
2721  SCIP_LP* lp, /**< current LP data */
2722  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2723  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2724  )
2725 {
2726  assert(lp != NULL);
2727  assert(barrierconvtol >= 0.0);
2728  assert(success != NULL);
2729 
2731 
2732  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2733  {
2734  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2735  if( *success )
2736  {
2737  if( lp->nrows > 0 && barrierconvtol < lp->lpibarrierconvtol
2739  {
2740  /* mark the current solution invalid */
2741  lp->solved = FALSE;
2742  lp->dualfeasible = FALSE;
2743  lp->dualchecked = FALSE;
2744  lp->lpobjval = SCIP_INVALID;
2746  }
2747  lp->lpibarrierconvtol = barrierconvtol;
2748  }
2749  }
2750  else
2751  *success = FALSE;
2752 
2753  return SCIP_OKAY;
2754 }
2755 
2756 /** sets the FROMSCRATCH setting of the LP solver */
2757 static
2759  SCIP_LP* lp, /**< current LP data */
2760  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2761  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2762  )
2763 {
2764  assert(lp != NULL);
2765  assert(success != NULL);
2766 
2768 
2769  if( fromscratch != lp->lpifromscratch )
2770  {
2771  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2772  if( *success )
2773  lp->lpifromscratch = fromscratch;
2774  }
2775  else
2776  *success = FALSE;
2777 
2778  return SCIP_OKAY;
2779 }
2780 
2781 /** sets the FASTMIP setting of the LP solver */
2782 static
2784  SCIP_LP* lp, /**< current LP data */
2785  int fastmip, /**< new FASTMIP setting */
2786  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2787  )
2788 {
2789  assert(lp != NULL);
2790  assert(success != NULL);
2791  assert(0 <= fastmip && fastmip <= 1);
2792 
2794 
2795  if( fastmip != lp->lpifastmip )
2796  {
2797  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2798  if( *success )
2799  lp->lpifastmip = fastmip;
2800  }
2801  else
2802  *success = FALSE;
2803 
2804  return SCIP_OKAY;
2805 }
2806 
2807 /** sets the SCALING setting of the LP solver */
2808 static
2810  SCIP_LP* lp, /**< current LP data */
2811  int scaling, /**< new SCALING setting */
2812  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2813  )
2814 {
2815  assert(lp != NULL);
2816  assert(success != NULL);
2817 
2819 
2820  if( scaling != lp->lpiscaling )
2821  {
2822  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2823  if( *success )
2824  lp->lpiscaling = scaling;
2825  }
2826  else
2827  *success = FALSE;
2828 
2829  return SCIP_OKAY;
2830 }
2831 
2832 /** sets the number of THREADS of the LP solver */
2833 static
2835  SCIP_LP* lp, /**< current LP data */
2836  int threads, /**< new number of threads used to solve the LP */
2837  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2838  )
2839 {
2840  assert(lp != NULL);
2841  assert(success != NULL);
2842 
2844 
2845  if( threads != lp->lpithreads )
2846  {
2847  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2848  if( *success )
2849  lp->lpithreads = threads;
2850  }
2851  else
2852  *success = FALSE;
2853 
2854  return SCIP_OKAY;
2855 }
2856 
2857 /** sets the PRESOLVING setting of the LP solver */
2858 static
2860  SCIP_LP* lp, /**< current LP data */
2861  SCIP_Bool presolving, /**< new PRESOLVING setting */
2862  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2863  )
2864 {
2865  assert(lp != NULL);
2866  assert(success != NULL);
2867 
2869 
2870  if( presolving != lp->lpipresolving )
2871  {
2872  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2873  if( *success )
2874  lp->lpipresolving = presolving;
2875  }
2876  else
2877  *success = FALSE;
2878 
2879  return SCIP_OKAY;
2880 }
2881 
2882 /** sets the ROWREPSWITCH setting of the LP solver */
2883 static
2885  SCIP_LP* lp, /**< current LP data */
2886  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2887  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2888  )
2889 {
2890  assert(lp != NULL);
2891  assert(success != NULL);
2892 
2894 
2895  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2896  {
2897  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2898  if( *success )
2899  lp->lpirowrepswitch = rowrepswitch;
2900  }
2901  else
2902  *success = FALSE;
2903 
2904  return SCIP_OKAY;
2905 }
2906 
2907 /** sets the iteration limit of the LP solver */
2908 static
2910  SCIP_LP* lp, /**< current LP data */
2911  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2912  )
2913 {
2914  SCIP_Bool success;
2915 
2916  assert(lp != NULL);
2917  assert(itlim >= -1);
2918 
2919  if( itlim == -1 )
2920  itlim = INT_MAX;
2921 
2923 
2924  if( itlim != lp->lpiitlim )
2925  {
2926  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2927  if( success )
2928  {
2929  if( itlim > lp->lpiitlim )
2930  {
2931  /* mark the current solution invalid */
2932  lp->solved = FALSE;
2933  lp->lpobjval = SCIP_INVALID;
2935  }
2936  lp->lpiitlim = itlim;
2937  }
2938  }
2939 
2940  return SCIP_OKAY;
2941 }
2942 
2943 /** sets the pricing strategy of the LP solver */
2944 static
2946  SCIP_LP* lp, /**< current LP data */
2947  SCIP_PRICING pricing /**< pricing strategy */
2948  )
2949 {
2950  SCIP_Bool success;
2951 
2952  assert(lp != NULL);
2953 
2955 
2956  if( pricing != lp->lpipricing )
2957  {
2958  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
2959  if( success )
2960  lp->lpipricing = pricing;
2961  }
2962 
2963  return SCIP_OKAY;
2964 }
2965 
2966 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
2967 static
2969  SCIP_LP* lp, /**< current LP data */
2970  char pricingchar /**< character representing the pricing strategy */
2971  )
2972 {
2973  SCIP_PRICING pricing;
2974 
2975  switch( pricingchar )
2976  {
2977  case 'l':
2978  pricing = SCIP_PRICING_LPIDEFAULT;
2979  break;
2980  case 'a':
2981  pricing = SCIP_PRICING_AUTO;
2982  break;
2983  case 'f':
2984  pricing = SCIP_PRICING_FULL;
2985  break;
2986  case 'p':
2987  pricing = SCIP_PRICING_PARTIAL;
2988  break;
2989  case 's':
2990  pricing = SCIP_PRICING_STEEP;
2991  break;
2992  case 'q':
2993  pricing = SCIP_PRICING_STEEPQSTART;
2994  break;
2995  case 'd':
2996  pricing = SCIP_PRICING_DEVEX;
2997  break;
2998  default:
2999  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3000  return SCIP_INVALIDDATA;
3001  }
3002 
3003  SCIP_CALL( lpSetPricing(lp, pricing) );
3004 
3005  return SCIP_OKAY;
3006 }
3007 
3008 /** sets the verbosity of the LP solver */
3009 static
3011  SCIP_LP* lp, /**< current LP data */
3012  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3013  )
3014 {
3015  SCIP_Bool success;
3016 
3017  assert(lp != NULL);
3018 
3020 
3021  if( lpinfo != lp->lpilpinfo )
3022  {
3023  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3024  if( success )
3025  lp->lpilpinfo = lpinfo;
3026  }
3027 
3028  return SCIP_OKAY;
3029 }
3030 
3031 /** sets the CONDITIONLIMIT setting of the LP solver */
3032 static
3034  SCIP_LP* lp, /**< current LP data */
3035  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3036  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3037  )
3038 {
3039  assert(lp != NULL);
3040  assert(success != NULL);
3041 
3043 
3044  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3045  {
3046  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3047  if( *success )
3048  lp->lpiconditionlimit = condlimit;
3049  }
3050  else
3051  *success = FALSE;
3052 
3053  return SCIP_OKAY;
3054 }
3055 
3056 /** sets the type of timer of the LP solver */
3057 static
3059  SCIP_LP* lp, /**< current LP data */
3060  SCIP_CLOCKTYPE timing, /**< new timing value */
3061  SCIP_Bool enabled, /**< is timing enabled? */
3062  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3063  )
3064 {
3065  int lptiming;
3066 
3067  assert(lp != NULL);
3068  assert(success != NULL);
3069  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2);
3070 
3072 
3073  if( !enabled )
3074  lptiming = 0;
3075  else
3076  lptiming = (int) timing;
3077 
3078  if( lptiming != lp->lpitiming ) /*lint !e777*/
3079  {
3080  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3081  if( *success )
3082  lp->lpitiming = lptiming;
3083  }
3084  else
3085  *success = FALSE;
3086 
3087  return SCIP_OKAY;
3088 }
3089 
3090 /** sets the initial random seed of the LP solver */
3091 static
3093  SCIP_LP* lp, /**< current LP data */
3094  int randomseed, /**< new initial random seed */
3095  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3096  )
3097 {
3098  assert(lp != NULL);
3099  assert(success != NULL);
3100 
3101  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3102 
3103  if( randomseed == 0 )
3104  {
3105  lp->lpirandomseed = randomseed;
3106  *success = TRUE;
3107  }
3108  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3109  {
3110  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3111  if( *success )
3112  lp->lpirandomseed = randomseed;
3113  }
3114  else
3115  *success = FALSE;
3116 
3117  return SCIP_OKAY;
3118 }
3119 
3120 /** sets the LP solution polishing method */
3121 static
3123  SCIP_LP* lp, /**< current LP data */
3124  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3125  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3126  )
3127 {
3128  assert(lp != NULL);
3129  assert(success != NULL);
3130 
3131  if( polishing != lp->lpisolutionpolishing )
3132  {
3133  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3134  if( *success )
3135  lp->lpisolutionpolishing = polishing;
3136  }
3137  else
3138  *success = FALSE;
3139 
3140  return SCIP_OKAY;
3141 }
3142 
3143 /*
3144  * Column methods
3145  */
3146 
3147 /** creates an LP column */
3149  SCIP_COL** col, /**< pointer to column data */
3150  BMS_BLKMEM* blkmem, /**< block memory */
3151  SCIP_SET* set, /**< global SCIP settings */
3152  SCIP_STAT* stat, /**< problem statistics */
3153  SCIP_VAR* var, /**< variable, this column represents */
3154  int len, /**< number of nonzeros in the column */
3155  SCIP_ROW** rows, /**< array with rows of column entries */
3156  SCIP_Real* vals, /**< array with coefficients of column entries */
3157  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3158  )
3159 {
3160  int i;
3161 
3162  assert(col != NULL);
3163  assert(blkmem != NULL);
3164  assert(set != NULL);
3165  assert(stat != NULL);
3166  assert(var != NULL);
3167  assert(len >= 0);
3168  assert(len == 0 || (rows != NULL && vals != NULL));
3169 
3170  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3171 
3172  if( len > 0 )
3173  {
3174  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3175  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3176  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3177 
3178  for( i = 0; i < len; ++i )
3179  {
3180  assert(rows[i] != NULL);
3181  assert(!SCIPsetIsZero(set, vals[i]));
3182  (*col)->linkpos[i] = -1;
3183  }
3184  }
3185  else
3186  {
3187  (*col)->rows = NULL;
3188  (*col)->vals = NULL;
3189  (*col)->linkpos = NULL;
3190  }
3191 
3192  (*col)->var = var;
3193  (*col)->obj = SCIPvarGetObj(var);
3194  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3195  (*col)->lb = SCIPvarGetLbLocal(var);
3196  (*col)->ub = SCIPvarGetUbLocal(var);
3197  (*col)->flushedobj = 0.0;
3198  (*col)->flushedlb = 0.0;
3199  (*col)->flushedub = 0.0;
3200  (*col)->index = stat->ncolidx;
3201  SCIPstatIncrement(stat, set, ncolidx);
3202  (*col)->size = len;
3203  (*col)->len = len;
3204  (*col)->nlprows = 0;
3205  (*col)->nunlinked = len;
3206  (*col)->lppos = -1;
3207  (*col)->lpipos = -1;
3208  (*col)->lpdepth = -1;
3209  (*col)->primsol = 0.0;
3210  (*col)->redcost = SCIP_INVALID;
3211  (*col)->farkascoef = SCIP_INVALID;
3212  (*col)->minprimsol = (*col)->ub;
3213  (*col)->maxprimsol = (*col)->lb;
3214  (*col)->sbdown = SCIP_INVALID;
3215  (*col)->sbup = SCIP_INVALID;
3216  (*col)->sbsolval = SCIP_INVALID;
3217  (*col)->sblpobjval = SCIP_INVALID;
3218  (*col)->sbnode = -1;
3219  (*col)->validredcostlp = -1;
3220  (*col)->validfarkaslp = -1;
3221  (*col)->validsblp = -1;
3222  (*col)->sbitlim = -1;
3223  (*col)->nsbcalls = 0;
3224  (*col)->age = 0;
3225  (*col)->obsoletenode = -1;
3226  (*col)->var_probindex = SCIPvarGetProbindex(var);
3227  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3228  (*col)->lprowssorted = TRUE;
3229  (*col)->nonlprowssorted = (len <= 1);
3230  (*col)->objchanged = FALSE;
3231  (*col)->lbchanged = FALSE;
3232  (*col)->ubchanged = FALSE;
3233  (*col)->coefchanged = FALSE;
3234  (*col)->integral = SCIPvarIsIntegral(var);
3235  (*col)->removable = removable;
3236  (*col)->sbdownvalid = FALSE;
3237  (*col)->sbupvalid = FALSE;
3238  (*col)->lazylb = SCIPvarGetLbLazy(var);
3239  (*col)->lazyub = SCIPvarGetUbLazy(var);
3240  (*col)->storedsolvals = NULL;
3241 
3242  return SCIP_OKAY;
3243 }
3244 
3245 /** frees an LP column */
3247  SCIP_COL** col, /**< pointer to LP column */
3248  BMS_BLKMEM* blkmem, /**< block memory */
3249  SCIP_SET* set, /**< global SCIP settings */
3250  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3251  SCIP_LP* lp /**< current LP data */
3252  )
3253 {
3254  assert(blkmem != NULL);
3255  assert(col != NULL);
3256  assert(*col != NULL);
3257  assert((*col)->var != NULL);
3258  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3259  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3260  assert((*col)->lppos == -1);
3261  assert((*col)->lpipos == -1);
3262 
3263  /* remove column indices from corresponding rows */
3264  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3265 
3266  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3267  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3268  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3269  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3270  BMSfreeBlockMemory(blkmem, col);
3271 
3272  return SCIP_OKAY;
3273 }
3274 
3275 /** output column to file stream */
3277  SCIP_COL* col, /**< LP column */
3278  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3279  FILE* file /**< output file (or NULL for standard output) */
3280  )
3281 {
3282  int r;
3283 
3284  assert(col != NULL);
3285  assert(col->var != NULL);
3286 
3287  /* print bounds */
3288  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3289 
3290  /* print coefficients */
3291  if( col->len == 0 )
3292  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3293  for( r = 0; r < col->len; ++r )
3294  {
3295  assert(col->rows[r] != NULL);
3296  assert(col->rows[r]->name != NULL);
3297  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3298  }
3299  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3300 }
3301 
3302 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3303  */
3305  SCIP_COL* col /**< column to be sorted */
3306  )
3307 {
3308  /* sort LP rows */
3309  colSortLP(col);
3310 
3311  /* sort non-LP rows */
3312  colSortNonLP(col);
3313 }
3314 
3315 /** adds a previously non existing coefficient to an LP column */
3317  SCIP_COL* col, /**< LP column */
3318  BMS_BLKMEM* blkmem, /**< block memory */
3319  SCIP_SET* set, /**< global SCIP settings */
3320  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3321  SCIP_LP* lp, /**< current LP data */
3322  SCIP_ROW* row, /**< LP row */
3323  SCIP_Real val /**< value of coefficient */
3324  )
3325 {
3326  assert(lp != NULL);
3327  assert(!lp->diving);
3328 
3329  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3330 
3331  checkLinks(lp);
3332 
3333  return SCIP_OKAY;
3334 }
3335 
3336 /** deletes existing coefficient from column */
3338  SCIP_COL* col, /**< column to be changed */
3339  BMS_BLKMEM* blkmem, /**< block memory */
3340  SCIP_SET* set, /**< global SCIP settings */
3341  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3342  SCIP_LP* lp, /**< current LP data */
3343  SCIP_ROW* row /**< coefficient to be deleted */
3344  )
3345 {
3346  int pos;
3347 
3348  assert(col != NULL);
3349  assert(col->var != NULL);
3350  assert(lp != NULL);
3351  assert(!lp->diving);
3352  assert(row != NULL);
3353 
3354  /* search the position of the row in the column's row vector */
3355  pos = colSearchCoef(col, row);
3356  if( pos == -1 )
3357  {
3358  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3359  return SCIP_INVALIDDATA;
3360  }
3361  assert(0 <= pos && pos < col->len);
3362  assert(col->rows[pos] == row);
3363 
3364  /* if row knows of the column, remove the column from the row's col vector */
3365  if( col->linkpos[pos] >= 0 )
3366  {
3367  assert(row->cols[col->linkpos[pos]] == col);
3368  assert(row->cols_index[col->linkpos[pos]] == col->index);
3369  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3370  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3371  }
3372 
3373  /* delete the row from the column's row vector */
3374  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3375 
3376  checkLinks(lp);
3377 
3378  return SCIP_OKAY;
3379 }
3380 
3381 /** changes or adds a coefficient to an LP column */
3383  SCIP_COL* col, /**< LP column */
3384  BMS_BLKMEM* blkmem, /**< block memory */
3385  SCIP_SET* set, /**< global SCIP settings */
3386  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3387  SCIP_LP* lp, /**< current LP data */
3388  SCIP_ROW* row, /**< LP row */
3389  SCIP_Real val /**< value of coefficient */
3390  )
3391 {
3392  int pos;
3393 
3394  assert(col != NULL);
3395  assert(lp != NULL);
3396  assert(!lp->diving);
3397  assert(row != NULL);
3398 
3399  /* search the position of the row in the column's row vector */
3400  pos = colSearchCoef(col, row);
3401 
3402  /* check, if row already exists in the column's row vector */
3403  if( pos == -1 )
3404  {
3405  /* add previously not existing coefficient */
3406  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3407  }
3408  else
3409  {
3410  /* modify already existing coefficient */
3411  assert(0 <= pos && pos < col->len);
3412  assert(col->rows[pos] == row);
3413 
3414  /* if row knows of the column, change the corresponding coefficient in the row */
3415  if( col->linkpos[pos] >= 0 )
3416  {
3417  assert(row->cols[col->linkpos[pos]] == col);
3418  assert(row->cols_index[col->linkpos[pos]] == col->index);
3419  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3420  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3421  }
3422 
3423  /* change the coefficient in the column */
3424  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3425  }
3426 
3427  checkLinks(lp);
3428 
3429  return SCIP_OKAY;
3430 }
3431 
3432 /** increases value of an existing or non-existing coefficient in an LP column */
3434  SCIP_COL* col, /**< LP column */
3435  BMS_BLKMEM* blkmem, /**< block memory */
3436  SCIP_SET* set, /**< global SCIP settings */
3437  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3438  SCIP_LP* lp, /**< current LP data */
3439  SCIP_ROW* row, /**< LP row */
3440  SCIP_Real incval /**< value to add to the coefficient */
3441  )
3442 {
3443  int pos;
3444 
3445  assert(col != NULL);
3446  assert(lp != NULL);
3447  assert(!lp->diving);
3448  assert(row != NULL);
3449 
3450  if( SCIPsetIsZero(set, incval) )
3451  return SCIP_OKAY;
3452 
3453  /* search the position of the row in the column's row vector */
3454  pos = colSearchCoef(col, row);
3455 
3456  /* check, if row already exists in the column's row vector */
3457  if( pos == -1 )
3458  {
3459  /* add previously not existing coefficient */
3460  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3461  }
3462  else
3463  {
3464  /* modify already existing coefficient */
3465  assert(0 <= pos && pos < col->len);
3466  assert(col->rows[pos] == row);
3467 
3468  /* if row knows of the column, change the corresponding coefficient in the row */
3469  if( col->linkpos[pos] >= 0 )
3470  {
3471  assert(row->cols[col->linkpos[pos]] == col);
3472  assert(row->cols_index[col->linkpos[pos]] == col->index);
3473  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3474  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3475  }
3476 
3477  /* change the coefficient in the column */
3478  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3479  }
3480 
3481  checkLinks(lp);
3482 
3483  return SCIP_OKAY;
3484 }
3485 
3486 /** insert column in the chgcols list (if not already there) */
3487 static
3489  SCIP_COL* col, /**< LP column to change */
3490  SCIP_SET* set, /**< global SCIP settings */
3491  SCIP_LP* lp /**< current LP data */
3492  )
3493 {
3494  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3495  {
3496  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3497  lp->chgcols[lp->nchgcols] = col;
3498  lp->nchgcols++;
3499  }
3500 
3501  /* mark the current LP unflushed */
3502  lp->flushed = FALSE;
3503 
3504  return SCIP_OKAY;
3505 }
3506 
3507 /** Is the new value reliable or may we have cancellation?
3508  *
3509  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3510  * cancellations which can occur during increasing the oldvalue to the newvalue
3511  */
3512 static
3514  SCIP_SET* set, /**< global SCIP settings */
3515  SCIP_Real newvalue, /**< new value */
3516  SCIP_Real oldvalue /**< old reliable value */
3517  )
3518 {
3519  SCIP_Real quotient;
3520 
3521  assert(set != NULL);
3522  assert(oldvalue < SCIP_INVALID);
3523 
3524  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3525 
3526  return SCIPsetIsZero(set, quotient);
3527 }
3528 
3529 /** update norms of objective function vector */
3530 static
3532  SCIP_LP* lp, /**< current LP data */
3533  SCIP_SET* set, /**< global SCIP settings */
3534  SCIP_Real oldobj, /**< old objective value of variable */
3535  SCIP_Real newobj /**< new objective value of variable */
3536  )
3537 {
3538  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3539  {
3540  if( !lp->objsqrnormunreliable )
3541  {
3542  SCIP_Real oldvalue;
3543 
3544  oldvalue = lp->objsqrnorm;
3545  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3546 
3547  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3548  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3549  lp->objsqrnormunreliable = TRUE;
3550  else
3551  {
3552  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3553 
3554  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3555  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3556 
3557  assert(lp->objsqrnorm >= 0.0);
3558  }
3559  }
3560 
3561  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3562  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3563  }
3564 }
3565 
3566 /** changes objective value of column */
3568  SCIP_COL* col, /**< LP column to change */
3569  SCIP_SET* set, /**< global SCIP settings */
3570  SCIP_LP* lp, /**< current LP data */
3571  SCIP_Real newobj /**< new objective value */
3572  )
3573 {
3574  assert(col != NULL);
3575  assert(col->var != NULL);
3576  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3577  assert(SCIPvarGetCol(col->var) == col);
3578  assert(lp != NULL);
3579 
3580  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3581 
3582  /* only add actual changes */
3583  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3584  {
3585  /* only variables with a real position in the LPI can be inserted */
3586  if( col->lpipos >= 0 )
3587  {
3588  /* insert column in the chgcols list (if not already there) */
3589  SCIP_CALL( insertColChgcols(col, set, lp) );
3590 
3591  /* mark objective value change in the column */
3592  col->objchanged = TRUE;
3593 
3594  assert(lp->nchgcols > 0);
3595  }
3596  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3597  * LP and the LP has to be flushed
3598  */
3599  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3600  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3601  {
3602  /* mark the LP unflushed */
3603  lp->flushed = FALSE;
3604  }
3605  }
3606 
3607  /* store new objective function value */
3608  col->obj = newobj;
3609 
3610  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3611  if( !lp->divingobjchg )
3612  {
3613  SCIP_Real oldobj = col->unchangedobj;
3614 
3615  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3616  col->unchangedobj = newobj;
3617 
3618  /* update the objective function vector norms */
3619  lpUpdateObjNorms(lp, set, oldobj, newobj);
3620  }
3621 
3622  return SCIP_OKAY;
3623 }
3624 
3625 /** changes lower bound of column */
3627  SCIP_COL* col, /**< LP column to change */
3628  SCIP_SET* set, /**< global SCIP settings */
3629  SCIP_LP* lp, /**< current LP data */
3630  SCIP_Real newlb /**< new lower bound value */
3631  )
3632 {
3633  assert(col != NULL);
3634  assert(col->var != NULL);
3635  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3636  assert(SCIPvarGetCol(col->var) == col);
3637  assert(lp != NULL);
3638 
3639  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3640 
3641  /* only add actual changes */
3642  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3643  {
3644  /* only variables with a real position in the LPI can be inserted */
3645  if( col->lpipos >= 0 )
3646  {
3647  /* insert column in the chgcols list (if not already there) */
3648  SCIP_CALL( insertColChgcols(col, set, lp) );
3649 
3650  /* mark bound change in the column */
3651  col->lbchanged = TRUE;
3652 
3653  assert(lp->nchgcols > 0);
3654  }
3655  /* 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
3656  * flushed
3657  */
3658  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3659  {
3660  /* mark the LP unflushed */
3661  lp->flushed = FALSE;
3662  }
3663  }
3664 
3665  col->lb = newlb;
3666 
3667  return SCIP_OKAY;
3668 }
3669 
3670 /** changes upper bound of column */
3672  SCIP_COL* col, /**< LP column to change */
3673  SCIP_SET* set, /**< global SCIP settings */
3674  SCIP_LP* lp, /**< current LP data */
3675  SCIP_Real newub /**< new upper bound value */
3676  )
3677 {
3678  assert(col != NULL);
3679  assert(col->var != NULL);
3680  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3681  assert(SCIPvarGetCol(col->var) == col);
3682  assert(lp != NULL);
3683 
3684  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3685 
3686  /* only add actual changes */
3687  if( !SCIPsetIsEQ(set, col->ub, newub) )
3688  {
3689  /* only variables with a real position in the LPI can be inserted */
3690  if( col->lpipos >= 0 )
3691  {
3692  /* insert column in the chgcols list (if not already there) */
3693  SCIP_CALL( insertColChgcols(col, set, lp) );
3694 
3695  /* mark bound change in the column */
3696  col->ubchanged = TRUE;
3697 
3698  assert(lp->nchgcols > 0);
3699  }
3700  /* 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
3701  * flushed
3702  */
3703  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3704  {
3705  /* mark the LP unflushed */
3706  lp->flushed = FALSE;
3707  }
3708  }
3709 
3710  col->ub = newub;
3711 
3712  return SCIP_OKAY;
3713 }
3714 
3715 /** calculates the reduced costs of a column using the given dual solution vector */
3717  SCIP_COL* col, /**< LP column */
3718  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3719  )
3720 {
3721  SCIP_ROW* row;
3722  SCIP_Real redcost;
3723  int i;
3724 
3725  assert(col != NULL);
3726  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3727  assert(SCIPvarGetCol(col->var) == col);
3728  assert(dualsol != NULL);
3729 
3730  redcost = col->obj;
3731  for( i = 0; i < col->nlprows; ++i )
3732  {
3733  row = col->rows[i];
3734  assert(row != NULL);
3735  assert(row->lppos >= 0);
3736  redcost -= col->vals[i] * dualsol[row->lppos];
3737  }
3738 
3739  if( col->nunlinked > 0 )
3740  {
3741  for( i = col->nlprows; i < col->len; ++i )
3742  {
3743  row = col->rows[i];
3744  assert(row != NULL);
3745  assert(row->lppos == -1 || col->linkpos[i] == -1);
3746  if( row->lppos >= 0 )
3747  redcost -= col->vals[i] * dualsol[row->lppos];
3748  }
3749  }
3750 #ifndef NDEBUG
3751  else
3752  {
3753  for( i = col->nlprows; i < col->len; ++i )
3754  {
3755  row = col->rows[i];
3756  assert(row != NULL);
3757  assert(row->lppos == -1);
3758  assert(col->linkpos[i] >= 0);
3759  }
3760  }
3761 #endif
3762 
3763  return redcost;
3764 }
3765 
3766 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3767 static
3769  SCIP_COL* col /**< LP column */
3770  )
3771 {
3772  SCIP_ROW* row;
3773  SCIP_Real redcost;
3774  int i;
3775 
3776  assert(col != NULL);
3777  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3778  assert(SCIPvarGetCol(col->var) == col);
3779 
3780  redcost = col->obj;
3781  for( i = 0; i < col->nlprows; ++i )
3782  {
3783  row = col->rows[i];
3784  assert(row != NULL);
3785  assert(row->dualsol < SCIP_INVALID);
3786  assert(row->lppos >= 0);
3787  assert(col->linkpos[i] >= 0);
3788  redcost -= col->vals[i] * row->dualsol;
3789  }
3790 
3791  if( col->nunlinked > 0 )
3792  {
3793  for( i = col->nlprows; i < col->len; ++i )
3794  {
3795  row = col->rows[i];
3796  assert(row != NULL);
3797  assert(row->lppos >= 0 || row->dualsol == 0.0);
3798  assert(row->lppos == -1 || col->linkpos[i] == -1);
3799  if( row->lppos >= 0 )
3800  redcost -= col->vals[i] * row->dualsol;
3801  }
3802  }
3803 #ifndef NDEBUG
3804  else
3805  {
3806  for( i = col->nlprows; i < col->len; ++i )
3807  {
3808  row = col->rows[i];
3809  assert(row != NULL);
3810  assert(row->dualsol == 0.0);
3811  assert(row->lppos == -1);
3812  assert(col->linkpos[i] >= 0);
3813  }
3814  }
3815 #endif
3816 
3817  return redcost;
3818 }
3819 
3820 /** gets the reduced costs of a column in last LP or after recalculation */
3822  SCIP_COL* col, /**< LP column */
3823  SCIP_STAT* stat, /**< problem statistics */
3824  SCIP_LP* lp /**< current LP data */
3825  )
3826 {
3827  assert(col != NULL);
3828  assert(stat != NULL);
3829  assert(lp != NULL);
3830  assert(col->validredcostlp <= stat->lpcount);
3831  assert(lp->validsollp == stat->lpcount);
3832 
3833  if( col->validredcostlp < stat->lpcount )
3834  {
3835  col->redcost = colCalcInternalRedcost(col);
3836  col->validredcostlp = stat->lpcount;
3837  }
3838  assert(col->validredcostlp == stat->lpcount);
3839  assert(col->redcost < SCIP_INVALID);
3840 
3841  return col->redcost;
3842 }
3843 
3844 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3846  SCIP_COL* col, /**< LP column */
3847  SCIP_SET* set, /**< global SCIP settings */
3848  SCIP_STAT* stat, /**< problem statistics */
3849  SCIP_LP* lp /**< current LP data */
3850  )
3851 {
3852  assert(col != NULL);
3853  assert(set != NULL);
3854  assert(stat != NULL);
3855  assert(lp != NULL);
3856  assert(lp->validsollp == stat->lpcount);
3857 
3858  /* A column's reduced cost is defined as
3859  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3860  * The activity is equal to the activity of the corresponding row in the dual LP.
3861  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3862  * The sides of the dual row depend on the bounds of the column:
3863  * - lb == ub : dual row is a free row with infinite sides
3864  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3865  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3866  * - lb < ub <= 0: obj <= activity => redcost <= 0
3867  */
3868  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3869  {
3870  /* dual row is free */
3871  return SCIPsetInfinity(set);
3872  }
3873  else
3874  {
3875  SCIP_Real redcost;
3876 
3877  /* calculate reduced costs */
3878  redcost = SCIPcolGetRedcost(col, stat, lp);
3879 
3880  if( !SCIPsetIsNegative(set, col->lb) )
3881  {
3882  /* dual row is activity <= obj <=> redcost >= 0 */
3883  return redcost;
3884  }
3885  else if( SCIPsetIsPositive(set, col->ub) )
3886  {
3887  /* dual row is activity == obj <=> redcost == 0 */
3888  return -REALABS(redcost);
3889  }
3890  else
3891  {
3892  /* dual row is activity >= obj <=> redcost <= 0 */
3893  return -redcost;
3894  }
3895  }
3896 }
3897 
3898 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
3900  SCIP_COL* col, /**< LP column */
3901  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
3902  )
3903 {
3904  SCIP_ROW* row;
3905  SCIP_Real farkas;
3906  int i;
3907 
3908  assert(col != NULL);
3909  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3910  assert(SCIPvarGetCol(col->var) == col);
3911  assert(dualfarkas != NULL);
3912 
3913  farkas = 0.0;
3914  for( i = 0; i < col->nlprows; ++i )
3915  {
3916  row = col->rows[i];
3917  assert(row != NULL);
3918  assert(row->lppos >= 0);
3919  farkas += col->vals[i] * dualfarkas[row->lppos];
3920  }
3921 
3922  if( col->nunlinked > 0 )
3923  {
3924  for( i = col->nlprows; i < col->len; ++i )
3925  {
3926  row = col->rows[i];
3927  assert(row != NULL);
3928  assert(row->lppos == -1 || col->linkpos[i] == -1);
3929  if( row->lppos >= 0 )
3930  farkas += col->vals[i] * dualfarkas[row->lppos];
3931  }
3932  }
3933 #ifndef NDEBUG
3934  else
3935  {
3936  for( i = col->nlprows; i < col->len; ++i )
3937  {
3938  row = col->rows[i];
3939  assert(row != NULL);
3940  assert(row->lppos == -1);
3941  assert(col->linkpos[i] >= 0);
3942  }
3943  }
3944 #endif
3945 
3946  return farkas;
3947 }
3948 
3949 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
3950 static
3952  SCIP_COL* col /**< LP column */
3953  )
3954 {
3955  SCIP_ROW* row;
3956  SCIP_Real farkas;
3957  int i;
3958 
3959  assert(col != NULL);
3960  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3961  assert(SCIPvarGetCol(col->var) == col);
3962 
3963  farkas = 0.0;
3964  for( i = 0; i < col->nlprows; ++i )
3965  {
3966  row = col->rows[i];
3967  assert(row != NULL);
3968  assert(row->dualfarkas < SCIP_INVALID);
3969  assert(row->lppos >= 0);
3970  assert(col->linkpos[i] >= 0);
3971  farkas += col->vals[i] * row->dualfarkas;
3972  }
3973 
3974  if( col->nunlinked > 0 )
3975  {
3976  for( i = col->nlprows; i < col->len; ++i )
3977  {
3978  row = col->rows[i];
3979  assert(row != NULL);
3980  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
3981  assert(row->lppos == -1 || col->linkpos[i] == -1);
3982  if( row->lppos >= 0 )
3983  farkas += col->vals[i] * row->dualfarkas;
3984  }
3985  }
3986 #ifndef NDEBUG
3987  else
3988  {
3989  for( i = col->nlprows; i < col->len; ++i )
3990  {
3991  row = col->rows[i];
3992  assert(row != NULL);
3993  assert(row->dualfarkas == 0.0);
3994  assert(row->lppos == -1);
3995  assert(col->linkpos[i] >= 0);
3996  }
3997  }
3998 #endif
3999 
4000  return farkas;
4001 }
4002 
4003 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4005  SCIP_COL* col, /**< LP column */
4006  SCIP_STAT* stat, /**< problem statistics */
4007  SCIP_LP* lp /**< current LP data */
4008  )
4009 {
4010  assert(col != NULL);
4011  assert(stat != NULL);
4012  assert(lp != NULL);
4013  assert(col->validfarkaslp <= stat->lpcount);
4014  assert(lp->validfarkaslp == stat->lpcount);
4015 
4016  if( col->validfarkaslp < stat->lpcount )
4017  {
4019  col->validfarkaslp = stat->lpcount;
4020  }
4021  assert(col->validfarkaslp == stat->lpcount);
4022  assert(col->farkascoef < SCIP_INVALID);
4023 
4024  return col->farkascoef;
4025 }
4026 
4027 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4028  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4029  */
4031  SCIP_COL* col, /**< LP column */
4032  SCIP_STAT* stat, /**< problem statistics */
4033  SCIP_LP* lp /**< current LP data */
4034  )
4035 {
4036  SCIP_Real farkascoef;
4037 
4038  assert(col != NULL);
4039 
4040  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4041 
4042  if( farkascoef > 0.0 )
4043  return col->ub * farkascoef;
4044  else
4045  return col->lb * farkascoef;
4046 }
4047 
4048 /** start strong branching - call before any strong branching */
4050  SCIP_LP* lp /**< LP data */
4051  )
4052 {
4053  assert(lp != NULL);
4054  assert(!lp->strongbranching);
4055 
4056  lp->strongbranching = TRUE;
4057  SCIPdebugMessage("starting strong branching ...\n");
4059 
4060  return SCIP_OKAY;
4061 }
4062 
4063 /** end strong branching - call after any strong branching */
4065  SCIP_LP* lp /**< LP data */
4066  )
4067 {
4068  assert(lp != NULL);
4069  assert(lp->strongbranching);
4070 
4071  lp->strongbranching = FALSE;
4072  SCIPdebugMessage("ending strong branching ...\n");
4074 
4075  return SCIP_OKAY;
4076 }
4077 
4078 /** sets strong branching information for a column variable */
4080  SCIP_COL* col, /**< LP column */
4081  SCIP_SET* set, /**< global SCIP settings */
4082  SCIP_STAT* stat, /**< dynamic problem statistics */
4083  SCIP_LP* lp, /**< LP data */
4084  SCIP_Real lpobjval, /**< objective value of the current LP */
4085  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4086  SCIP_Real sbdown, /**< dual bound after branching column down */
4087  SCIP_Real sbup, /**< dual bound after branching column up */
4088  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4089  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4090  SCIP_Longint iter, /**< total number of strong branching iterations */
4091  int itlim /**< iteration limit applied to the strong branching call */
4092  )
4093 {
4094  assert(col != NULL);
4095  assert(col->var != NULL);
4096  assert(SCIPcolIsIntegral(col));
4097  assert(SCIPvarIsIntegral(col->var));
4098  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4099  assert(SCIPvarGetCol(col->var) == col);
4100  assert(col->lpipos >= 0);
4101  assert(col->lppos >= 0);
4102  assert(set != NULL);
4103  assert(stat != NULL);
4104  assert(lp != NULL);
4105  assert(lp->strongbranchprobing);
4106  assert(col->lppos < lp->ncols);
4107  assert(lp->cols[col->lppos] == col);
4108  assert(itlim >= 1);
4109 
4110  col->sblpobjval = lpobjval;
4111  col->sbsolval = primsol;
4112  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4113  col->sbnode = stat->nnodes;
4114 
4115  col->sbitlim = itlim;
4116  col->nsbcalls++;
4117 
4118  col->sbdown = MIN(sbdown, lp->cutoffbound);
4119  col->sbup = MIN(sbup, lp->cutoffbound);
4120  col->sbdownvalid = sbdownvalid;
4121  col->sbupvalid = sbupvalid;
4122 
4123  SCIPstatIncrement(stat, set, nstrongbranchs);
4124  SCIPstatAdd(stat, set, nsblpiterations, iter);
4125  if( stat->nnodes == 1 )
4126  {
4127  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4128  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4129  }
4130 }
4131 
4132 /** invalidates strong branching information for a column variable */
4134  SCIP_COL* col, /**< LP column */
4135  SCIP_SET* set, /**< global SCIP settings */
4136  SCIP_STAT* stat, /**< dynamic problem statistics */
4137  SCIP_LP* lp /**< LP data */
4138  )
4139 {
4140  assert(col != NULL);
4141  assert(col->var != NULL);
4142  assert(SCIPcolIsIntegral(col));
4143  assert(SCIPvarIsIntegral(col->var));
4144  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4145  assert(SCIPvarGetCol(col->var) == col);
4146  assert(col->lpipos >= 0);
4147  assert(col->lppos >= 0);
4148  assert(set != NULL);
4149  assert(stat != NULL);
4150  assert(lp != NULL);
4151  assert(lp->strongbranchprobing);
4152  assert(col->lppos < lp->ncols);
4153  assert(lp->cols[col->lppos] == col);
4154 
4155  col->sbdown = SCIP_INVALID;
4156  col->sbup = SCIP_INVALID;
4157  col->sbdownvalid = FALSE;
4158  col->sbupvalid = FALSE;
4159  col->validsblp = -1;
4160  col->sbsolval = SCIP_INVALID;
4161  col->sblpobjval = SCIP_INVALID;
4162  col->sbnode = -1;
4163  col->sbitlim = -1;
4164 }
4165 
4166 
4167 /** gets strong branching information on a column variable */
4169  SCIP_COL* col, /**< LP column */
4170  SCIP_Bool integral, /**< should integral strong branching be performed? */
4171  SCIP_SET* set, /**< global SCIP settings */
4172  SCIP_STAT* stat, /**< dynamic problem statistics */
4173  SCIP_PROB* prob, /**< problem data */
4174  SCIP_LP* lp, /**< LP data */
4175  int itlim, /**< iteration limit for strong branchings */
4176  SCIP_Real* down, /**< stores dual bound after branching column down */
4177  SCIP_Real* up, /**< stores dual bound after branching column up */
4178  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4179  * otherwise, it can only be used as an estimate value */
4180  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4181  * otherwise, it can only be used as an estimate value */
4182  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4183  )
4184 {
4185  assert(col != NULL);
4186  assert(col->var != NULL);
4187  assert(SCIPcolIsIntegral(col));
4188  assert(SCIPvarIsIntegral(col->var));
4189  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4190  assert(SCIPvarGetCol(col->var) == col);
4191  assert(col->primsol < SCIP_INVALID);
4192  assert(col->lpipos >= 0);
4193  assert(col->lppos >= 0);
4194  assert(set != NULL);
4195  assert(stat != NULL);
4196  assert(lp != NULL);
4197  assert(lp->flushed);
4198  assert(lp->solved);
4199  assert(lp->strongbranching);
4200  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4201  assert(lp->validsollp == stat->lpcount);
4202  assert(col->lppos < lp->ncols);
4203  assert(lp->cols[col->lppos] == col);
4204  assert(itlim >= 1);
4205  /* assert(down != NULL);
4206  * assert(up != NULL); temporary hack for cloud branching
4207  */
4208  assert(lperror != NULL);
4209 
4210  *lperror = FALSE;
4211 
4212  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4213  {
4214  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4215  col->sbsolval = col->primsol;
4216  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4217  col->sbnode = stat->nnodes;
4218  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4219 
4220  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4221  if( lp->looseobjvalinf > 0 )
4222  {
4223  col->sbdown = -SCIPsetInfinity(set);
4224  col->sbup = -SCIPsetInfinity(set);
4225  col->sbdownvalid = FALSE;
4226  col->sbupvalid = FALSE;
4227  }
4228  else
4229  {
4230  SCIP_RETCODE retcode;
4231  SCIP_Real sbdown;
4232  SCIP_Real sbup;
4233  SCIP_Bool sbdownvalid;
4234  SCIP_Bool sbupvalid;
4235  int iter;
4236 
4237  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4238  SCIPvarGetName(col->var), col->primsol, itlim);
4239 
4240  /* start timing */
4241  SCIPclockStart(stat->strongbranchtime, set);
4242 
4243  /* call LPI strong branching */
4244  col->sbitlim = itlim;
4245  col->nsbcalls++;
4246 
4247  sbdown = lp->lpobjval;
4248  sbup = lp->lpobjval;
4249 
4250  if( integral )
4251  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4252  else
4253  {
4254  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4255  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4256  }
4257 
4258 
4259  /* check return code for errors */
4260  if( retcode == SCIP_LPERROR )
4261  {
4262  *lperror = TRUE;
4263  col->sbdown = SCIP_INVALID;
4264  col->sbup = SCIP_INVALID;
4265  col->sbdownvalid = FALSE;
4266  col->sbupvalid = FALSE;
4267  col->validsblp = -1;
4268  col->sbsolval = SCIP_INVALID;
4269  col->sblpobjval = SCIP_INVALID;
4270  col->sbnode = -1;
4271  }
4272  else
4273  {
4274  SCIP_Real looseobjval;
4275 
4276  *lperror = FALSE;
4277  SCIP_CALL( retcode );
4278 
4279  looseobjval = getFiniteLooseObjval(lp, set, prob);
4280  col->sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4281  col->sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4282 
4283  col->sbdownvalid = sbdownvalid;
4284  col->sbupvalid = sbupvalid;
4285 
4286  /* update strong branching statistics */
4287  if( iter == -1 )
4288  {
4289  /* calculate average iteration number */
4290  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4291  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4292  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4293  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4294  : 0;
4295  if( iter/2 >= itlim )
4296  iter = 2*itlim;
4297  }
4298  SCIPstatIncrement(stat, set, nstrongbranchs);
4299  SCIPstatAdd(stat, set, nsblpiterations, iter);
4300  if( stat->nnodes == 1 )
4301  {
4302  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4303  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4304  }
4305  }
4306 
4307  /* stop timing */
4308  SCIPclockStop(stat->strongbranchtime, set);
4309  }
4310  }
4311  assert(*lperror || col->sbdown < SCIP_INVALID);
4312  assert(*lperror || col->sbup < SCIP_INVALID);
4313 
4314  if( down != NULL)
4315  *down = col->sbdown;
4316  if( up != NULL )
4317  *up = col->sbup;
4318  if( downvalid != NULL )
4319  *downvalid = col->sbdownvalid;
4320  if( upvalid != NULL )
4321  *upvalid = col->sbupvalid;
4322 
4323  return SCIP_OKAY;
4324 }
4325 
4326 /** gets strong branching information on column variables */
4328  SCIP_COL** cols, /**< LP columns */
4329  int ncols, /**< number of columns */
4330  SCIP_Bool integral, /**< should integral strong branching be performed? */
4331  SCIP_SET* set, /**< global SCIP settings */
4332  SCIP_STAT* stat, /**< dynamic problem statistics */
4333  SCIP_PROB* prob, /**< problem data */
4334  SCIP_LP* lp, /**< LP data */
4335  int itlim, /**< iteration limit for strong branchings */
4336  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4337  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4338  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4339  * otherwise, they can only be used as an estimate value */
4340  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4341  * otherwise, they can only be used as an estimate value */
4342  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4343  )
4344 {
4345  SCIP_RETCODE retcode;
4346  SCIP_Real* sbdown;
4347  SCIP_Real* sbup;
4348  SCIP_Bool* sbdownvalid;
4349  SCIP_Bool* sbupvalid;
4350  SCIP_Real* primsols;
4351  SCIP_COL** subcols;
4352  int* lpipos;
4353  int* subidx;
4354  int nsubcols;
4355  int iter;
4356  int j;
4357 
4358  assert(cols != NULL);
4359  assert(set != NULL);
4360  assert(stat != NULL);
4361  assert(lp != NULL);
4362  assert(lp->flushed);
4363  assert(lp->solved);
4364  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4365  assert(lp->validsollp == stat->lpcount);
4366  assert(itlim >= 1);
4367  assert(down != NULL);
4368  assert(up != NULL);
4369  assert(lperror != NULL);
4370 
4371  *lperror = FALSE;
4372 
4373  if ( ncols <= 0 )
4374  return SCIP_OKAY;
4375 
4376  /* start timing */
4377  SCIPclockStart(stat->strongbranchtime, set);
4378 
4379  /* initialize storage */
4380  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4381  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4382  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4383  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4384  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4385  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4386  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4387  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4388 
4389  nsubcols = 0;
4390  for( j = 0; j < ncols; ++j )
4391  {
4392  SCIP_COL* col;
4393  col = cols[j];
4394 
4395  assert(col->lppos < lp->ncols);
4396  assert(lp->cols[col->lppos] == col);
4397  assert(SCIPcolIsIntegral(col));
4398  assert(SCIPvarIsIntegral(col->var));
4399  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4400  assert(SCIPvarGetCol(col->var) == col);
4401  assert(col->primsol < SCIP_INVALID);
4402  assert(col->lpipos >= 0);
4403  assert(col->lppos >= 0);
4404 
4405  if( col->validsblp != stat->lpcount - stat->nsbdivinglps || itlim > col->sbitlim )
4406  {
4407  col->validsblp = stat->lpcount - stat->nsbdivinglps;
4408  col->sbsolval = col->primsol;
4409  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4410  col->sbnode = stat->nnodes;
4411  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4412 
4413  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4414  if( lp->looseobjvalinf > 0 )
4415  {
4416  /* directly set up column and result vectors*/
4417  col->sbdown = -SCIPsetInfinity(set);
4418  col->sbup = -SCIPsetInfinity(set);
4419  col->sbdownvalid = FALSE;
4420  col->sbupvalid = FALSE;
4421  down[j] = col->sbdown;
4422  up[j] = col->sbup;
4423  if( downvalid != NULL )
4424  downvalid[j] = col->sbdownvalid;
4425  if( upvalid != NULL )
4426  upvalid[j] = col->sbupvalid;
4427  }
4428  else
4429  {
4430  col->sbitlim = itlim;
4431  col->nsbcalls++;
4432 
4433  lpipos[nsubcols] = col->lpipos;
4434  primsols[nsubcols] = col->primsol;
4435  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4436  subidx[nsubcols] = j;
4437  subcols[nsubcols++] = col;
4438  }
4439  }
4440  else
4441  {
4442  /* directly set up resulting values (use stored values) */
4443  down[j] = col->sbdown;
4444  up[j] = col->sbup;
4445  if( downvalid != NULL )
4446  downvalid[j] = col->sbdownvalid;
4447  if( upvalid != NULL )
4448  upvalid[j] = col->sbupvalid;
4449  }
4450  }
4451 
4452  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4453 
4454  /* call LPI strong branching */
4455  if ( integral )
4456  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4457  else
4458  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4459 
4460  /* check return code for errors */
4461  if( retcode == SCIP_LPERROR )
4462  {
4463  *lperror = TRUE;
4464 
4465  for( j = 0; j < nsubcols; ++j )
4466  {
4467  SCIP_COL* col;
4468  int idx;
4469 
4470  col = subcols[j];
4471  idx = subidx[j];
4472 
4473  col->sbdown = SCIP_INVALID;
4474  col->sbup = SCIP_INVALID;
4475  col->sbdownvalid = FALSE;
4476  col->sbupvalid = FALSE;
4477  col->validsblp = -1;
4478  col->sbsolval = SCIP_INVALID;
4479  col->sblpobjval = SCIP_INVALID;
4480  col->sbnode = -1;
4481 
4482  down[idx] = col->sbdown;
4483  up[idx] = col->sbup;
4484  if( downvalid != NULL )
4485  downvalid[idx] = col->sbdownvalid;
4486  if( upvalid != NULL )
4487  upvalid[idx] = col->sbupvalid;
4488  }
4489  }
4490  else
4491  {
4492  SCIP_Real looseobjval;
4493 
4494  *lperror = FALSE;
4495  SCIP_CALL( retcode );
4496 
4497  looseobjval = getFiniteLooseObjval(lp, set, prob);
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  assert( col->sbdown < SCIP_INVALID);
4508  assert( col->sbup < SCIP_INVALID);
4509 
4510  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4511  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4512  col->sbdownvalid = sbdownvalid[j];
4513  col->sbupvalid = sbupvalid[j];
4514 
4515  down[idx] = col->sbdown;
4516  up[idx] = col->sbup;
4517  if( downvalid != NULL )
4518  downvalid[idx] = col->sbdownvalid;
4519  if( upvalid != NULL )
4520  upvalid[idx] = col->sbupvalid;
4521  }
4522 
4523  /* update strong branching statistics */
4524  if( iter == -1 )
4525  {
4526  /* calculate average iteration number */
4527  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4528  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4529  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4530  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4531  : 0;
4532  if( iter/2 >= itlim )
4533  iter = 2*itlim;
4534  }
4535  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4536  SCIPstatAdd(stat, set, nsblpiterations, iter);
4537  if( stat->nnodes == 1 )
4538  {
4539  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4540  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4541  }
4542  }
4543 
4544  SCIPsetFreeBufferArray(set, &sbupvalid);
4545  SCIPsetFreeBufferArray(set, &sbdownvalid);
4546  SCIPsetFreeBufferArray(set, &sbup);
4547  SCIPsetFreeBufferArray(set, &sbdown);
4548  SCIPsetFreeBufferArray(set, &primsols);
4549  SCIPsetFreeBufferArray(set, &lpipos);
4550  SCIPsetFreeBufferArray(set, &subidx);
4551  SCIPsetFreeBufferArray(set, &subcols);
4552 
4553  /* stop timing */
4554  SCIPclockStop(stat->strongbranchtime, set);
4555 
4556  return SCIP_OKAY;
4557 }
4558 
4559 /** gets last strong branching information available for a column variable;
4560  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4561  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4562  */
4564  SCIP_COL* col, /**< LP column */
4565  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4566  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4567  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4568  * otherwise, it can only be used as an estimate value */
4569  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4570  * otherwise, it can only be used as an estimate value */
4571  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4572  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4573  )
4574 {
4575  assert(col != NULL);
4576 
4577  if( down != NULL )
4578  *down = col->sbdown;
4579  if( up != NULL )
4580  *up = col->sbup;
4581  if( downvalid != NULL )
4582  *downvalid = col->sbdownvalid;
4583  if( upvalid != NULL )
4584  *upvalid = col->sbupvalid;
4585  if( solval != NULL )
4586  *solval = col->sbsolval;
4587  if( lpobjval != NULL )
4588  *lpobjval = col->sblpobjval;
4589 }
4590 
4591 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4592  * the LP where the strong branching on this column was applied;
4593  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4594  */
4596  SCIP_COL* col, /**< LP column */
4597  SCIP_STAT* stat /**< dynamic problem statistics */
4598  )
4599 {
4600  assert(col != NULL);
4601  assert(stat != NULL);
4602 
4603  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->lpcount - stat->nsbdivinglps - col->validsblp);
4604 }
4605 
4606 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4608  SCIP_COL* col, /**< LP column */
4609  SCIP_STAT* stat /**< problem statistics */
4610  )
4611 {
4612  assert(col != NULL);
4613  assert(stat != NULL);
4614  assert(stat->nnodes > 0);
4615 
4616  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4617  col->obsoletenode = stat->nnodes;
4618 }
4619 
4620 
4621 /*
4622  * Row methods
4623  */
4624 
4625 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4626 static
4628  SCIP_ROW* row, /**< LP row */
4629  SCIP_SET* set /**< global SCIP settings */
4630  )
4631 {
4632  int i;
4633 
4634  assert(row != NULL);
4635  assert(set != NULL);
4636 
4637  row->sqrnorm = 0.0;
4638  row->sumnorm = 0.0;
4639  row->objprod = 0.0;
4640  row->maxval = 0.0;
4641  row->nummaxval = 1;
4642  row->minval = SCIPsetInfinity(set);
4643  row->numminval = 1;
4644  row->minidx = INT_MAX;
4645  row->maxidx = INT_MIN;
4646  row->validminmaxidx = TRUE;
4647  row->lpcolssorted = TRUE;
4648  row->nonlpcolssorted = TRUE;
4649 
4650  /* check, if row is sorted
4651  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4652  */
4653  for( i = 0; i < row->nlpcols; ++i )
4654  {
4655  assert(row->cols[i] != NULL);
4656  assert(!SCIPsetIsZero(set, row->vals[i]));
4657  assert(row->cols[i]->lppos >= 0);
4658  assert(row->linkpos[i] >= 0);
4659  assert(row->cols[i]->index == row->cols_index[i]);
4660 
4661  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4662  if( i > 0 )
4663  {
4664  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4665  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4666  }
4667  }
4668  for( i = row->nlpcols; i < row->len; ++i )
4669  {
4670  assert(row->cols[i] != NULL);
4671  assert(!SCIPsetIsZero(set, row->vals[i]));
4672  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4673  assert(row->cols[i]->index == row->cols_index[i]);
4674 
4675  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4676  if( i > row->nlpcols )
4677  {
4678  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4679  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4680  }
4681  }
4682 }
4683 
4684 /** calculates min/maxval and min/maxidx from scratch */
4685 static
4687  SCIP_ROW* row, /**< LP row */
4688  SCIP_SET* set /**< global SCIP settings */
4689  )
4690 {
4691  SCIP_COL* col;
4692  SCIP_Real absval;
4693  int i;
4694 
4695  assert(row != NULL);
4696  assert(set != NULL);
4697 
4698  row->maxval = 0.0;
4699  row->nummaxval = 1;
4700  row->minval = SCIPsetInfinity(set);
4701  row->numminval = 1;
4702  row->minidx = INT_MAX;
4703  row->maxidx = INT_MIN;
4704  row->validminmaxidx = TRUE;
4705 
4706  /* calculate maxval, minval, minidx, and maxidx */
4707  for( i = 0; i < row->len; ++i )
4708  {
4709  col = row->cols[i];
4710  assert(col != NULL);
4711  assert(!SCIPsetIsZero(set, row->vals[i]));
4712 
4713  absval = REALABS(row->vals[i]);
4714  assert(!SCIPsetIsZero(set, absval));
4715 
4716  /* update min/maxidx */
4717  row->minidx = MIN(row->minidx, col->index);
4718  row->maxidx = MAX(row->maxidx, col->index);
4719 
4720  /* update maximal and minimal non-zero value */
4721  if( row->nummaxval > 0 )
4722  {
4723  if( SCIPsetIsGT(set, absval, row->maxval) )
4724  {
4725  row->maxval = absval;
4726  row->nummaxval = 1;
4727  }
4728  else if( SCIPsetIsGE(set, absval, row->maxval) )
4729  row->nummaxval++;
4730  }
4731  if( row->numminval > 0 )
4732  {
4733  if( SCIPsetIsLT(set, absval, row->minval) )
4734  {
4735  row->minval = absval;
4736  row->numminval = 1;
4737  }
4738  else if( SCIPsetIsLE(set, absval, row->minval) )
4739  row->numminval++;
4740  }
4741  }
4742 }
4743 
4744 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4745 static
4747  SCIP_Real val, /**< value that should be scaled to an integral value */
4748  SCIP_Real scalar, /**< scalar that should be tried */
4749  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4750  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4751  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4752  )
4753 {
4754  SCIP_Real sval;
4755  SCIP_Real downval;
4756  SCIP_Real upval;
4757 
4758  assert(mindelta <= 0.0);
4759  assert(maxdelta >= 0.0);
4760 
4761  sval = val * scalar;
4762  downval = floor(sval);
4763  upval = ceil(sval);
4764 
4765  if( SCIPrelDiff(sval, downval) <= maxdelta )
4766  {
4767  if( intval != NULL )
4768  *intval = downval;
4769  return TRUE;
4770  }
4771  else if( SCIPrelDiff(sval, upval) >= mindelta )
4772  {
4773  if( intval != NULL )
4774  *intval = upval;
4775  return TRUE;
4776  }
4777 
4778  return FALSE;
4779 }
4780 
4781 /** scales row with given factor, and rounds coefficients to integers if close enough;
4782  * the constant is automatically moved to the sides;
4783  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4784  */
4785 static
4787  SCIP_ROW* row, /**< LP row */
4788  BMS_BLKMEM* blkmem, /**< block memory */
4789  SCIP_SET* set, /**< global SCIP settings */
4790  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4791  SCIP_STAT* stat, /**< problem statistics */
4792  SCIP_LP* lp, /**< current LP data */
4793  SCIP_Real scaleval, /**< value to scale row with */
4794  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4795  * if they are close to integral values? */
4796  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4797  * upto which the integral is used instead of the scaled real coefficient */
4798  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4799  * upto which the integral is used instead of the scaled real coefficient */
4800  )
4801 {
4802  SCIP_COL* col;
4803  SCIP_Real val;
4804  SCIP_Real newval;
4805  SCIP_Real intval;
4806  SCIP_Real mindelta;
4807  SCIP_Real maxdelta;
4808  SCIP_Real lb;
4809  SCIP_Real ub;
4810  SCIP_Bool mindeltainf;
4811  SCIP_Bool maxdeltainf;
4812  int oldlen;
4813  int c;
4814 
4815  assert(row != NULL);
4816  assert(row->len == 0 || row->cols != NULL);
4817  assert(row->len == 0 || row->vals != NULL);
4818  assert(SCIPsetIsPositive(set, scaleval));
4819  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4820  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4821 
4822  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4823 
4824  mindelta = 0.0;
4825  maxdelta = 0.0;
4826  mindeltainf = FALSE;
4827  maxdeltainf = FALSE;
4828  oldlen = row->len;
4829 
4830  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4831  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4832  * this rounding can lead to
4833  */
4834  row->integral = TRUE;
4835 
4836  c = 0;
4837  while( c < row->len )
4838  {
4839  col = row->cols[c];
4840  val = row->vals[c];
4841  assert(!SCIPsetIsZero(set, val));
4842 
4843  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4844  if( row->local )
4845  {
4846  lb = col->lb;
4847  ub = col->ub;
4848  }
4849  else
4850  {
4851  lb = SCIPvarGetLbGlobal(col->var);
4852  ub = SCIPvarGetUbGlobal(col->var);
4853  }
4854 
4855  /* calculate scaled coefficient */
4856  newval = val * scaleval;
4857  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
4858  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
4859  {
4860  if( !SCIPsetIsEQ(set, intval, newval) )
4861  {
4862  if( intval < newval )
4863  {
4864  mindelta += (intval - newval)*ub;
4865  maxdelta += (intval - newval)*lb;
4866  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
4867  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
4868  }
4869  else
4870  {
4871  mindelta += (intval - newval)*lb;
4872  maxdelta += (intval - newval)*ub;
4873  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
4874  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
4875  }
4876  }
4877  newval = intval;
4878  }
4879 
4880  if( !SCIPsetIsEQ(set, val, newval) )
4881  {
4882  /* if column knows of the row, change the corresponding coefficient in the column */
4883  if( row->linkpos[c] >= 0 )
4884  {
4885  assert(col->rows[row->linkpos[c]] == row);
4886  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
4887  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
4888  }
4889 
4890  /* change the coefficient in the row, and update the norms and integrality status */
4891  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
4892 
4893  /* current coefficient has been deleted from the row because it was almost zero */
4894  if( oldlen != row->len )
4895  {
4896  assert(row->len == oldlen - 1);
4897  c--;
4898  oldlen = row->len;
4899  }
4900 
4901  }
4902  else
4903  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
4904 
4905  ++c;
4906  }
4907 
4908  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
4909  * to not destroy feasibility due to rounding
4910  */
4911  /**@todo ensure that returned cut does not have infinite lhs and rhs */
4912  if( !SCIPsetIsInfinity(set, -row->lhs) )
4913  {
4914  if( mindeltainf )
4915  newval = -SCIPsetInfinity(set);
4916  else
4917  {
4918  newval = (row->lhs - row->constant) * scaleval + mindelta;
4919  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4920  newval = SCIPsetSumCeil(set, newval);
4921  }
4922  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
4923  }
4924  if( !SCIPsetIsInfinity(set, row->rhs) )
4925  {
4926  if( maxdeltainf )
4927  newval = SCIPsetInfinity(set);
4928  else
4929  {
4930  newval = (row->rhs - row->constant) * scaleval + maxdelta;
4931  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4932  newval = SCIPsetSumFloor(set, newval);
4933  }
4934  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
4935  }
4936 
4937  /* clear the row constant */
4938  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
4939 
4940  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
4941  debugRowPrint(set, row);
4942 
4943 #ifdef SCIP_DEBUG
4944  /* check integrality status of row */
4945  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
4946  {}
4947  assert(row->integral == (c == row->len));
4948 #endif
4949 
4950  /* invalid the activity */
4951  row->validactivitylp = -1;
4952 
4953  return SCIP_OKAY;
4954 }
4955 
4956 /** creates and captures an LP row */
4958  SCIP_ROW** row, /**< pointer to LP row data */
4959  BMS_BLKMEM* blkmem, /**< block memory */
4960  SCIP_SET* set, /**< global SCIP settings */
4961  SCIP_STAT* stat, /**< problem statistics */
4962  SCIP_LP* lp, /**< current LP data */
4963  const char* name, /**< name of row */
4964  int len, /**< number of nonzeros in the row */
4965  SCIP_COL** cols, /**< array with columns of row entries */
4966  SCIP_Real* vals, /**< array with coefficients of row entries */
4967  SCIP_Real lhs, /**< left hand side of row */
4968  SCIP_Real rhs, /**< right hand side of row */
4969  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
4970  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
4971  SCIP_Bool local, /**< is row only valid locally? */
4972  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
4973  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
4974  )
4975 {
4976  assert(row != NULL);
4977  assert(blkmem != NULL);
4978  assert(stat != NULL);
4979  assert(len >= 0);
4980  assert(len == 0 || (cols != NULL && vals != NULL));
4981  /* note, that the assert tries to avoid numerical troubles in the LP solver.
4982  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
4983  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
4984  */
4985  assert(lhs <= rhs);
4986 
4987  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
4988 
4989  (*row)->integral = TRUE;
4990  if( len > 0 )
4991  {
4992  SCIP_VAR* var;
4993  int i;
4994 
4995  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
4996  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
4997  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
4998  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
4999 
5000  for( i = 0; i < len; ++i )
5001  {
5002  assert(cols[i] != NULL);
5003  assert(!SCIPsetIsZero(set, vals[i]));
5004 
5005  var = cols[i]->var;
5006  (*row)->cols_index[i] = cols[i]->index;
5007  (*row)->linkpos[i] = -1;
5008  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5009  {
5010  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5011  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5012  }
5013  else
5014  {
5015  (*row)->integral = FALSE;
5016  }
5017  }
5018  }
5019  else
5020  {
5021  (*row)->cols = NULL;
5022  (*row)->cols_index = NULL;
5023  (*row)->vals = NULL;
5024  (*row)->linkpos = NULL;
5025  }
5026 
5027  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5028  (*row)->constant = 0.0;
5029  (*row)->lhs = lhs;
5030  (*row)->rhs = rhs;
5031  (*row)->flushedlhs = -SCIPsetInfinity(set);
5032  (*row)->flushedrhs = SCIPsetInfinity(set);
5033  (*row)->sqrnorm = 0.0;
5034  (*row)->sumnorm = 0.0;
5035  (*row)->objprod = 0.0;
5036  (*row)->maxval = 0.0;
5037  (*row)->minval = SCIPsetInfinity(set);
5038  (*row)->dualsol = 0.0;
5039  (*row)->activity = SCIP_INVALID;
5040  (*row)->dualfarkas = 0.0;
5041  (*row)->pseudoactivity = SCIP_INVALID;
5042  (*row)->minactivity = SCIP_INVALID;
5043  (*row)->maxactivity = SCIP_INVALID;
5044  (*row)->origin = origin;
5045  (*row)->eventfilter = NULL;
5046  (*row)->index = stat->nrowidx;
5047  SCIPstatIncrement(stat, set, nrowidx);
5048  (*row)->size = len;
5049  (*row)->len = len;
5050  (*row)->nlpcols = 0;
5051  (*row)->nunlinked = len;
5052  (*row)->nuses = 0;
5053  (*row)->lppos = -1;
5054  (*row)->lpipos = -1;
5055  (*row)->lpdepth = -1;
5056  (*row)->minidx = INT_MAX;
5057  (*row)->maxidx = INT_MIN;
5058  (*row)->nummaxval = 0;
5059  (*row)->numminval = 0;
5060  (*row)->validactivitylp = -1;
5061  (*row)->validpsactivitydomchg = -1;
5062  (*row)->validactivitybdsdomchg = -1;
5063  (*row)->nlpsaftercreation = 0L;
5064  (*row)->activeinlpcounter = 0L;
5065  (*row)->age = 0;
5066  (*row)->rank = 0;
5067  (*row)->obsoletenode = -1;
5068  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5069  (*row)->lpcolssorted = TRUE;
5070  (*row)->nonlpcolssorted = (len <= 1);
5071  (*row)->delaysort = FALSE;
5072  (*row)->validminmaxidx = FALSE;
5073  (*row)->lhschanged = FALSE;
5074  (*row)->rhschanged = FALSE;
5075  (*row)->coefchanged = FALSE;
5076  (*row)->local = local;
5077  (*row)->modifiable = modifiable;
5078  (*row)->nlocks = 0;
5079  (*row)->origintype = origintype; /*lint !e641*/
5080  (*row)->removable = removable;
5081  (*row)->inglobalcutpool = FALSE;
5082  (*row)->storedsolvals = NULL;
5083 
5084  /* calculate row norms and min/maxidx, and check if row is sorted */
5085  rowCalcNorms(*row, set);
5086 
5087  /* capture the row */
5088  SCIProwCapture(*row);
5089 
5090  /* create event filter */
5091  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5092 
5093  return SCIP_OKAY;
5094 } /*lint !e715*/
5095 
5096 /** frees an LP row */
5098  SCIP_ROW** row, /**< pointer to LP row */
5099  BMS_BLKMEM* blkmem, /**< block memory */
5100  SCIP_SET* set, /**< global SCIP settings */
5101  SCIP_LP* lp /**< current LP data */
5102  )
5103 {
5104  assert(blkmem != NULL);
5105  assert(row != NULL);
5106  assert(*row != NULL);
5107  assert((*row)->nuses == 0);
5108  assert((*row)->lppos == -1);
5109  assert((*row)->eventfilter != NULL);
5110 
5111  /* remove column indices from corresponding rows */
5112  SCIP_CALL( rowUnlink(*row, set, lp) );
5113 
5114  /* free event filter */
5115  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5116 
5117  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5118  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5119  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5120  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5121  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5122  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5123  BMSfreeBlockMemory(blkmem, row);
5124 
5125  return SCIP_OKAY;
5126 }
5127 
5128 /** output row to file stream */
5130  SCIP_ROW* row, /**< LP row */
5131  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5132  FILE* file /**< output file (or NULL for standard output) */
5133  )
5134 {
5135  int i;
5136 
5137  assert(row != NULL);
5138 
5139  /* print row name */
5140  if( row->name != NULL && row->name[0] != '\0' )
5141  {
5142  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5143  }
5144 
5145  /* print left hand side */
5146  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5147 
5148  /* print coefficients */
5149  if( row->len == 0 )
5150  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5151  for( i = 0; i < row->len; ++i )
5152  {
5153  assert(row->cols[i] != NULL);
5154  assert(row->cols[i]->var != NULL);
5155  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5156  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5157  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5158  }
5159 
5160  /* print constant */
5161  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5162  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5163 
5164  /* print right hand side */
5165  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5166 }
5167 
5168 /** increases usage counter of LP row */
5170  SCIP_ROW* row /**< LP row */
5171  )
5172 {
5173  assert(row != NULL);
5174  assert(row->nuses >= 0);
5175  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5176 
5177  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5178  row->nuses++;
5179 }
5180 
5181 /** decreases usage counter of LP row, and frees memory if necessary */
5183  SCIP_ROW** row, /**< pointer to LP row */
5184  BMS_BLKMEM* blkmem, /**< block memory */
5185  SCIP_SET* set, /**< global SCIP settings */
5186  SCIP_LP* lp /**< current LP data */
5187  )
5188 {
5189  assert(blkmem != NULL);
5190  assert(row != NULL);
5191  assert(*row != NULL);
5192  assert((*row)->nuses >= 1);
5193  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5194 
5195  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5196  (*row)->nuses--;
5197  if( (*row)->nuses == 0 )
5198  {
5199  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5200  }
5201 
5202  *row = NULL;
5203 
5204  return SCIP_OKAY;
5205 }
5206 
5207 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5209  SCIP_ROW* row /**< LP row */
5210  )
5211 {
5212  assert(row != NULL);
5213 
5214  /* check, if row is modifiable */
5215  if( !row->modifiable )
5216  {
5217  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5218  row->nlocks++;
5219  }
5220 }
5221 
5222 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5224  SCIP_ROW* row /**< LP row */
5225  )
5226 {
5227  assert(row != NULL);
5228 
5229  /* check, if row is modifiable */
5230  if( !row->modifiable )
5231  {
5232  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5233  assert(row->nlocks > 0);
5234  row->nlocks--;
5235  }
5236 }
5237 
5238 /** adds a previously non existing coefficient to an LP row */
5240  SCIP_ROW* row, /**< LP row */
5241  BMS_BLKMEM* blkmem, /**< block memory */
5242  SCIP_SET* set, /**< global SCIP settings */
5243  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5244  SCIP_LP* lp, /**< current LP data */
5245  SCIP_COL* col, /**< LP column */
5246  SCIP_Real val /**< value of coefficient */
5247  )
5248 {
5249  assert(lp != NULL);
5250  assert(!lp->diving || row->lppos == -1);
5251 
5252  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5253 
5254  checkLinks(lp);
5255 
5256  return SCIP_OKAY;
5257 }
5258 
5259 /** deletes coefficient from row */
5261  SCIP_ROW* row, /**< row to be changed */
5262  BMS_BLKMEM* blkmem, /**< block memory */
5263  SCIP_SET* set, /**< global SCIP settings */
5264  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5265  SCIP_LP* lp, /**< current LP data */
5266  SCIP_COL* col /**< coefficient to be deleted */
5267  )
5268 {
5269  int pos;
5270 
5271  assert(row != NULL);
5272  assert(!row->delaysort);
5273  assert(lp != NULL);
5274  assert(!lp->diving || row->lppos == -1);
5275  assert(col != NULL);
5276  assert(col->var != NULL);
5277 
5278  /* search the position of the column in the row's col vector */
5279  pos = rowSearchCoef(row, col);
5280  if( pos == -1 )
5281  {
5282  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5283  return SCIP_INVALIDDATA;
5284  }
5285  assert(0 <= pos && pos < row->len);
5286  assert(row->cols[pos] == col);
5287  assert(row->cols_index[pos] == col->index);
5288 
5289  /* if column knows of the row, remove the row from the column's row vector */
5290  if( row->linkpos[pos] >= 0 )
5291  {
5292  assert(col->rows[row->linkpos[pos]] == row);
5293  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5294  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5295  }
5296 
5297  /* delete the column from the row's col vector */
5298  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5299 
5300  checkLinks(lp);
5301 
5302  return SCIP_OKAY;
5303 }
5304 
5305 /** changes or adds a coefficient to an LP row */
5307  SCIP_ROW* row, /**< LP row */
5308  BMS_BLKMEM* blkmem, /**< block memory */
5309  SCIP_SET* set, /**< global SCIP settings */
5310  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5311  SCIP_LP* lp, /**< current LP data */
5312  SCIP_COL* col, /**< LP column */
5313  SCIP_Real val /**< value of coefficient */
5314  )
5315 {
5316  int pos;
5317 
5318  assert(row != NULL);
5319  assert(!row->delaysort);
5320  assert(lp != NULL);
5321  assert(!lp->diving || row->lppos == -1);
5322  assert(col != NULL);
5323 
5324  /* search the position of the column in the row's col vector */
5325  pos = rowSearchCoef(row, col);
5326 
5327  /* check, if column already exists in the row's col vector */
5328  if( pos == -1 )
5329  {
5330  /* add previously not existing coefficient */
5331  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5332  }
5333  else
5334  {
5335  /* modify already existing coefficient */
5336  assert(0 <= pos && pos < row->len);
5337  assert(row->cols[pos] == col);
5338  assert(row->cols_index[pos] == col->index);
5339 
5340  /* if column knows of the row, change the corresponding coefficient in the column */
5341  if( row->linkpos[pos] >= 0 )
5342  {
5343  assert(col->rows[row->linkpos[pos]] == row);
5344  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5345  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5346  }
5347 
5348  /* change the coefficient in the row */
5349  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5350  }
5351 
5352  checkLinks(lp);
5353 
5354  return SCIP_OKAY;
5355 }
5356 
5357 /** increases value of an existing or non-existing coefficient in an LP row */
5359  SCIP_ROW* row, /**< LP row */
5360  BMS_BLKMEM* blkmem, /**< block memory */
5361  SCIP_SET* set, /**< global SCIP settings */
5362  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5363  SCIP_LP* lp, /**< current LP data */
5364  SCIP_COL* col, /**< LP column */
5365  SCIP_Real incval /**< value to add to the coefficient */
5366  )
5367 {
5368  int pos;
5369 
5370  assert(row != NULL);
5371  assert(lp != NULL);
5372  assert(!lp->diving || row->lppos == -1);
5373  assert(col != NULL);
5374 
5375  if( SCIPsetIsZero(set, incval) )
5376  return SCIP_OKAY;
5377 
5378  /* search the position of the column in the row's col vector */
5379  pos = rowSearchCoef(row, col);
5380 
5381  /* check, if column already exists in the row's col vector */
5382  if( pos == -1 )
5383  {
5384  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5385  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5386  }
5387  else
5388  {
5389  /* modify already existing coefficient */
5390  assert(0 <= pos && pos < row->len);
5391  assert(row->cols[pos] == col);
5392  assert(row->cols_index[pos] == col->index);
5393 
5394  /* if column knows of the row, change the corresponding coefficient in the column */
5395  if( row->linkpos[pos] >= 0 )
5396  {
5397  assert(col->rows[row->linkpos[pos]] == row);
5398  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5399  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5400  }
5401 
5402  /* change the coefficient in the row */
5403  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5404  }
5405 
5406  checkLinks(lp);
5407 
5408  /* invalid the activity */
5409  row->validactivitylp = -1;
5410 
5411  return SCIP_OKAY;
5412 }
5413 
5414 /** changes constant value of a row */
5416  SCIP_ROW* row, /**< LP row */
5417  BMS_BLKMEM* blkmem, /**< block memory */
5418  SCIP_SET* set, /**< global SCIP settings */
5419  SCIP_STAT* stat, /**< problem statistics */
5420  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5421  SCIP_LP* lp, /**< current LP data */
5422  SCIP_Real constant /**< new constant value */
5423  )
5424 {
5425  assert(row != NULL);
5426  assert(row->lhs <= row->rhs);
5427  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5428  assert(stat != NULL);
5429  assert(lp != NULL);
5430  assert(!lp->diving || row->lppos == -1);
5431 
5432  if( !SCIPsetIsEQ(set, constant, row->constant) )
5433  {
5434  SCIP_Real oldconstant;
5435 
5436  if( row->validpsactivitydomchg == stat->domchgcount )
5437  {
5438  assert(row->pseudoactivity < SCIP_INVALID);
5439  row->pseudoactivity += constant - row->constant;
5440  }
5441  if( row->validactivitybdsdomchg == stat->domchgcount )
5442  {
5443  assert(row->minactivity < SCIP_INVALID);
5444  assert(row->maxactivity < SCIP_INVALID);
5445  row->minactivity += constant - row->constant;
5446  row->maxactivity += constant - row->constant;
5447  }
5448 
5449  if( !SCIPsetIsInfinity(set, -row->lhs) )
5450  {
5451  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5452  }
5453  if( !SCIPsetIsInfinity(set, row->rhs) )
5454  {
5455  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5456  }
5457 
5458  oldconstant = row->constant;
5459 
5460  row->constant = constant;
5461 
5462  /* issue row constant changed event */
5463  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5464  }
5465 
5466  return SCIP_OKAY;
5467 }
5468 
5469 /** add constant value to a row */
5471  SCIP_ROW* row, /**< LP row */
5472  BMS_BLKMEM* blkmem, /**< block memory */
5473  SCIP_SET* set, /**< global SCIP settings */
5474  SCIP_STAT* stat, /**< problem statistics */
5475  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5476  SCIP_LP* lp, /**< current LP data */
5477  SCIP_Real addval /**< constant value to add to the row */
5478  )
5479 {
5480  assert(row != NULL);
5481  assert(row->lhs <= row->rhs);
5482  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5483  assert(stat != NULL);
5484  assert(lp != NULL);
5485  assert(!lp->diving || row->lppos == -1);
5486 
5487  if( !SCIPsetIsZero(set, addval) )
5488  {
5489  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5490  }
5491 
5492  return SCIP_OKAY;
5493 }
5494 
5495 /** changes left hand side of LP row */
5497  SCIP_ROW* row, /**< LP row */
5498  BMS_BLKMEM* blkmem, /**< block memory */
5499  SCIP_SET* set, /**< global SCIP settings */
5500  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5501  SCIP_LP* lp, /**< current LP data */
5502  SCIP_Real lhs /**< new left hand side */
5503  )
5504 {
5505  assert(row != NULL);
5506  assert(lp != NULL);
5507 
5508  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5509  {
5510  SCIP_Real oldlhs;
5511 
5512  oldlhs = row->lhs;
5513 
5514  row->lhs = lhs;
5515  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5516 
5517  if( !lp->diving )
5518  {
5519  /* issue row side changed event */
5520  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5521  }
5522  }
5523 
5524  return SCIP_OKAY;
5525 }
5526 
5527 /** changes right hand side of LP row */
5529  SCIP_ROW* row, /**< LP row */
5530  BMS_BLKMEM* blkmem, /**< block memory */
5531  SCIP_SET* set, /**< global SCIP settings */
5532  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5533  SCIP_LP* lp, /**< current LP data */
5534  SCIP_Real rhs /**< new right hand side */
5535  )
5536 {
5537  assert(row != NULL);
5538  assert(lp != NULL);
5539 
5540  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5541  {
5542  SCIP_Real oldrhs;
5543 
5544  oldrhs = row->rhs;
5545 
5546  row->rhs = rhs;
5547  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5548 
5549  if( !lp->diving )
5550  {
5551  /* issue row side changed event */
5552  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5553  }
5554  }
5555 
5556  return SCIP_OKAY;
5557 }
5558 
5559 /** changes the local flag of LP row */
5561  SCIP_ROW* row, /**< LP row */
5562  SCIP_Bool local /**< new value for local flag */
5563  )
5564 {
5565  assert(row != NULL);
5566 
5567  row->local = local;
5568 
5569  return SCIP_OKAY;
5570 }
5571 
5572 /** additional scalars that are tried in integrality scaling */
5573 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5574 static const int nscalars = 9;
5575 
5576 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5578  SCIP_ROW* row, /**< LP row */
5579  SCIP_SET* set, /**< global SCIP settings */
5580  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5581  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5582  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5583  SCIP_Real maxscale, /**< maximal allowed scalar */
5584  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5585  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5586  SCIP_Bool* success /**< stores whether returned value is valid */
5587  )
5588 {
5589 #ifndef NDEBUG
5590  SCIP_COL* col;
5591 #endif
5592  SCIP_Longint gcd;
5593  SCIP_Longint scm;
5594  SCIP_Longint nominator;
5595  SCIP_Longint denominator;
5596  SCIP_Real val;
5597  SCIP_Real absval;
5598  SCIP_Real minval;
5599  SCIP_Real scaleval;
5600  SCIP_Real twomultval;
5601  SCIP_Bool scalable;
5602  SCIP_Bool twomult;
5603  SCIP_Bool rational;
5604  int c;
5605  int s;
5606 
5607  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5608  assert(row != NULL);
5609  assert(row->len == 0 || row->cols != NULL);
5610  assert(row->len == 0 || row->cols_index != NULL);
5611  assert(row->len == 0 || row->vals != NULL);
5612  assert(maxdnom >= 1);
5613  assert(mindelta < 0.0);
5614  assert(maxdelta > 0.0);
5615  assert(success != NULL);
5616 
5617  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5618  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5619 
5620  if( intscalar != NULL )
5621  *intscalar = SCIP_INVALID;
5622  *success = FALSE;
5623 
5624  /* get minimal absolute non-zero value */
5625  minval = SCIP_REAL_MAX;
5626  for( c = 0; c < row->len; ++c )
5627  {
5628 #ifndef NDEBUG
5629  col = row->cols[c];
5630  assert(col != NULL);
5631  assert(col->var != NULL);
5632  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5633  assert(SCIPvarGetCol(col->var) == col);
5634 #endif
5635  val = row->vals[c];
5636  assert(!SCIPsetIsZero(set, val));
5637 
5638  if( val < mindelta || val > maxdelta )
5639  {
5640  absval = REALABS(val);
5641  minval = MIN(minval, absval);
5642  }
5643  }
5644  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5645  {
5646  /* all coefficients are zero (inside tolerances) */
5647  if( intscalar != NULL )
5648  *intscalar = 1.0;
5649  *success = TRUE;
5650  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5651 
5652  return SCIP_OKAY;
5653  }
5654  assert(minval > MIN(-mindelta, maxdelta));
5655  assert(SCIPsetIsPositive(set, minval));
5656  assert(!SCIPsetIsInfinity(set, minval));
5657 
5658  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5659  * and a power of 2
5660  */
5661  scaleval = 1.0/minval;
5662  scalable = (scaleval <= maxscale);
5663  for( c = 0; c < row->len && scalable; ++c )
5664  {
5665  /* don't look at continuous variables, if we don't have to */
5666  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5667  continue;
5668 
5669  /* check, if the coefficient can be scaled with a simple scalar */
5670  val = row->vals[c];
5671  absval = REALABS(val);
5672  while( scaleval <= maxscale
5673  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5674  {
5675  for( s = 0; s < nscalars; ++s )
5676  {
5677  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5678  {
5679  scaleval *= scalars[s];
5680  break;
5681  }
5682  }
5683  if( s >= nscalars )
5684  scaleval *= 2.0;
5685  }
5686  scalable = (scaleval <= maxscale);
5687  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5688  }
5689  if( scalable )
5690  {
5691  /* make row coefficients integral by dividing them by the smallest coefficient
5692  * (and multiplying them with a power of 2)
5693  */
5694  assert(scaleval <= maxscale);
5695  if( intscalar != NULL )
5696  *intscalar = scaleval;
5697  *success = TRUE;
5698  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5699 
5700  return SCIP_OKAY;
5701  }
5702 
5703  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5704  twomultval = 1.0;
5705  twomult = (twomultval <= maxscale);
5706  for( c = 0; c < row->len && twomult; ++c )
5707  {
5708  /* don't look at continuous variables, if we don't have to */
5709  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5710  continue;
5711 
5712  /* check, if the coefficient can be scaled with a simple scalar */
5713  val = row->vals[c];
5714  absval = REALABS(val);
5715  while( twomultval <= maxscale
5716  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5717  {
5718  for( s = 0; s < nscalars; ++s )
5719  {
5720  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5721  {
5722  twomultval *= scalars[s];
5723  break;
5724  }
5725  }
5726  if( s >= nscalars )
5727  twomultval *= 2.0;
5728  }
5729  twomult = (twomultval <= maxscale);
5730  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5731  val, twomultval, val*twomultval, twomult);
5732  }
5733  if( twomult )
5734  {
5735  /* make row coefficients integral by multiplying them with a power of 2 */
5736  assert(twomultval <= maxscale);
5737  if( intscalar != NULL )
5738  *intscalar = twomultval;
5739  *success = TRUE;
5740  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5741 
5742  return SCIP_OKAY;
5743  }
5744 
5745  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5746  * and the smallest common multiple of the denominators
5747  */
5748  gcd = 1;
5749  scm = 1;
5750  rational = (maxdnom > 1);
5751 
5752  /* first coefficient (to initialize gcd) */
5753  for( c = 0; c < row->len && rational; ++c )
5754  {
5755  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5756  {
5757  val = row->vals[c];
5758  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5759  if( rational && nominator != 0 )
5760  {
5761  assert(denominator > 0);
5762  gcd = ABS(nominator);
5763  scm = denominator;
5764  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5765  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5766  val, nominator, denominator, gcd, scm, rational);
5767  break;
5768  }
5769  }
5770  }
5771 
5772  /* remaining coefficients */
5773  for( ++c; c < row->len && rational; ++c )
5774  {
5775  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5776  {
5777  val = row->vals[c];
5778  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5779  if( rational && nominator != 0 )
5780  {
5781  assert(denominator > 0);
5782  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5783  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5784  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5785  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5786  val, nominator, denominator, gcd, scm, rational);
5787  }
5788  }
5789  }
5790 
5791  if( rational )
5792  {
5793  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5794  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5795  if( intscalar != NULL )
5796  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5797  *success = TRUE;
5798  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5799  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5800  }
5801  else
5802  {
5803  assert(!(*success));
5804  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5805  }
5806 
5807  return SCIP_OKAY;
5808 }
5809 
5810 /** tries to scale row, s.t. all coefficients become integral */
5812  SCIP_ROW* row, /**< LP row */
5813  BMS_BLKMEM* blkmem, /**< block memory */
5814  SCIP_SET* set, /**< global SCIP settings */
5815  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5816  SCIP_STAT* stat, /**< problem statistics */
5817  SCIP_LP* lp, /**< current LP data */
5818  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5819  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5820  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5821  SCIP_Real maxscale, /**< maximal value to scale row with */
5822  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5823  SCIP_Bool* success /**< stores whether row could be made rational */
5824  )
5825 {
5826  SCIP_Real intscalar;
5827 
5828  assert(success != NULL);
5829 
5830  /* calculate scalar to make coefficients integral */
5831  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5832  &intscalar, success) );
5833 
5834  if( *success )
5835  {
5836  /* scale the row */
5837  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
5838  }
5839 
5840  return SCIP_OKAY;
5841 }
5842 
5843 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
5844  * higher ones
5845  */
5847  SCIP_ROW* row /**< row to be sorted */
5848  )
5849 {
5850  assert(row != NULL);
5851 
5852  /* sort LP columns */
5853  rowSortLP(row);
5854 
5855  /* sort non-LP columns */
5856  rowSortNonLP(row);
5857 
5858 #ifdef SCIP_MORE_DEBUG
5859  /* check the sorting */
5860  {
5861  int c;
5862  if( !row->delaysort )
5863  {
5864  for( c = 1; c < row->nlpcols; ++c )
5865  assert(row->cols[c]->index >= row->cols[c-1]->index);
5866  for( c = row->nlpcols + 1; c < row->len; ++c )
5867  assert(row->cols[c]->index >= row->cols[c-1]->index);
5868  }
5869  }
5870 #endif
5871 }
5872 
5873 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
5874  * zero entries from row
5875  * the row must not be linked to the columns; otherwise, we would need to update the columns as
5876  * well, which is too expensive
5877  */
5878 static
5880  SCIP_ROW* row, /**< row to be sorted */
5881  SCIP_SET* set /**< global SCIP settings */
5882  )
5883 {
5884  assert(row != NULL);
5885  assert(!row->delaysort);
5886  assert(row->nunlinked == row->len);
5887  assert(row->nlpcols == 0);
5888 
5889  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
5890 
5891  /* do nothing on empty rows; if row is sorted, nothing has to be done */
5892  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
5893  {
5894  SCIP_COL** cols;
5895  int* cols_index;
5896  SCIP_Real* vals;
5897  int s;
5898  int t;
5899 
5900  /* make sure, the row is sorted */
5901  SCIProwSort(row);
5902  assert(row->lpcolssorted);
5903  assert(row->nonlpcolssorted);
5904 
5905  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
5906  cols = row->cols;
5907  cols_index = row->cols_index;
5908  vals = row->vals;
5909  assert(cols != NULL);
5910  assert(cols_index != NULL);
5911  assert(vals != NULL);
5912 
5913  t = 0;
5914  row->integral = TRUE;
5915  assert(!SCIPsetIsZero(set, vals[0]));
5916  assert(row->linkpos[0] == -1);
5917 
5918  for( s = 1; s < row->len; ++s )
5919  {
5920  assert(!SCIPsetIsZero(set, vals[s]));
5921  assert(row->linkpos[s] == -1);
5922 
5923  if( cols[s] == cols[t] )
5924  {
5925  /* merge entries with equal column */
5926  vals[t] += vals[s];
5927  }
5928  else
5929  {
5930  /* go to the next entry, overwriting current entry if coefficient is zero */
5931  if( !SCIPsetIsZero(set, vals[t]) )
5932  {
5933  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
5934  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
5935 
5936  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5937  t++;
5938  }
5939  cols[t] = cols[s];
5940  cols_index[t] = cols_index[s];
5941  vals[t] = vals[s];
5942  }
5943  }
5944  if( !SCIPsetIsZero(set, vals[t]) )
5945  {
5946  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
5947  t++;
5948  }
5949  assert(s == row->len);
5950  assert(t <= row->len);
5951 
5952  row->len = t;
5953  row->nunlinked = t;
5954 
5955  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
5956  if( t < s )
5957  rowCalcNorms(row, set);
5958  }
5959 
5960 #ifndef NDEBUG
5961  /* check for double entries */
5962  {
5963  int i;
5964  int j;
5965 
5966  for( i = 0; i < row->len; ++i )
5967  {
5968  assert(row->cols[i] != NULL);
5969  assert(row->cols[i]->index == row->cols_index[i]);
5970  for( j = i+1; j < row->len; ++j )
5971  assert(row->cols[i] != row->cols[j]);
5972  }
5973  }
5974 #endif
5975 }
5976 
5977 /** enables delaying of row sorting */
5979  SCIP_ROW* row /**< LP row */
5980  )
5981 {
5982  assert(row != NULL);
5983  assert(!row->delaysort);
5984 
5985  row->delaysort = TRUE;
5986 }
5987 
5988 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
5990  SCIP_ROW* row, /**< LP row */
5991  SCIP_SET* set /**< global SCIP settings */
5992  )
5993 {
5994  assert(row != NULL);
5995  assert(row->delaysort);
5996 
5997  row->delaysort = FALSE;
5998  rowMerge(row, set);
5999 }
6000 
6001 /** recalculates the current activity of a row */
6003  SCIP_ROW* row, /**< LP row */
6004  SCIP_STAT* stat /**< problem statistics */
6005  )
6006 {
6007  SCIP_COL* col;
6008  int c;
6009 
6010  assert(row != NULL);
6011  assert(stat != NULL);
6012 
6013  row->activity = row->constant;
6014  for( c = 0; c < row->nlpcols; ++c )
6015  {
6016  col = row->cols[c];
6017  assert(col != NULL);
6018  assert(col->primsol < SCIP_INVALID);
6019  assert(col->lppos >= 0);
6020  assert(row->linkpos[c] >= 0);
6021  row->activity += row->vals[c] * col->primsol;
6022  }
6023 
6024  if( row->nunlinked > 0 )
6025  {
6026  for( c = row->nlpcols; c < row->len; ++c )
6027  {
6028  col = row->cols[c];
6029  assert(col != NULL);
6030  assert(col->lppos >= 0 || col->primsol == 0.0);
6031  assert(col->lppos == -1 || row->linkpos[c] == -1);
6032  if( col->lppos >= 0 )
6033  row->activity += row->vals[c] * col->primsol;
6034  }
6035  }
6036 #ifndef NDEBUG
6037  else
6038  {
6039  for( c = row->nlpcols; c < row->len; ++c )
6040  {
6041  col = row->cols[c];
6042  assert(col != NULL);
6043  assert(col->primsol == 0.0);
6044  assert(col->lppos == -1);
6045  assert(row->linkpos[c] >= 0);
6046  }
6047  }
6048 #endif
6049 
6050  row->validactivitylp = stat->lpcount;
6051 }
6052 
6053 /** returns the activity of a row in the current LP solution */
6055  SCIP_ROW* row, /**< LP row */
6056  SCIP_SET* set, /**< global SCIP settings */
6057  SCIP_STAT* stat, /**< problem statistics */
6058  SCIP_LP* lp /**< current LP data */
6059  )
6060 {
6061  SCIP_Real inf;
6062  SCIP_Real activity;
6063 
6064  assert(row != NULL);
6065  assert(stat != NULL);
6066  assert(lp != NULL);
6067  assert(row->validactivitylp <= stat->lpcount);
6068  assert(lp->validsollp == stat->lpcount);
6069 
6070  if( row->validactivitylp != stat->lpcount )
6071  SCIProwRecalcLPActivity(row, stat);
6072  assert(row->validactivitylp == stat->lpcount);
6073  assert(row->activity < SCIP_INVALID);
6074 
6075  activity = row->activity;
6076  inf = SCIPsetInfinity(set);
6077  activity = MAX(activity, -inf);
6078  activity = MIN(activity, +inf);
6079 
6080  return activity;
6081 }
6082 
6083 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6085  SCIP_ROW* row, /**< LP row */
6086  SCIP_SET* set, /**< global SCIP settings */
6087  SCIP_STAT* stat, /**< problem statistics */
6088  SCIP_LP* lp /**< current LP data */
6089  )
6090 {
6091  SCIP_Real activity;
6092 
6093  assert(row != NULL);
6094 
6095  activity = SCIProwGetLPActivity(row, set, stat, lp);
6096 
6097  return MIN(row->rhs - activity, activity - row->lhs);
6098 }
6099 
6100 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6101  *
6102  * @todo Implement calculation of activities similar to LPs.
6103  */
6105  SCIP_ROW* row, /**< LP row */
6106  SCIP_SET* set, /**< global SCIP settings */
6107  SCIP_STAT* stat /**< problem statistics */
6108  )
6109 {
6110  SCIP_Real inf;
6111  SCIP_Real activity;
6112  SCIP_COL* col;
6113  int c;
6114 
6115  assert( row != NULL );
6116  assert( stat != NULL );
6117 
6118  activity = row->constant;
6119  for (c = 0; c < row->nlpcols; ++c)
6120  {
6121  col = row->cols[c];
6122  assert( col != NULL );
6123  assert( col->lppos >= 0 );
6124  assert( col->var != NULL );
6125  assert( row->linkpos[c] >= 0 );
6126  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6127  }
6128 
6129  if ( row->nunlinked > 0 )
6130  {
6131  for (c = row->nlpcols; c < row->len; ++c)
6132  {
6133  col = row->cols[c];
6134  assert( col != NULL );
6135  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6136  if ( col->lppos >= 0 )
6137  {
6138  assert( col->var != NULL );
6139  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6140  }
6141  }
6142  }
6143 #ifndef NDEBUG
6144  else
6145  {
6146  for (c = row->nlpcols; c < row->len; ++c)
6147  {
6148  col = row->cols[c];
6149  assert( col != NULL );
6150  assert( col->lppos == -1 );
6151  assert( row->linkpos[c] >= 0 );
6152  }
6153  }
6154 #endif
6155  inf = SCIPsetInfinity(set);
6156  activity = MAX(activity, -inf);
6157  activity = MIN(activity, +inf);
6158 
6159  return MIN(row->rhs - activity, activity - row->lhs);
6160 }
6161 
6162 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6163  *
6164  * @todo Implement calculation of activities similar to LPs.
6165  */
6167  SCIP_ROW* row, /**< LP row */
6168  SCIP_SET* set, /**< global SCIP settings */
6169  SCIP_STAT* stat /**< problem statistics */
6170  )
6171 {
6172  SCIP_Real inf;
6173  SCIP_Real activity;
6174  SCIP_COL* col;
6175  int c;
6176 
6177  assert( row != NULL );
6178  assert( stat != NULL );
6179 
6180  activity = row->constant;
6181  for (c = 0; c < row->nlpcols; ++c)
6182  {
6183  col = row->cols[c];
6184  assert( col != NULL );
6185  assert( col->lppos >= 0 );
6186  assert( col->var != NULL );
6187  assert( row->linkpos[c] >= 0 );
6188  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6189  }
6190 
6191  if ( row->nunlinked > 0 )
6192  {
6193  for (c = row->nlpcols; c < row->len; ++c)
6194  {
6195  col = row->cols[c];
6196  assert( col != NULL );
6197  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6198  if ( col->lppos >= 0 )
6199  {
6200  assert( col->var != NULL );
6201  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6202  }
6203  }
6204  }
6205 #ifndef NDEBUG
6206  else
6207  {
6208  for (c = row->nlpcols; c < row->len; ++c)
6209  {
6210  col = row->cols[c];
6211  assert( col != NULL );
6212  assert( col->lppos == -1 );
6213  assert( row->linkpos[c] >= 0 );
6214  }
6215  }
6216 #endif
6217  inf = SCIPsetInfinity(set);
6218  activity = MAX(activity, -inf);
6219  activity = MIN(activity, +inf);
6220 
6221  return MIN(row->rhs - activity, activity - row->lhs);
6222 }
6223 
6224 /** calculates the current pseudo activity of a row */
6226  SCIP_ROW* row, /**< row data */
6227  SCIP_STAT* stat /**< problem statistics */
6228  )
6229 {
6230  SCIP_COL* col;
6231  int i;
6232 
6233  assert(row != NULL);
6234  assert(stat != NULL);
6235 
6236  row->pseudoactivity = row->constant;
6237  for( i = 0; i < row->len; ++i )
6238  {
6239  col = row->cols[i];
6240  assert(col != NULL);
6241  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6242  assert(col->var != NULL);
6243  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6244 
6245  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6246  }
6247  row->validpsactivitydomchg = stat->domchgcount;
6248  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6249 }
6250 
6251 /** returns the pseudo activity of a row in the current pseudo solution */
6253  SCIP_ROW* row, /**< LP row */
6254  SCIP_SET* set, /**< global SCIP settings */
6255  SCIP_STAT* stat /**< problem statistics */
6256  )
6257 {
6258  SCIP_Real inf;
6259  SCIP_Real activity;
6260 
6261  assert(row != NULL);
6262  assert(stat != NULL);
6263  assert(row->validpsactivitydomchg <= stat->domchgcount);
6264 
6265  /* check, if pseudo activity has to be calculated */
6266  if( row->validpsactivitydomchg != stat->domchgcount )
6267  SCIProwRecalcPseudoActivity(row, stat);
6268  assert(row->validpsactivitydomchg == stat->domchgcount);
6269  assert(row->pseudoactivity < SCIP_INVALID);
6270 
6271  activity = row->pseudoactivity;
6272  inf = SCIPsetInfinity(set);
6273  activity = MAX(activity, -inf);
6274  activity = MIN(activity, +inf);
6275 
6276  return activity;
6277 }
6278 
6279 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6281  SCIP_ROW* row, /**< LP row */
6282  SCIP_SET* set, /**< global SCIP settings */
6283  SCIP_STAT* stat /**< problem statistics */
6284  )
6285 {
6286  SCIP_Real pseudoactivity;
6287 
6288  assert(row != NULL);
6289 
6290  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6291 
6292  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6293 }
6294 
6295 /** returns the activity of a row for a given solution */
6297  SCIP_ROW* row, /**< LP row */
6298  SCIP_SET* set, /**< global SCIP settings */
6299  SCIP_STAT* stat, /**< problem statistics data */
6300  SCIP_SOL* sol /**< primal CIP solution */
6301  )
6302 {
6303  SCIP_COL* col;
6304  SCIP_Real inf;
6305  SCIP_Real activity;
6306  SCIP_Real solval;
6307  int i;
6308 
6309  assert(row != NULL);
6310 
6311  activity = row->constant;
6312  for( i = 0; i < row->len; ++i )
6313  {
6314  col = row->cols[i];
6315  assert(col != NULL);
6316  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6317  solval = SCIPsolGetVal(sol, set, stat, col->var);
6318  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6319  {
6320  if( SCIPsetIsInfinity(set, -row->lhs) )
6321  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6322  else if( SCIPsetIsInfinity(set, row->rhs) )
6323  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6324  else
6325  solval = (col->lb + col->ub)/2.0;
6326  }
6327  activity += row->vals[i] * solval;
6328  }
6329 
6330  inf = SCIPsetInfinity(set);
6331  activity = MAX(activity, -inf);
6332  activity = MIN(activity, +inf);
6333 
6334  return activity;
6335 }
6336 
6337 /** returns the feasibility of a row for the given solution */
6339  SCIP_ROW* row, /**< LP row */
6340  SCIP_SET* set, /**< global SCIP settings */
6341  SCIP_STAT* stat, /**< problem statistics data */
6342  SCIP_SOL* sol /**< primal CIP solution */
6343  )
6344 {
6345  SCIP_Real activity;
6346 
6347  assert(row != NULL);
6348 
6349  activity = SCIProwGetSolActivity(row, set, stat, sol);
6350 
6351  return MIN(row->rhs - activity, activity - row->lhs);
6352 }
6353 
6354 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6355 static
6357  SCIP_ROW* row, /**< row data */
6358  SCIP_SET* set, /**< global SCIP settings */
6359  SCIP_STAT* stat /**< problem statistics data */
6360  )
6361 {
6362  SCIP_COL* col;
6363  SCIP_Real val;
6364  SCIP_Bool mininfinite;
6365  SCIP_Bool maxinfinite;
6366  int i;
6367 
6368  assert(row != NULL);
6369  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6370  assert(stat != NULL);
6371 
6372  /* calculate activity bounds */
6373  mininfinite = FALSE;
6374  maxinfinite = FALSE;
6375  row->minactivity = row->constant;
6376  row->maxactivity = row->constant;
6377  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6378  {
6379  col = row->cols[i];
6380  assert(col != NULL);
6381  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6382  val = row->vals[i];
6383  if( val >= 0.0 )
6384  {
6385  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6386  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6387  if( !mininfinite )
6388  row->minactivity += val * col->lb;
6389  if( !maxinfinite )
6390  row->maxactivity += val * col->ub;
6391  }
6392  else
6393  {
6394  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6395  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6396  if( !mininfinite )
6397  row->minactivity += val * col->ub;
6398  if( !maxinfinite )
6399  row->maxactivity += val * col->lb;
6400  }
6401  }
6402 
6403  if( mininfinite )
6404  row->minactivity = -SCIPsetInfinity(set);
6405  if( maxinfinite )
6406  row->maxactivity = SCIPsetInfinity(set);
6407  row->validactivitybdsdomchg = stat->domchgcount;
6408 
6409  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6411  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIP_DEFAULT_SUMEPSILON
6413 }
6414 
6415 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6417  SCIP_ROW* row, /**< LP row */
6418  SCIP_SET* set, /**< global SCIP settings */
6419  SCIP_STAT* stat /**< problem statistics data */
6420  )
6421 {
6422  assert(row != NULL);
6423  assert(stat != NULL);
6424  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6425 
6426  /* check, if activity bounds has to be calculated */
6427  if( row->validactivitybdsdomchg != stat->domchgcount )
6428  rowCalcActivityBounds(row, set, stat);
6429  assert(row->validactivitybdsdomchg == stat->domchgcount);
6430  assert(row->minactivity < SCIP_INVALID);
6431  assert(row->maxactivity < SCIP_INVALID);
6432 
6433  return row->minactivity;
6434 }
6435 
6436 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6438  SCIP_ROW* row, /**< LP row */
6439  SCIP_SET* set, /**< global SCIP settings */
6440  SCIP_STAT* stat /**< problem statistics data */
6441  )
6442 {
6443  assert(row != NULL);
6444  assert(stat != NULL);
6445  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6446 
6447  /* check, if activity bounds has to be calculated */
6448  if( row->validactivitybdsdomchg != stat->domchgcount )
6449  rowCalcActivityBounds(row, set, stat);
6450  assert(row->validactivitybdsdomchg == stat->domchgcount);
6451  assert(row->minactivity < SCIP_INVALID);
6452  assert(row->maxactivity < SCIP_INVALID);
6453 
6454  return row->maxactivity;
6455 }
6456 
6457 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6459  SCIP_ROW* row, /**< LP row */
6460  SCIP_SET* set, /**< global SCIP settings */
6461  SCIP_STAT* stat /**< problem statistics data */
6462  )
6463 {
6464  assert(row != NULL);
6465 
6466  if( row->modifiable )
6467  return FALSE;
6468  if( !SCIPsetIsInfinity(set, -row->lhs) )
6469  {
6470  SCIP_Real minactivity;
6471 
6472  minactivity = SCIProwGetMinActivity(row, set, stat);
6473  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6474  return FALSE;
6475  }
6476  if( !SCIPsetIsInfinity(set, row->rhs) )
6477  {
6478  SCIP_Real maxactivity;
6479 
6480  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6481  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6482  return FALSE;
6483  }
6484 
6485  return TRUE;
6486 }
6487 
6488 /** gets maximal absolute value of row vector coefficients */
6490  SCIP_ROW* row, /**< LP row */
6491  SCIP_SET* set /**< global SCIP settings */
6492  )
6493 {
6494  assert(row != NULL);
6495 
6496  if( row->nummaxval == 0 )
6497  rowCalcIdxsAndVals(row, set);
6498  assert(row->nummaxval > 0);
6499  assert(row->maxval >= 0.0 || row->len == 0);
6500 
6501  return row->maxval;
6502 }
6503 
6504 /** gets minimal absolute value of row vector's non-zero coefficients */
6506  SCIP_ROW* row, /**< LP row */
6507  SCIP_SET* set /**< global SCIP settings */
6508  )
6509 {
6510  assert(row != NULL);
6511 
6512  if( row->numminval == 0 )
6513  rowCalcIdxsAndVals(row, set);
6514  assert(row->numminval > 0);
6515  assert(row->minval >= 0.0 || row->len == 0);
6516 
6517  return row->minval;
6518 }
6519 
6520 /** gets maximal column index of row entries */
6522  SCIP_ROW* row, /**< LP row */
6523  SCIP_SET* set /**< global SCIP settings */
6524  )
6525 {
6526  assert(row != NULL);
6527 
6528  if( row->validminmaxidx == 0 )
6529  rowCalcIdxsAndVals(row, set);
6530  assert(row->maxidx >= 0 || row->len == 0);
6531  assert(row->validminmaxidx);
6532 
6533  return row->maxidx;
6534 }
6535 
6536 /** gets minimal column index of row entries */
6538  SCIP_ROW* row, /**< LP row */
6539  SCIP_SET* set /**< global SCIP settings */
6540  )
6541 {
6542  assert(row != NULL);
6543 
6544  if( row->validminmaxidx == 0 )
6545  rowCalcIdxsAndVals(row, set);
6546  assert(row->minidx >= 0 || row->len == 0);
6547  assert(row->validminmaxidx);
6548 
6549  return row->minidx;
6550 }
6551 
6552 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6554  SCIP_ROW* row, /**< LP row */
6555  SCIP_SET* set, /**< global SCIP settings */
6556  SCIP_STAT* stat, /**< problem statistics data */
6557  SCIP_LP* lp /**< current LP data */
6558  )
6559 {
6560  SCIP_Real norm;
6561  SCIP_Real feasibility;
6562  SCIP_Real eps;
6563 
6564  assert(set != NULL);
6565 
6566  switch( set->sepa_efficacynorm )
6567  {
6568  case 'e':
6569  norm = SCIProwGetNorm(row);
6570  break;
6571  case 'm':
6572  norm = SCIProwGetMaxval(row, set);
6573  break;
6574  case 's':
6575  norm = SCIProwGetSumNorm(row);
6576  break;
6577  case 'd':
6578  norm = (row->len == 0 ? 0.0 : 1.0);
6579  break;
6580  default:
6581  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6582  SCIPABORT();
6583  norm = 0.0; /*lint !e527*/
6584  }
6585 
6586  eps = SCIPsetSumepsilon(set);
6587  norm = MAX(norm, eps);
6588  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6589 
6590  return -feasibility / norm;
6591 }
6592 
6593 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6595  SCIP_ROW* row, /**< LP row */
6596  SCIP_SET* set, /**< global SCIP settings */
6597  SCIP_STAT* stat, /**< problem statistics data */
6598  SCIP_LP* lp, /**< current LP data */
6599  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6600  )
6601 {
6602  SCIP_Real efficacy;
6603 
6604  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6605 
6606  return SCIPsetIsEfficacious(set, root, efficacy);
6607 }
6608 
6609 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6611  SCIP_ROW* row, /**< LP row */
6612  SCIP_SET* set, /**< global SCIP settings */
6613  SCIP_STAT* stat, /**< problem statistics data */
6614  SCIP_SOL* sol /**< primal CIP solution */
6615  )
6616 {
6617  SCIP_Real norm;
6618  SCIP_Real feasibility;
6619  SCIP_Real eps;
6620 
6621  assert(set != NULL);
6622 
6623  switch( set->sepa_efficacynorm )
6624  {
6625  case 'e':
6626  norm = SCIProwGetNorm(row);
6627  break;
6628  case 'm':
6629  norm = SCIProwGetMaxval(row, set);
6630  break;
6631  case 's':
6632  norm = SCIProwGetSumNorm(row);
6633  break;
6634  case 'd':
6635  norm = (row->len == 0 ? 0.0 : 1.0);
6636  break;
6637  default:
6638  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6639  SCIPABORT();
6640  norm = 0.0; /*lint !e527*/
6641  }
6642 
6643  eps = SCIPsetSumepsilon(set);
6644  norm = MAX(norm, eps);
6645  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6646 
6647  return -feasibility / norm;
6648 }
6649 
6650 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6651  * efficacy
6652  */
6654  SCIP_ROW* row, /**< LP row */
6655  SCIP_SET* set, /**< global SCIP settings */
6656  SCIP_STAT* stat, /**< problem statistics data */
6657  SCIP_SOL* sol, /**< primal CIP solution */
6658  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6659  )
6660 {
6661  SCIP_Real efficacy;
6662 
6663  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6664 
6665  return SCIPsetIsEfficacious(set, root, efficacy);
6666 }
6667 
6668 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6670  SCIP_ROW* row, /**< LP row */
6671  SCIP_SET* set, /**< global SCIP settings */
6672  SCIP_STAT* stat /**< problem statistics data */
6673  )
6674 {
6675  SCIP_Real norm;
6676  SCIP_Real feasibility;
6677  SCIP_Real eps;
6678 
6679  assert(set != NULL);
6680 
6681  switch( set->sepa_efficacynorm )
6682  {
6683  case 'e':
6684  norm = SCIProwGetNorm(row);
6685  break;
6686  case 'm':
6687  norm = SCIProwGetMaxval(row, set);
6688  break;
6689  case 's':
6690  norm = SCIProwGetSumNorm(row);
6691  break;
6692  case 'd':
6693  norm = (row->len == 0 ? 0.0 : 1.0);
6694  break;
6695  default:
6696  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6697  SCIPABORT();
6698  norm = 0.0; /*lint !e527*/
6699  }
6700 
6701  eps = SCIPsetSumepsilon(set);
6702  norm = MAX(norm, eps);
6703  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6704 
6705  return -feasibility / norm;
6706 }
6707 
6708 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6710  SCIP_ROW* row, /**< LP row */
6711  SCIP_SET* set, /**< global SCIP settings */
6712  SCIP_STAT* stat /**< problem statistics data */
6713  )
6714 {
6715  SCIP_Real norm;
6716  SCIP_Real feasibility;
6717  SCIP_Real eps;
6718 
6719  assert(set != NULL);
6720 
6721  switch( set->sepa_efficacynorm )
6722  {
6723  case 'e':
6724  norm = SCIProwGetNorm(row);
6725  break;
6726  case 'm':
6727  norm = SCIProwGetMaxval(row, set);
6728  break;
6729  case 's':
6730  norm = SCIProwGetSumNorm(row);
6731  break;
6732  case 'd':
6733  norm = (row->len == 0 ? 0.0 : 1.0);
6734  break;
6735  default:
6736  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6737  SCIPABORT();
6738  norm = 0.0; /*lint !e527*/
6739  }
6740 
6741  eps = SCIPsetSumepsilon(set);
6742  norm = MAX(norm, eps);
6743  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6744 
6745  return -feasibility / norm;
6746 }
6747 
6748 /** returns the scalar product of the coefficient vectors of the two given rows
6749  *
6750  * @note the scalar product is computed w.r.t. the current LP columns only
6751  * @todo also consider non-LP columns for the computation?
6752  */
6754  SCIP_ROW* row1, /**< first LP row */
6755  SCIP_ROW* row2 /**< second LP row */
6756  )
6757 {
6758  SCIP_Real scalarprod;
6759  int* row1colsidx;
6760  int* row2colsidx;
6761  int i1;
6762  int i2;
6763 
6764  assert(row1 != NULL);
6765  assert(row2 != NULL);
6766 
6767  /* Sort the column indices of both rows.
6768  *
6769  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
6770  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
6771  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
6772  * for both or one of the non-LP columns for both.
6773  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
6774  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
6775  * columns can be added later and remain unlinked while all previously added columns might already be linked.
6776  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
6777  *
6778  * We distinguish the following cases:
6779  *
6780  * 1) both rows have no unlinked columns
6781  * -> we just check the LP partitions
6782  *
6783  * 2) exactly one row is completely unlinked, the other one is completely linked
6784  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
6785  * (thus all common LP columns are regarded)
6786  *
6787  * 3) we have unlinked and LP columns in both rows
6788  * -> we need to compare four partitions at once
6789  *
6790  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
6791  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
6792  * other row
6793  *
6794  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
6795  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
6796  *
6797  * 5) both rows are completely unlinked
6798  * -> we need to compare two partitions: both complete rows
6799  */
6800  SCIProwSort(row1);
6801  assert(row1->lpcolssorted);
6802  assert(row1->nonlpcolssorted);
6803  SCIProwSort(row2);
6804  assert(row2->lpcolssorted);
6805  assert(row2->nonlpcolssorted);
6806 
6807  assert(row1->nunlinked <= row1->len - row1->nlpcols);
6808  assert(row2->nunlinked <= row2->len - row2->nlpcols);
6809 
6810  row1colsidx = row1->cols_index;
6811  row2colsidx = row2->cols_index;
6812 
6813 #ifndef NDEBUG
6814  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
6815  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
6816  {
6817  i1 = 0;
6818  i2 = row2->nlpcols;
6819  while( i1 < row1->nlpcols && i2 < row2->len )
6820  {
6821  assert(row1->cols[i1] != row2->cols[i2]);
6822  if( row1->cols[i1]->index < row2->cols[i2]->index )
6823  ++i1;
6824  else
6825  {
6826  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6827  ++i2;
6828  }
6829  }
6830  assert(i1 == row1->nlpcols || i2 == row2->len);
6831 
6832  i1 = row1->nlpcols;
6833  i2 = 0;
6834  while( i1 < row1->len && i2 < row2->nlpcols )
6835  {
6836  assert(row1->cols[i1] != row2->cols[i2]);
6837  if( row1->cols[i1]->index < row2->cols[i2]->index )
6838  ++i1;
6839  else
6840  {
6841  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6842  ++i2;
6843  }
6844  }
6845  assert(i1 == row1->len || i2 == row2->nlpcols);
6846  }
6847 #endif
6848 
6849  /* The "easy" cases 1) and 2) */
6850  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
6851  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
6852  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
6853  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
6854  {
6855  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
6856  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
6857 
6858  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
6859  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
6860  */
6861  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
6862  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
6863  scalarprod = 0.0;
6864 
6865  /* calculate the scalar product */
6866  while( i1 >= 0 && i2 >= 0 )
6867  {
6868  assert(row1->cols[i1]->index == row1colsidx[i1]);
6869  assert(row2->cols[i2]->index == row2colsidx[i2]);
6870  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
6871  if( row1colsidx[i1] < row2colsidx[i2] )
6872  --i2;
6873  else if( row1colsidx[i1] > row2colsidx[i2] )
6874  --i1;
6875  else
6876  {
6877  scalarprod += row1->vals[i1] * row2->vals[i2];
6878  --i1;
6879  --i2;
6880  }
6881  }
6882  }
6883  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
6884  else
6885  {
6886  SCIP_Bool lpcols;
6887  int ilp1;
6888  int inlp1;
6889  int ilp2;
6890  int inlp2;
6891  int end1;
6892  int end2;
6893 
6894  scalarprod = 0;
6895  ilp1 = 0;
6896  ilp2 = 0;
6897 
6898  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
6899  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
6900  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
6901 
6902  /* handle the case of four partitions (case 3) until one partition is finished;
6903  * cases 4a), 4b), and 5) will fail the while-condition
6904  */
6905  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
6906  {
6907  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
6908  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
6909  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
6910  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
6911  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
6912  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
6913  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
6914  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
6915 
6916  /* rows have the same linked LP columns */
6917  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
6918  {
6919  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
6920  ++ilp1;
6921  ++ilp2;
6922  }
6923  /* LP column of row1 is the same as unlinked column of row2 */
6924  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
6925  {
6926  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
6927  ++ilp1;
6928  ++inlp2;
6929  }
6930  /* unlinked column of row1 is the same as LP column of row2 */
6931  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
6932  {
6933  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
6934  ++inlp1;
6935  ++ilp2;
6936  }
6937  /* two unlinked LP columns are the same */
6938  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
6939  {
6940  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
6941  ++inlp1;
6942  ++inlp2;
6943  }
6944  /* increase smallest counter */
6945  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
6946  {
6947  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
6948  {
6949  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
6950  ++ilp1;
6951  else
6952  ++ilp2;
6953  }
6954  else
6955  {
6956  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
6957  ++ilp1;
6958  else
6959  ++inlp2;
6960  }
6961  }
6962  else
6963  {
6964  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
6965  {
6966  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
6967  ++inlp1;
6968  else
6969  ++ilp2;
6970  }
6971  else
6972  {
6973  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
6974  ++inlp1;
6975  else
6976  ++inlp2;
6977  }
6978  }
6979  }
6980 
6981  /* One partition was completely handled, we just have to handle the three remaining partitions:
6982  * the remaining partition of this row and the two partitions of the other row.
6983  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
6984  */
6985  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
6986  {
6987  int tmpilp;
6988  int tmpinlp;
6989 
6990  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
6991 
6992  SCIPswapPointers((void**) &row1, (void**) &row2);
6993  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
6994  tmpilp = ilp1;
6995  tmpinlp = inlp1;
6996  ilp1 = ilp2;
6997  inlp1 = inlp2;
6998  ilp2 = tmpilp;
6999  inlp2 = tmpinlp;
7000  }
7001 
7002  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7003  * -> this merges cases 4a) and 4b)
7004  */
7005  if( ilp1 == row1->nlpcols )
7006  {
7007  i1 = inlp1;
7008  end1 = row1->len;
7009  lpcols = FALSE;
7010  }
7011  else
7012  {
7013  assert(inlp1 == row1->len);
7014 
7015  i1 = ilp1;
7016  end1 = row1->nlpcols;
7017  lpcols = TRUE;
7018  }
7019 
7020  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7021  * case 5) will fail the while-condition
7022  */
7023  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7024  {
7025  assert(row1->cols[i1]->index == row1colsidx[i1]);
7026  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7027  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7028  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7029  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7030 
7031  /* current column in row 1 is the same as the current LP column in row 2 */
7032  if( row1colsidx[i1] == row2colsidx[ilp2] )
7033  {
7034  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7035  ++i1;
7036  ++ilp2;
7037  }
7038  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7039  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7040  {
7041  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7042  ++i1;
7043  ++inlp2;
7044  }
7045  /* increase smallest counter */
7046  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7047  {
7048  if( row1colsidx[i1] < row2colsidx[ilp2] )
7049  ++i1;
7050  else
7051  ++ilp2;
7052  }
7053  else
7054  {
7055  if( row1colsidx[i1] < row2colsidx[inlp2] )
7056  ++i1;
7057  else
7058  ++inlp2;
7059  }
7060  }
7061 
7062  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7063  * the two rows
7064  */
7065  if( i1 < end1 )
7066  {
7067  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7068  if( ilp2 == row2->nlpcols )
7069  {
7070  i2 = inlp2;
7071  end2 = row2->len;
7072  lpcols = FALSE;
7073  }
7074  else
7075  {
7076  assert(inlp2 == row2->len);
7077 
7078  i2 = ilp2;
7079  end2 = row2->nlpcols;
7080  }
7081 
7082  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7083  while( i1 < end1 && i2 < end2 )
7084  {
7085  assert(row1->cols[i1]->index == row1colsidx[i1]);
7086  assert(row2->cols[i2]->index == row2colsidx[i2]);
7087  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7088 
7089  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7090  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7091  {
7092  scalarprod += row1->vals[i1] * row2->vals[i2];
7093  ++i1;
7094  ++i2;
7095  }
7096  /* increase smallest counter */
7097  else if( row1colsidx[i1] < row2colsidx[i2] )
7098  ++i1;
7099  else
7100  ++i2;
7101  }
7102  }
7103  }
7104 
7105  return scalarprod;
7106 }
7107 
7108 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7109 static
7111  SCIP_ROW* row1, /**< first LP row */
7112  SCIP_ROW* row2 /**< second LP row */
7113  )
7114 {
7115  int prod;
7116  int* row1colsidx;
7117  int* row2colsidx;
7118  int i1;
7119  int i2;
7120 
7121  assert(row1 != NULL);
7122  assert(row2 != NULL);
7123 
7124  /* Sort the column indices of both rows.
7125  *
7126  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7127  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7128  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7129  * for both or one of the non-LP columns for both.
7130  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7131  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7132  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7133  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7134  *
7135  * We distinguish the following cases:
7136  *
7137  * 1) both rows have no unlinked columns
7138  * -> we just check the LP partitions
7139  *
7140  * 2) exactly one row is completely unlinked, the other one is completely linked
7141  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7142  * (thus all common LP columns are regarded)
7143  *
7144  * 3) we have unlinked and LP columns in both rows
7145  * -> we need to compare four partitions at once
7146  *
7147  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7148  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7149  * other row
7150  *
7151  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7152  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7153  *
7154  * 5) both rows are completely unlinked
7155  * -> we need to compare two partitions: both complete rows
7156  */
7157  SCIProwSort(row1);
7158  assert(row1->lpcolssorted);
7159  assert(row1->nonlpcolssorted);
7160  SCIProwSort(row2);
7161  assert(row2->lpcolssorted);
7162  assert(row2->nonlpcolssorted);
7163 
7164  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7165  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7166 
7167  row1colsidx = row1->cols_index;
7168  row2colsidx = row2->cols_index;
7169 
7170 #ifndef NDEBUG
7171  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7172  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7173  {
7174  i1 = 0;
7175  i2 = row2->nlpcols;
7176  while( i1 < row1->nlpcols && i2 < row2->len )
7177  {
7178  assert(row1->cols[i1] != row2->cols[i2]);
7179  if( row1->cols[i1]->index < row2->cols[i2]->index )
7180  ++i1;
7181  else
7182  {
7183  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7184  ++i2;
7185  }
7186  }
7187  assert(i1 == row1->nlpcols || i2 == row2->len);
7188 
7189  i1 = row1->nlpcols;
7190  i2 = 0;
7191  while( i1 < row1->len && i2 < row2->nlpcols )
7192  {
7193  assert(row1->cols[i1] != row2->cols[i2]);
7194  if( row1->cols[i1]->index < row2->cols[i2]->index )
7195  ++i1;
7196  else
7197  {
7198  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7199  ++i2;
7200  }
7201  }
7202  assert(i1 == row1->len || i2 == row2->nlpcols);
7203  }
7204 #endif
7205 
7206  /* The "easy" cases 1) and 2) */
7207  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7208  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7209  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7210  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7211  {
7212  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7213  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7214 
7215  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7216  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7217  */
7218  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7219  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7220  prod = 0;
7221 
7222  /* calculate the scalar product */
7223  while( i1 >= 0 && i2 >= 0 )
7224  {
7225  assert(row1->cols[i1]->index == row1colsidx[i1]);
7226  assert(row2->cols[i2]->index == row2colsidx[i2]);
7227  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7228  if( row1colsidx[i1] < row2colsidx[i2] )
7229  --i2;
7230  else if( row1colsidx[i1] > row2colsidx[i2] )
7231  --i1;
7232  else
7233  {
7234  ++prod;
7235  --i1;
7236  --i2;
7237  }
7238  }
7239  }
7240  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7241  else
7242  {
7243  SCIP_Bool lpcols;
7244  int ilp1;
7245  int inlp1;
7246  int ilp2;
7247  int inlp2;
7248  int end1;
7249  int end2;
7250 
7251  prod = 0;
7252  ilp1 = 0;
7253  ilp2 = 0;
7254 
7255  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7256  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7257  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7258 
7259  /* handle the case of four partitions (case 3) until one partition is finished;
7260  * cases 4a), 4b), and 5) will fail the while-condition
7261  */
7262  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7263  {
7264  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7265  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7266  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7267  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7268  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7269  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7270  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7271  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7272 
7273  /* rows have the same linked LP columns */
7274  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7275  {
7276  ++prod;
7277  ++ilp1;
7278  ++ilp2;
7279  }
7280  /* LP column of row1 is the same as unlinked column of row2 */
7281  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7282  {
7283  ++prod;
7284  ++ilp1;
7285  ++inlp2;
7286  }
7287  /* unlinked column of row1 is the same as LP column of row2 */
7288  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7289  {
7290  ++prod;
7291  ++inlp1;
7292  ++ilp2;
7293  }
7294  /* two unlinked LP columns are the same */
7295  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7296  {
7297  ++prod;
7298  ++inlp1;
7299  ++inlp2;
7300  }
7301  /* increase smallest counter */
7302  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7303  {
7304  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7305  {
7306  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7307  ++ilp1;
7308  else
7309  ++ilp2;
7310  }
7311  else
7312  {
7313  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7314  ++ilp1;
7315  else
7316  ++inlp2;
7317  }
7318  }
7319  else
7320  {
7321  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7322  {
7323  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7324  ++inlp1;
7325  else
7326  ++ilp2;
7327  }
7328  else
7329  {
7330  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7331  ++inlp1;
7332  else
7333  ++inlp2;
7334  }
7335  }
7336  }
7337 
7338  /* One partition was completely handled, we just have to handle the three remaining partitions:
7339  * the remaining partition of this row and the two partitions of the other row.
7340  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7341  */
7342  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7343  {
7344  int tmpilp;
7345  int tmpinlp;
7346 
7347  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7348 
7349  SCIPswapPointers((void**) &row1, (void**) &row2);
7350  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7351  tmpilp = ilp1;
7352  tmpinlp = inlp1;
7353  ilp1 = ilp2;
7354  inlp1 = inlp2;
7355  ilp2 = tmpilp;
7356  inlp2 = tmpinlp;
7357  }
7358 
7359  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7360  * -> this merges cases 4a) and 4b)
7361  */
7362  if( ilp1 == row1->nlpcols )
7363  {
7364  i1 = inlp1;
7365  end1 = row1->len;
7366  lpcols = FALSE;
7367  }
7368  else
7369  {
7370  assert(inlp1 == row1->len);
7371 
7372  i1 = ilp1;
7373  end1 = row1->nlpcols;
7374  lpcols = TRUE;
7375  }
7376 
7377  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7378  * case 5) will fail the while-condition
7379  */
7380  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7381  {
7382  assert(row1->cols[i1]->index == row1colsidx[i1]);
7383  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7384  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7385  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7386  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7387 
7388  /* current column in row 1 is the same as the current LP column in row 2 */
7389  if( row1colsidx[i1] == row2colsidx[ilp2] )
7390  {
7391  ++prod;
7392  ++i1;
7393  ++ilp2;
7394  }
7395  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7396  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7397  {
7398  ++prod;
7399  ++i1;
7400  ++inlp2;
7401  }
7402  /* increase smallest counter */
7403  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7404  {
7405  if( row1colsidx[i1] < row2colsidx[ilp2] )
7406  ++i1;
7407  else
7408  ++ilp2;
7409  }
7410  else
7411  {
7412  if( row1colsidx[i1] < row2colsidx[inlp2] )
7413  ++i1;
7414  else
7415  ++inlp2;
7416  }
7417  }
7418 
7419  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7420  * the two rows
7421  */
7422  if( i1 < end1 )
7423  {
7424  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7425  if( ilp2 == row2->nlpcols )
7426  {
7427  i2 = inlp2;
7428  end2 = row2->len;
7429  lpcols = FALSE;
7430  }
7431  else
7432  {
7433  assert(inlp2 == row2->len);
7434 
7435  i2 = ilp2;
7436  end2 = row2->nlpcols;
7437  }
7438 
7439  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7440  while( i1 < end1 && i2 < end2 )
7441  {
7442  assert(row1->cols[i1]->index == row1colsidx[i1]);
7443  assert(row2->cols[i2]->index == row2colsidx[i2]);
7444  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7445 
7446  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7447  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7448  {
7449  ++prod;
7450  ++i1;
7451  ++i2;
7452  }
7453  /* increase smallest counter */
7454  else if( row1colsidx[i1] < row2colsidx[i2] )
7455  ++i1;
7456  else
7457  ++i2;
7458  }
7459  }
7460  }
7461 
7462  return prod;
7463 }
7464 
7465 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7466  * p = |v*w|/(|v|*|w|);
7467  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7468  */
7470  SCIP_ROW* row1, /**< first LP row */
7471  SCIP_ROW* row2, /**< second LP row */
7472  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7473  )
7474 {
7475  SCIP_Real parallelism;
7476  SCIP_Real scalarprod;
7477 
7478  switch( orthofunc )
7479  {
7480  case 'e':
7481  scalarprod = SCIProwGetScalarProduct(row1, row2);
7482  if( scalarprod == 0.0 )
7483  {
7484  parallelism = 0.0;
7485  break;
7486  }
7487 
7488  if( SCIProwGetNorm(row1) == 0.0 )
7489  {
7490  /* In theory, this should not happen if the scalarproduct is not zero
7491  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7492  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7493  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7494  */
7495  int i;
7496  for( i = 0; i < row1->len; ++i )
7497  if( row1->cols[i]->lppos >= 0 )
7498  row1->sqrnorm += SQR(row1->vals[i]);
7499  assert(SCIProwGetNorm(row1) != 0.0);
7500  }
7501 
7502  if( SCIProwGetNorm(row2) == 0.0 )
7503  {
7504  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7505  int i;
7506  for( i = 0; i < row2->len; ++i )
7507  if( row2->cols[i]->lppos >= 0 )
7508  row2->sqrnorm += SQR(row2->vals[i]);
7509  assert(SCIProwGetNorm(row2) != 0.0);
7510  }
7511 
7512  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7513  break;
7514 
7515  case 'd':
7516  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7517  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7518  break;
7519 
7520  default:
7521  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7522  SCIPABORT();
7523  parallelism = 0.0; /*lint !e527*/
7524  }
7525 
7526  return parallelism;
7527 }
7528 
7529 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7530  * o = 1 - |v*w|/(|v|*|w|);
7531  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7532  */
7534  SCIP_ROW* row1, /**< first LP row */
7535  SCIP_ROW* row2, /**< second LP row */
7536  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7537  )
7538 {
7539  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7540 }
7541 
7542 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7543  * function, if the value is 0, it is orthogonal to the objective function
7544  */
7546  SCIP_ROW* row, /**< LP row */
7547  SCIP_SET* set, /**< global SCIP settings */
7548  SCIP_LP* lp /**< current LP data */
7549  )
7550 {
7551  SCIP_Real prod;
7552  SCIP_Real parallelism;
7553 
7554  assert(row != NULL);
7555  assert(lp != NULL);
7556 
7557  if( lp->objsqrnormunreliable )
7558  SCIPlpRecalculateObjSqrNorm(set, lp);
7559 
7560  assert(!lp->objsqrnormunreliable);
7561  assert(lp->objsqrnorm >= 0.0);
7562 
7563  checkRowSqrnorm(row);
7564  checkRowObjprod(row);
7565 
7566  prod = row->sqrnorm * lp->objsqrnorm;
7567 
7568  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7569  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7570  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7571  parallelism = MIN(parallelism, 1.0);
7572  parallelism = MAX(parallelism, 0.0);
7573 
7574  return parallelism;
7575 }
7576 
7577 /** includes event handler with given data in row's event filter */
7579  SCIP_ROW* row, /**< row */
7580  BMS_BLKMEM* blkmem, /**< block memory */
7581  SCIP_SET* set, /**< global SCIP settings */
7582  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7583  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7584  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7585  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7586  )
7587 {
7588  assert(row != NULL);
7589  assert(row->eventfilter != NULL);
7590  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7591  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7592 
7593  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7594  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7595 
7596  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7597 
7598  return SCIP_OKAY;
7599 }
7600 
7601 /** deletes event handler with given data from row's event filter */
7603  SCIP_ROW* row, /**< row */
7604  BMS_BLKMEM* blkmem, /**< block memory */
7605  SCIP_SET* set, /**< global SCIP settings */
7606  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7607  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7608  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7609  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7610  )
7611 {
7612  assert(row != NULL);
7613  assert(row->eventfilter != NULL);
7614 
7615  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7616 
7617  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7618 
7619  return SCIP_OKAY;
7620 }
7621 
7622 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7624  SCIP_ROW* row, /**< LP row */
7625  SCIP_STAT* stat /**< problem statistics */
7626  )
7627 {
7628  assert(row != NULL);
7629  assert(stat != NULL);
7630  assert(stat->nnodes > 0);
7631 
7632  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7633  row->obsoletenode = stat->nnodes;
7634 }
7635 
7636 /*
7637  * LP solver data update
7638  */
7639 
7640 /** resets column data to represent a column not in the LP solver */
7641 static
7643  SCIP_COL* col /**< column to be marked deleted */
7644  )
7645 {
7646  assert(col != NULL);
7647 
7648  col->lpipos = -1;
7649  col->primsol = 0.0;
7650  col->redcost = SCIP_INVALID;
7651  col->farkascoef = SCIP_INVALID;
7652  col->sbdown = SCIP_INVALID;
7653  col->sbup = SCIP_INVALID;
7654  col->sbdownvalid = FALSE;
7655  col->sbupvalid = FALSE;
7656  col->validredcostlp = -1;
7657  col->validfarkaslp = -1;
7658  col->sbitlim = -1;
7659  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7660 }
7661 
7662 /** applies all cached column removals to the LP solver */
7663 static
7665  SCIP_LP* lp /**< current LP data */
7666  )
7667 {
7668  assert(lp != NULL);
7669  assert(lp->lpifirstchgcol <= lp->nlpicols);
7670  assert(lp->lpifirstchgcol <= lp->ncols);
7671 
7672  /* find the first column to change */
7673  while( lp->lpifirstchgcol < lp->nlpicols
7674  && lp->lpifirstchgcol < lp->ncols
7675  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7676  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7677  {
7678  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7679  lp->lpifirstchgcol++;
7680  }
7681 
7682  /* shrink LP to the part which didn't change */
7683  if( lp->lpifirstchgcol < lp->nlpicols )
7684  {
7685  int i;
7686 
7687  assert(!lp->diving);
7688  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7689  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7690  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7691  {
7692  markColDeleted(lp->lpicols[i]);
7693  }
7694  lp->nlpicols = lp->lpifirstchgcol;
7695  lp->flushdeletedcols = TRUE;
7696  lp->updateintegrality = TRUE;
7697 
7698  /* mark the LP unsolved */
7699  lp->solved = FALSE;
7700  lp->primalfeasible = FALSE;
7701  lp->primalchecked = FALSE;
7702  lp->lpobjval = SCIP_INVALID;
7704  }
7705  assert(lp->nlpicols == lp->lpifirstchgcol);
7706 
7707  return SCIP_OKAY;
7708 }
7709 
7710 /** computes for the given column the lower and upper bound that should be flushed into the LP
7711  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7712  * the bounds are explicitly added to the LP in any case
7713  */
7714 static
7716  SCIP_LP* lp, /**< current LP data */
7717  SCIP_SET* set, /**< global SCIP settings */
7718  SCIP_COL* col, /**< column to compute bounds for */
7719  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7720  SCIP_Real* lb, /**< pointer to store the new lower bound */
7721  SCIP_Real* ub /**< pointer to store the new upper bound */
7722  )
7723 {
7724  assert(lp != NULL);
7725  assert(set != NULL);
7726  assert(col != NULL);
7727  assert(lb != NULL);
7728  assert(ub != NULL);
7729 
7730  /* get the correct new lower bound:
7731  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7732  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7733  */
7734  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7735  (*lb) = -lpiinf;
7736  else
7737  (*lb) = col->lb;
7738  /* get the correct new upper bound:
7739  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7740  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7741  */
7742  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7743  (*ub) = lpiinf;
7744  else
7745  (*ub) = col->ub;
7746 }
7747 
7748 /** applies all cached column additions to the LP solver */
7749 static
7751  SCIP_LP* lp, /**< current LP data */
7752  BMS_BLKMEM* blkmem, /**< block memory */
7753  SCIP_SET* set, /**< global SCIP settings */
7754  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7755  )
7756 {
7757  SCIP_Real* obj;
7758  SCIP_Real* lb;
7759  SCIP_Real* ub;
7760  int* beg;
7761  int* ind;
7762  SCIP_Real* val;
7763  char** name;
7764  SCIP_COL* col;
7765  SCIP_Real lpiinf;
7766  int c;
7767  int pos;
7768  int nnonz;
7769  int naddcols;
7770  int naddcoefs;
7771  int i;
7772  int lpipos;
7773 
7774  assert(lp != NULL);
7775  assert(lp->lpifirstchgcol == lp->nlpicols);
7776  assert(blkmem != NULL);
7777  assert(set != NULL);
7778 
7779  /* if there are no columns to add, we are ready */
7780  if( lp->ncols == lp->nlpicols )
7781  return SCIP_OKAY;
7782 
7783  /* add the additional columns */
7784  assert(!lp->diving);
7785  assert(lp->ncols > lp->nlpicols);
7786  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
7787 
7788  /* get the solver's infinity value */
7789  lpiinf = SCIPlpiInfinity(lp->lpi);
7790 
7791  /* count the (maximal) number of added coefficients, calculate the number of added columns */
7792  naddcols = lp->ncols - lp->nlpicols;
7793  naddcoefs = 0;
7794  for( c = lp->nlpicols; c < lp->ncols; ++c )
7795  naddcoefs += lp->cols[c]->len;
7796  assert(naddcols > 0);
7797 
7798  /* get temporary memory for changes */
7799  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
7800  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
7801  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
7802  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
7803  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
7804  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
7805  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
7806 
7807  /* fill temporary memory with column data */
7808  nnonz = 0;
7809  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
7810  {
7811  col = lp->cols[c];
7812  assert(col != NULL);
7813  assert(col->var != NULL);
7814  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
7815  assert(SCIPvarGetCol(col->var) == col);
7816  assert(col->lppos == c);
7817  assert(nnonz + col->nlprows <= naddcoefs);
7818 
7819  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
7820  debugColPrint(set, col);
7821 
7822  /* Because the column becomes a member of the LP solver, it now can take values
7823  * different from zero. That means, we have to include the column in the corresponding
7824  * row vectors.
7825  */
7826  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
7827 
7828  lp->lpicols[c] = col;
7829  col->lpipos = c;
7830  col->primsol = SCIP_INVALID;
7831  col->redcost = SCIP_INVALID;
7832  col->farkascoef = SCIP_INVALID;
7833  col->sbdown = SCIP_INVALID;
7834  col->sbup = SCIP_INVALID;
7835  col->sbdownvalid = FALSE;
7836  col->sbupvalid = FALSE;
7837  col->validredcostlp = -1;
7838  col->validfarkaslp = -1;
7839  col->sbitlim = -1;
7840  col->objchanged = FALSE;
7841  col->lbchanged = FALSE;
7842  col->ubchanged = FALSE;
7843  col->coefchanged = FALSE;
7844  obj[pos] = col->obj;
7845 
7846  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
7847  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
7848 
7849  beg[pos] = nnonz;
7850  name[pos] = (char*)SCIPvarGetName(col->var);
7851 
7852  col->flushedobj = obj[pos];
7853  col->flushedlb = lb[pos];
7854  col->flushedub = ub[pos];
7855 
7856  for( i = 0; i < col->nlprows; ++i )
7857  {
7858  assert(col->rows[i] != NULL);
7859  lpipos = col->rows[i]->lpipos;
7860  if( lpipos >= 0 )
7861  {
7862  assert(lpipos < lp->nrows);
7863  assert(nnonz < naddcoefs);
7864  ind[nnonz] = lpipos;
7865  val[nnonz] = col->vals[i];
7866  nnonz++;
7867  }
7868  }
7869 #ifndef NDEBUG
7870  for( i = col->nlprows; i < col->len; ++i )
7871  {
7872  assert(col->rows[i] != NULL);
7873  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
7874  }
7875 #endif
7876  }
7877 
7878  /* call LP interface */
7879  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
7880  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
7881  lp->nlpicols = lp->ncols;
7882  lp->lpifirstchgcol = lp->nlpicols;
7883 
7884  /* free temporary memory */
7885  SCIPsetFreeBufferArray(set, &name);
7886  SCIPsetFreeBufferArray(set, &val);
7887  SCIPsetFreeBufferArray(set, &ind);
7888  SCIPsetFreeBufferArray(set, &beg);
7889  SCIPsetFreeBufferArray(set, &ub);
7890  SCIPsetFreeBufferArray(set, &lb);
7891  SCIPsetFreeBufferArray(set, &obj);
7892 
7893  lp->flushaddedcols = TRUE;
7894  lp->updateintegrality = TRUE;
7895 
7896  /* mark the LP unsolved */
7897  lp->solved = FALSE;
7898  lp->dualfeasible = FALSE;
7899  lp->dualchecked = FALSE;
7900  lp->lpobjval = SCIP_INVALID;
7902 
7903  return SCIP_OKAY;
7904 }
7905 
7906 /** resets row data to represent a row not in the LP solver */
7907 static
7909  SCIP_ROW* row /**< row to be marked deleted */
7910  )
7911 {
7912  assert(row != NULL);
7913 
7914  row->lpipos = -1;
7915  row->dualsol = 0.0;
7916  row->activity = SCIP_INVALID;
7917  row->dualfarkas = 0.0;
7918  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
7919  row->validactivitylp = -1;
7920 }
7921 
7922 /** applies all cached row removals to the LP solver */
7923 static
7925  SCIP_LP* lp, /**< current LP data */
7926  BMS_BLKMEM* blkmem, /**< block memory */
7927  SCIP_SET* set /**< global SCIP settings */
7928  )
7929 {
7930  assert(lp != NULL);
7931  assert(lp->lpifirstchgrow <= lp->nlpirows);
7932  assert(lp->lpifirstchgrow <= lp->nrows);
7933 
7934  /* find the first row to change */
7935  while( lp->lpifirstchgrow < lp->nlpirows
7936  && lp->lpifirstchgrow < lp->nrows
7937  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
7938  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
7939  {
7940  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
7941  lp->lpifirstchgrow++;
7942  }
7943 
7944  /* shrink LP to the part which didn't change */
7945  if( lp->lpifirstchgrow < lp->nlpirows )
7946  {
7947  int i;
7948 
7949  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
7950  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
7951  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
7952  {
7953  markRowDeleted(lp->lpirows[i]);
7954  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
7955  }
7956  lp->nlpirows = lp->lpifirstchgrow;
7957  lp->flushdeletedrows = TRUE;
7958 
7959  /* mark the LP unsolved */
7960  lp->solved = FALSE;
7961  lp->dualfeasible = FALSE;
7962  lp->dualchecked = FALSE;
7963  lp->lpobjval = SCIP_INVALID;
7965  }
7966  assert(lp->nlpirows == lp->lpifirstchgrow);
7967 
7968  return SCIP_OKAY;
7969 }
7970 
7971 /** applies all cached row additions and removals to the LP solver */
7972 static
7974  SCIP_LP* lp, /**< current LP data */
7975  BMS_BLKMEM* blkmem, /**< block memory */
7976  SCIP_SET* set, /**< global SCIP settings */
7977  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7978  )
7979 {
7980  SCIP_Real* lhs;
7981  SCIP_Real* rhs;
7982  int* beg;
7983  int* ind;
7984  SCIP_Real* val;
7985  char** name;
7986  SCIP_ROW* row;
7987  SCIP_Real lpiinf;
7988  int r;
7989  int pos;
7990  int nnonz;
7991  int naddrows;
7992  int naddcoefs;
7993  int i;
7994  int lpipos;
7995 
7996  assert(lp != NULL);
7997  assert(lp->lpifirstchgrow == lp->nlpirows);
7998  assert(blkmem != NULL);
7999 
8000  /* if there are no rows to add, we are ready */
8001  if( lp->nrows == lp->nlpirows )
8002  return SCIP_OKAY;
8003 
8004  /* add the additional rows */
8005  assert(lp->nrows > lp->nlpirows);
8006  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8007 
8008  /* get the solver's infinity value */
8009  lpiinf = SCIPlpiInfinity(lp->lpi);
8010 
8011  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8012  naddrows = lp->nrows - lp->nlpirows;
8013  naddcoefs = 0;
8014  for( r = lp->nlpirows; r < lp->nrows; ++r )
8015  naddcoefs += lp->rows[r]->len;
8016  assert(naddrows > 0);
8017 
8018  /* get temporary memory for changes */
8019  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8020  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8021  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8022  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8023  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8024  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8025 
8026  /* fill temporary memory with row data */
8027  nnonz = 0;
8028  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8029  {
8030  row = lp->rows[r];
8031  assert(row != NULL);
8032  assert(row->lppos == r);
8033  assert(nnonz + row->nlpcols <= naddcoefs);
8034 
8035  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8036  debugRowPrint(set, row);
8037 
8038  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8039  * different from zero. That means, we have to include the row in the corresponding
8040  * column vectors.
8041  */
8042  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8043 
8044  SCIProwCapture(row);
8045  lp->lpirows[r] = row;
8046  row->lpipos = r;
8047  row->dualsol = SCIP_INVALID;
8048  row->activity = SCIP_INVALID;
8049  row->dualfarkas = SCIP_INVALID;
8050  row->validactivitylp = -1;
8051  row->lhschanged = FALSE;
8052  row->rhschanged = FALSE;
8053  row->coefchanged = FALSE;
8054  if( SCIPsetIsInfinity(set, -row->lhs) )
8055  lhs[pos] = -lpiinf;
8056  else
8057  lhs[pos] = row->lhs - row->constant;
8058  if( SCIPsetIsInfinity(set, row->rhs) )
8059  rhs[pos] = lpiinf;
8060  else
8061  rhs[pos] = row->rhs - row->constant;
8062  beg[pos] = nnonz;
8063  name[pos] = row->name;
8064 
8065  row->flushedlhs = lhs[pos];
8066  row->flushedrhs = rhs[pos];
8067 
8068  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8069  for( i = 0; i < row->nlpcols; ++i )
8070  {
8071  assert(row->cols[i] != NULL);
8072  lpipos = row->cols[i]->lpipos;
8073  if( lpipos >= 0 )
8074  {
8075  assert(lpipos < lp->ncols);
8076  assert(nnonz < naddcoefs);
8077  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8078  ind[nnonz] = lpipos;
8079  val[nnonz] = row->vals[i];
8080  nnonz++;
8081  }
8082  }
8083  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8084 #ifndef NDEBUG
8085  for( i = row->nlpcols; i < row->len; ++i )
8086  {
8087  assert(row->cols[i] != NULL);
8088  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8089  }
8090 #endif
8091  }
8092 
8093  /* call LP interface */
8094  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8095  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8096  lp->nlpirows = lp->nrows;
8097  lp->lpifirstchgrow = lp->nlpirows;
8098 
8099  /* free temporary memory */
8100  SCIPsetFreeBufferArray(set, &name);
8101  SCIPsetFreeBufferArray(set, &val);
8102  SCIPsetFreeBufferArray(set, &ind);
8103  SCIPsetFreeBufferArray(set, &beg);
8104  SCIPsetFreeBufferArray(set, &rhs);
8105  SCIPsetFreeBufferArray(set, &lhs);
8106 
8107  lp->flushaddedrows = TRUE;
8108 
8109  /* mark the LP unsolved */
8110  lp->solved = FALSE;
8111  lp->primalfeasible = FALSE;
8112  lp->primalchecked = FALSE;
8113  lp->lpobjval = SCIP_INVALID;
8115 
8116  return SCIP_OKAY;
8117 }
8118 
8119 /** applies all cached column bound and objective changes to the LP */
8120 static
8122  SCIP_LP* lp, /**< current LP data */
8123  SCIP_SET* set /**< global SCIP settings */
8124  )
8125 {
8126 #ifndef NDEBUG
8127  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8128 #endif
8129  SCIP_COL* col;
8130  int* objind;
8131  int* bdind;
8132  SCIP_Real* obj;
8133  SCIP_Real* lb;
8134  SCIP_Real* ub;
8135  SCIP_Real lpiinf;
8136  int nobjchg;
8137  int nbdchg;
8138  int i;
8139 
8140  assert(lp != NULL);
8141 
8142  if( lp->nchgcols == 0 )
8143  return SCIP_OKAY;
8144 
8145  /* get the solver's infinity value */
8146  lpiinf = SCIPlpiInfinity(lp->lpi);
8147 
8148  /* get temporary memory for changes */
8149  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8150  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8151  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8152  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8153  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8154 
8155  /* collect all cached bound and objective changes */
8156  nobjchg = 0;
8157  nbdchg = 0;
8158  for( i = 0; i < lp->nchgcols; ++i )
8159  {
8160  col = lp->chgcols[i];
8161  assert(col != NULL);
8162  assert(col->var != NULL);
8163  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8164  assert(SCIPvarGetCol(col->var) == col);
8165 
8166  if( col->lpipos >= 0 )
8167  {
8168 #ifndef NDEBUG
8169  /* do not check consistency of data with LPI in case of LPI=none */
8170  if( !lpinone )
8171  {
8172  SCIP_Real lpiobj;
8173  SCIP_Real lpilb;
8174  SCIP_Real lpiub;
8175 
8176  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8177  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8178  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8179  assert((SCIPsetIsInfinity(set, lpilb) && SCIPsetIsInfinity(set, col->flushedlb))
8180  || (!SCIPsetIsInfinity(set, lpilb) && !SCIPsetIsInfinity(set, col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8181  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8182  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8183  }
8184 #endif
8185 
8186  if( col->objchanged )
8187  {
8188  SCIP_Real newobj;
8189 
8190  newobj = col->obj;
8191  if( col->flushedobj != newobj ) /*lint !e777*/
8192  {
8193  assert(nobjchg < lp->ncols);
8194  objind[nobjchg] = col->lpipos;
8195  obj[nobjchg] = newobj;
8196  nobjchg++;
8197  col->flushedobj = newobj;
8198  }
8199  col->objchanged = FALSE;
8200  }
8201 
8202  if( col->lbchanged || col->ubchanged )
8203  {
8204  SCIP_Real newlb;
8205  SCIP_Real newub;
8206 
8207  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8208  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8209 
8210  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8211  {
8212  assert(nbdchg < lp->ncols);
8213  bdind[nbdchg] = col->lpipos;
8214  lb[nbdchg] = newlb;
8215  ub[nbdchg] = newub;
8216  nbdchg++;
8217  col->flushedlb = newlb;
8218  col->flushedub = newub;
8219  }
8220  col->lbchanged = FALSE;
8221  col->ubchanged = FALSE;
8222  }
8223  }
8224  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8225  }
8226 
8227  /* change objective values in LP */
8228  if( nobjchg > 0 )
8229  {
8230  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8231  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8232 
8233  /* mark the LP unsolved */
8234  lp->solved = FALSE;
8235  lp->dualfeasible = FALSE;
8236  lp->dualchecked = FALSE;
8237  lp->lpobjval = SCIP_INVALID;
8239  }
8240 
8241  /* change bounds in LP */
8242  if( nbdchg > 0 )
8243  {
8244  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8245  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8246 
8247  /* mark the LP unsolved */
8248  lp->solved = FALSE;
8249  lp->primalfeasible = FALSE;
8250  lp->primalchecked = FALSE;
8251  lp->lpobjval = SCIP_INVALID;
8253  }
8254 
8255  lp->nchgcols = 0;
8256 
8257  /* free temporary memory */
8258  SCIPsetFreeBufferArray(set, &ub);
8259  SCIPsetFreeBufferArray(set, &lb);
8260  SCIPsetFreeBufferArray(set, &bdind);
8261  SCIPsetFreeBufferArray(set, &obj);
8262  SCIPsetFreeBufferArray(set, &objind);
8263 
8264  return SCIP_OKAY;
8265 }
8266 
8267 /** applies all cached row side changes to the LP */
8268 static
8270  SCIP_LP* lp, /**< current LP data */
8271  SCIP_SET* set /**< global SCIP settings */
8272  )
8273 {
8274 #ifndef NDEBUG
8275  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8276 #endif
8277  SCIP_ROW* row;
8278  int* ind;
8279  SCIP_Real* lhs;
8280  SCIP_Real* rhs;
8281  SCIP_Real lpiinf;
8282  int i;
8283  int nchg;
8284 
8285  assert(lp != NULL);
8286 
8287  if( lp->nchgrows == 0 )
8288  return SCIP_OKAY;
8289 
8290  /* get the solver's infinity value */
8291  lpiinf = SCIPlpiInfinity(lp->lpi);
8292 
8293  /* get temporary memory for changes */
8294  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8295  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8296  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8297 
8298  /* collect all cached left and right hand side changes */
8299  nchg = 0;
8300  for( i = 0; i < lp->nchgrows; ++i )
8301  {
8302  row = lp->chgrows[i];
8303  assert(row != NULL);
8304 
8305  if( row->lpipos >= 0 )
8306  {
8307 #ifndef NDEBUG
8308  /* do not check consistency of data with LPI in case of LPI=none */
8309  if( !lpinone )
8310  {
8311  SCIP_Real lpilhs;
8312  SCIP_Real lpirhs;
8313 
8314  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8315  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8316  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8317  }
8318 #endif
8319  if( row->lhschanged || row->rhschanged )
8320  {
8321  SCIP_Real newlhs;
8322  SCIP_Real newrhs;
8323 
8324  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8325  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8326  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8327  {
8328  assert(nchg < lp->nrows);
8329  ind[nchg] = row->lpipos;
8330  lhs[nchg] = newlhs;
8331  rhs[nchg] = newrhs;
8332  nchg++;
8333  row->flushedlhs = newlhs;
8334  row->flushedrhs = newrhs;
8335  }
8336  row->lhschanged = FALSE;
8337  row->rhschanged = FALSE;
8338  }
8339  }
8340  }
8341 
8342  /* change left and right hand sides in LP */
8343  if( nchg > 0 )
8344  {
8345  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8346  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8347 
8348  /* mark the LP unsolved */
8349  lp->solved = FALSE;
8350  lp->primalfeasible = FALSE;
8351  lp->primalchecked = FALSE;
8352  lp->lpobjval = SCIP_INVALID;
8354  }
8355 
8356  lp->nchgrows = 0;
8357 
8358  /* free temporary memory */
8359  SCIPsetFreeBufferArray(set, &rhs);
8360  SCIPsetFreeBufferArray(set, &lhs);
8361  SCIPsetFreeBufferArray(set, &ind);
8362 
8363  return SCIP_OKAY;
8364 }
8365 
8366 /** copy integrality information to the LP */
8367 static
8369  SCIP_LP* lp, /**< current LP data */
8370  SCIP_SET* set /**< global SCIP settings */
8371  )
8372 {
8373  int i;
8374  int nintegers;
8375  int* integerInfo;
8376  SCIP_VAR* var;
8377 
8378  assert(lp != NULL);
8379 
8380  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8381 
8382  /* count total number of integralities */
8383  nintegers = 0;
8384 
8385  for( i = 0; i < lp->ncols; ++i )
8386  {
8387  var = SCIPcolGetVar(lp->cols[i]);
8388  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8389  {
8390  integerInfo[i] = 1;
8391  ++nintegers;
8392  }
8393  else
8394  integerInfo[i] = 0;
8395  }
8396 
8397  /* only pass integrality information if integer variables are present */
8398  if( nintegers > 0 )
8399  {
8400  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8401  }
8402  else
8403  {
8405  }
8406 
8407  SCIPsetFreeBufferArray(set, &integerInfo);
8408 
8409  /* mark integralities to be updated */
8410  lp->updateintegrality = FALSE;
8411 
8412  return SCIP_OKAY;
8413 }
8414 
8415 /** applies all cached changes to the LP solver */
8417  SCIP_LP* lp, /**< current LP data */
8418  BMS_BLKMEM* blkmem, /**< block memory */
8419  SCIP_SET* set, /**< global SCIP settings */
8420  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8421  )
8422 {
8423  assert(lp != NULL);
8424  assert(blkmem != NULL);
8425 
8426  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",
8427  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8428 
8429  if( !lp->flushed )
8430  {
8431  lp->flushdeletedcols = FALSE;
8432  lp->flushaddedcols = FALSE;
8433  lp->flushdeletedrows = FALSE;
8434  lp->flushaddedrows = FALSE;
8435 
8436  SCIP_CALL( lpFlushDelCols(lp) );
8437  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8438  SCIP_CALL( lpFlushChgCols(lp, set) );
8439  SCIP_CALL( lpFlushChgRows(lp, set) );
8440  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8441  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8442 
8443  lp->flushed = TRUE;
8444 
8445  checkLinks(lp);
8446  }
8447 
8448  assert(lp->nlpicols == lp->ncols);
8449  assert(lp->lpifirstchgcol == lp->nlpicols);
8450  assert(lp->nlpirows == lp->nrows);
8451  assert(lp->lpifirstchgrow == lp->nlpirows);
8452  assert(lp->nchgcols == 0);
8453  assert(lp->nchgrows == 0);
8454 #ifndef NDEBUG
8455  {
8456  int ncols;
8457  int nrows;
8458 
8459  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8460  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8461  assert(ncols == lp->ncols);
8462  assert(nrows == lp->nrows);
8463  }
8464 #endif
8465 
8466  return SCIP_OKAY;
8467 }
8468 
8469 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8471  SCIP_LP* lp, /**< current LP data */
8472  SCIP_SET* set /**< global SCIP settings */
8473  )
8474 {
8475 #ifndef NDEBUG
8476  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8477 #endif
8478  int i;
8479 
8480  assert(lp != NULL);
8481 
8482 #ifndef NDEBUG
8483  /* check, if there are really no column or row deletions or coefficient changes left */
8484  while( lp->lpifirstchgcol < lp->nlpicols
8485  && lp->lpifirstchgcol < lp->ncols
8486  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8487  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8488  {
8489  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8490  lp->lpifirstchgcol++;
8491  }
8492  assert(lp->nlpicols == lp->lpifirstchgcol);
8493 
8494  while( lp->lpifirstchgrow < lp->nlpirows
8495  && lp->lpifirstchgrow < lp->nrows
8496  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8497  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8498  {
8499  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8500  lp->lpifirstchgrow++;
8501  }
8502  assert(lp->nlpirows == lp->lpifirstchgrow);
8503 #endif
8504 
8505  lp->lpifirstchgcol = lp->nlpicols;
8506  lp->lpifirstchgrow = lp->nlpirows;
8507 
8508  /* check, if there are really no column or row additions left */
8509  assert(lp->ncols == lp->nlpicols);
8510  assert(lp->nrows == lp->nlpirows);
8511 
8512  /* mark the changed columns to be unchanged, and check, if this is really correct */
8513  for( i = 0; i < lp->nchgcols; ++i )
8514  {
8515  SCIP_COL* col;
8516 
8517  col = lp->chgcols[i];
8518  assert(col != NULL);
8519  assert(col->var != NULL);
8520  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8521  assert(SCIPvarGetCol(col->var) == col);
8522 
8523  if( col->lpipos >= 0 )
8524  {
8525 #ifndef NDEBUG
8526  /* do not check consistency of data with LPI in case of LPI=none */
8527  if( !lpinone )
8528  {
8529  SCIP_Real lpiobj;
8530  SCIP_Real lpilb;
8531  SCIP_Real lpiub;
8532 
8533  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8534  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8535  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8536  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8537  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8538  assert(col->flushedobj == col->obj); /*lint !e777*/
8539  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8540  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8541  }
8542 #endif
8543  col->objchanged = FALSE;
8544  col->lbchanged = FALSE;
8545  col->ubchanged = FALSE;
8546  }
8547  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8548  }
8549  lp->nchgcols = 0;
8550 
8551  /* mark the changed rows to be unchanged, and check, if this is really correct */
8552  for( i = 0; i < lp->nchgrows; ++i )
8553  {
8554  SCIP_ROW* row;
8555 
8556  row = lp->chgrows[i];
8557  assert(row != NULL);
8558 
8559  if( row->lpipos >= 0 )
8560  {
8561 #ifndef NDEBUG
8562  /* do not check consistency of data with LPI in case of LPI=none */
8563  if( !lpinone )
8564  {
8565  SCIP_Real lpilhs;
8566  SCIP_Real lpirhs;
8567 
8568  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8569  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8570  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8571  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8572  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8573  }
8574 #endif
8575  row->lhschanged = FALSE;
8576  row->rhschanged = FALSE;
8577  }
8578  }
8579  lp->nchgrows = 0;
8580 
8581  /* mark the LP to be flushed */
8582  lp->flushed = TRUE;
8583 
8584  checkLinks(lp);
8585 
8586  return SCIP_OKAY;
8587 }
8588 
8589 
8590 
8591 
8592 /*
8593  * LP methods
8594  */
8595 
8596 /** updates link data after addition of column */
8597 static
8599  SCIP_COL* col, /**< LP column */
8600  SCIP_SET* set /**< global SCIP settings */
8601  )
8602 {
8603  SCIP_ROW* row;
8604  int i;
8605  int pos;
8606 
8607  assert(col != NULL);
8608  assert(col->lppos >= 0);
8609 
8610  /* update column arrays of all linked rows */
8611  for( i = 0; i < col->len; ++i )
8612  {
8613  pos = col->linkpos[i];
8614  if( pos >= 0 )
8615  {
8616  row = col->rows[i];
8617  assert(row != NULL);
8618  assert(row->linkpos[pos] == i);
8619  assert(row->cols[pos] == col);
8620  assert(row->nlpcols <= pos && pos < row->len);
8621 
8622  row->nlpcols++;
8623  rowSwapCoefs(row, pos, row->nlpcols-1);
8624  assert(row->cols[row->nlpcols-1] == col);
8625 
8626  /* if no swap was necessary, mark lpcols to be unsorted */
8627  if( pos == row->nlpcols-1 )
8628  row->lpcolssorted = FALSE;
8629 
8630  /* update norms */
8631  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8632  }
8633  }
8634 }
8635 
8636 /** updates link data after addition of row */
8637 static
8639  SCIP_ROW* row /**< LP row */
8640  )
8641 {
8642  SCIP_COL* col;
8643  int i;
8644  int pos;
8645 
8646  assert(row != NULL);
8647  assert(row->lppos >= 0);
8648 
8649  /* update row arrays of all linked columns */
8650  for( i = 0; i < row->len; ++i )
8651  {
8652  pos = row->linkpos[i];
8653  if( pos >= 0 )
8654  {
8655  col = row->cols[i];
8656  assert(col != NULL);
8657  assert(col->linkpos[pos] == i);
8658  assert(col->rows[pos] == row);
8659  assert(col->nlprows <= pos && pos < col->len);
8660 
8661  col->nlprows++;
8662  colSwapCoefs(col, pos, col->nlprows-1);
8663 
8664  /* if no swap was necessary, mark lprows to be unsorted */
8665  if( pos == col->nlprows-1 )
8666  col->lprowssorted = FALSE;
8667  }
8668  }
8669 }
8670 
8671 /** updates link data after removal of column */
8672 static
8674  SCIP_COL* col, /**< LP column */
8675  SCIP_SET* set /**< global SCIP settings */
8676  )
8677 {
8678  SCIP_ROW* row;
8679  int i;
8680  int pos;
8681 
8682  assert(col != NULL);
8683  assert(col->lppos == -1);
8684 
8685  /* update column arrays of all linked rows */
8686  for( i = 0; i < col->len; ++i )
8687  {
8688  pos = col->linkpos[i];
8689  if( pos >= 0 )
8690  {
8691  row = col->rows[i];
8692  assert(row != NULL);
8693  assert(row->linkpos[pos] == i);
8694  assert(row->cols[pos] == col);
8695  assert(0 <= pos && pos < row->nlpcols);
8696 
8697  /* update norms */
8698  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8699 
8700  row->nlpcols--;
8701  rowSwapCoefs(row, pos, row->nlpcols);
8702 
8703  /* if no swap was necessary, mark nonlpcols to be unsorted */
8704  if( pos == row->nlpcols )
8705  row->nonlpcolssorted = FALSE;
8706  }
8707  }
8708 }
8709 
8710 /** updates link data after removal of row */
8711 static
8713  SCIP_ROW* row /**< LP row */
8714  )
8715 {
8716  SCIP_COL* col;
8717  int i;
8718  int pos;
8719 
8720  assert(row != NULL);
8721  assert(row->lppos == -1);
8722 
8723  /* update row arrays of all linked columns */
8724  for( i = 0; i < row->len; ++i )
8725  {
8726  pos = row->linkpos[i];
8727  if( pos >= 0 )
8728  {
8729  col = row->cols[i];
8730  assert(col != NULL);
8731  assert(0 <= pos && pos < col->nlprows);
8732  assert(col->linkpos[pos] == i);
8733  assert(col->rows[pos] == row);
8734 
8735  col->nlprows--;
8736  colSwapCoefs(col, pos, col->nlprows);
8737 
8738  /* if no swap was necessary, mark lprows to be unsorted */
8739  if( pos == col->nlprows )
8740  col->nonlprowssorted = FALSE;
8741  }
8742  }
8743 }
8744 
8745 static
8747  SCIP_LP* lp, /**< LP data object */
8748  int initsize /**< initial size of the arrays */
8749  )
8750 {
8751  assert(lp != NULL);
8752  assert(lp->divechgsides == NULL);
8753  assert(lp->divechgsidetypes == NULL);
8754  assert(lp->divechgrows == NULL);
8755  assert(lp->ndivechgsides == 0);
8756  assert(lp->divechgsidessize == 0);
8757  assert(initsize > 0);
8758 
8759  lp->divechgsidessize = initsize;
8763 
8764  return SCIP_OKAY;
8765 }
8766 
8767 static
8769  SCIP_LP* lp, /**< LP data object */
8770  int minsize, /**< minimal number of elements */
8771  SCIP_Real growfact /**< growing factor */
8772  )
8773 {
8774  assert(lp != NULL);
8775  assert(lp->divechgsides != NULL);
8776  assert(lp->divechgsidetypes != NULL);
8777  assert(lp->divechgrows != NULL);
8778  assert(lp->ndivechgsides > 0);
8779  assert(lp->divechgsidessize > 0);
8780  assert(minsize > 0);
8781 
8782  if( minsize <= lp->divechgsidessize )
8783  return SCIP_OKAY;
8784 
8785  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
8789 
8790  return SCIP_OKAY;
8791 }
8792 
8793 static
8795  SCIP_LP* lp /**< LP data object */
8796  )
8797 {
8798  assert(lp != NULL);
8799  assert(lp->divechgsides != NULL);
8800  assert(lp->divechgsidetypes != NULL);
8801  assert(lp->divechgrows != NULL);
8802  assert(lp->ndivechgsides == 0);
8803  assert(lp->divechgsidessize > 0);
8804 
8808  lp->divechgsidessize = 0;
8809 }
8810 
8811 #define DIVESTACKINITSIZE 100
8812 
8813 /** creates empty LP data object */
8815  SCIP_LP** lp, /**< pointer to LP data object */
8816  SCIP_SET* set, /**< global SCIP settings */
8817  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
8818  SCIP_STAT* stat, /**< problem statistics */
8819  const char* name /**< problem name */
8820  )
8821 {
8822  SCIP_Bool success;
8823 
8824  assert(lp != NULL);
8825  assert(set != NULL);
8826  assert(stat != NULL);
8827  assert(name != NULL);
8828 
8829  SCIP_ALLOC( BMSallocMemory(lp) );
8830 
8831  /* open LP Solver interface */
8832  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
8833 
8834  (*lp)->lpicols = NULL;
8835  (*lp)->lpirows = NULL;
8836  (*lp)->chgcols = NULL;
8837  (*lp)->chgrows = NULL;
8838  (*lp)->cols = NULL;
8839  (*lp)->lazycols = NULL;
8840  (*lp)->rows = NULL;
8841  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
8842  (*lp)->lpobjval = 0.0;
8843  (*lp)->glbpseudoobjval = 0.0;
8844  (*lp)->relglbpseudoobjval = 0.0;
8845  (*lp)->glbpseudoobjvalid = TRUE;
8846  (*lp)->glbpseudoobjvalinf = 0;
8847  (*lp)->pseudoobjval = 0.0;
8848  (*lp)->relpseudoobjval = 0.0;
8849  (*lp)->pseudoobjvalid = TRUE;
8850  (*lp)->pseudoobjvalinf = 0;
8851  (*lp)->looseobjval = 0.0;
8852  (*lp)->rellooseobjval = 0.0;
8853  (*lp)->looseobjvalid = TRUE;
8854  (*lp)->looseobjvalinf = 0;
8855  (*lp)->nloosevars = 0;
8856  (*lp)->rootlpobjval = SCIP_INVALID;
8857  (*lp)->rootlooseobjval = SCIP_INVALID;
8858  (*lp)->cutoffbound = SCIPsetInfinity(set);
8859  (*lp)->objsqrnorm = 0.0;
8860  (*lp)->objsumnorm = 0.0;
8861  (*lp)->lpicolssize = 0;
8862  (*lp)->nlpicols = 0;
8863  (*lp)->lpirowssize = 0;
8864  (*lp)->nlpirows = 0;
8865  (*lp)->lpifirstchgcol = 0;
8866  (*lp)->lpifirstchgrow = 0;
8867  (*lp)->colssize = 0;
8868  (*lp)->ncols = 0;
8869  (*lp)->lazycolssize = 0;
8870  (*lp)->nlazycols = 0;
8871  (*lp)->rowssize = 0;
8872  (*lp)->nrows = 0;
8873  (*lp)->chgcolssize = 0;
8874  (*lp)->nchgcols = 0;
8875  (*lp)->chgrowssize = 0;
8876  (*lp)->nchgrows = 0;
8877  (*lp)->firstnewcol = 0;
8878  (*lp)->firstnewrow = 0;
8879  (*lp)->nremovablecols = 0;
8880  (*lp)->nremovablerows = 0;
8881  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
8882  (*lp)->validfarkaslp = -1;
8883  (*lp)->objsqrnormunreliable = FALSE;
8884  (*lp)->flushdeletedcols = FALSE;
8885  (*lp)->flushaddedcols = FALSE;
8886  (*lp)->flushdeletedrows = FALSE;
8887  (*lp)->flushaddedrows = FALSE;
8888  (*lp)->updateintegrality = TRUE;
8889  (*lp)->flushed = TRUE;
8890  (*lp)->solved = TRUE;
8891  (*lp)->primalfeasible = TRUE;
8892  (*lp)->primalchecked = TRUE;
8893  (*lp)->dualfeasible = TRUE;
8894  (*lp)->dualchecked = TRUE;
8895  (*lp)->solisbasic = FALSE;
8896  (*lp)->rootlpisrelax = TRUE;
8897  (*lp)->isrelax = TRUE;
8898  (*lp)->installing = FALSE;
8899  (*lp)->strongbranching = FALSE;
8900  (*lp)->strongbranchprobing = FALSE;
8901  (*lp)->probing = FALSE;
8902  (*lp)->diving = FALSE;
8903  (*lp)->divingobjchg = FALSE;
8904  (*lp)->divinglazyapplied = FALSE;
8905  (*lp)->divelpistate = NULL;
8906  (*lp)->divelpwasprimfeas = TRUE;
8907  (*lp)->divelpwasprimchecked = TRUE;
8908  (*lp)->divelpwasdualfeas = TRUE;
8909  (*lp)->divelpwasdualchecked = TRUE;
8910  (*lp)->divechgsides = NULL;
8911  (*lp)->divechgsidetypes = NULL;
8912  (*lp)->divechgrows = NULL;
8913  (*lp)->ndivechgsides = 0;
8914  (*lp)->divechgsidessize = 0;
8915  (*lp)->ndivingrows = 0;
8916  (*lp)->divinglpiitlim = INT_MAX;
8917  (*lp)->resolvelperror = FALSE;
8918  (*lp)->adjustlpval = FALSE;
8919  (*lp)->lpiuobjlim = SCIPlpiInfinity((*lp)->lpi);
8920  (*lp)->lpifeastol = SCIPsetLpfeastol(set);
8921  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
8922  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
8923  (*lp)->lpifromscratch = FALSE;
8924  (*lp)->lpifastmip = set->lp_fastmip;
8925  (*lp)->lpiscaling = set->lp_scaling;
8926  (*lp)->lpipresolving = set->lp_presolving;
8927  (*lp)->lpilpinfo = set->disp_lpinfo;
8928  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
8929  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
8930  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
8931  (*lp)->lpiitlim = INT_MAX;
8932  (*lp)->lpipricing = SCIP_PRICING_AUTO;
8933  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
8934  (*lp)->lpithreads = set->lp_threads;
8935  (*lp)->lpitiming = (int) set->time_clocktype;
8936  (*lp)->lpirandomseed = set->random_randomseed;
8937  (*lp)->storedsolvals = NULL;
8938 
8939  /* allocate arrays for diving */
8941 
8942  /* set default parameters in LP solver */
8943  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_UOBJLIM, (*lp)->lpiuobjlim, &success) );
8944  if( !success )
8945  {
8946  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8947  "LP Solver <%s>: upper objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
8949  }
8950  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
8951  (*lp)->lpihasfeastol = success;
8952  if( !success )
8953  {
8954  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8955  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8957  }
8958  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
8959  (*lp)->lpihasdualfeastol = success;
8960  if( !success )
8961  {
8962  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8963  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8965  }
8966  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
8967  (*lp)->lpihasbarrierconvtol = success;
8968  if( !success )
8969  {
8970  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8971  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
8973  }
8974  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
8975  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
8976  (*lp)->lpihasfastmip = success;
8977  if( !success )
8978  {
8979  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8980  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
8982  }
8983  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
8984  (*lp)->lpihasscaling = success;
8985  if( !success )
8986  {
8987  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8988  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
8990  }
8991  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
8992  (*lp)->lpihaspresolving = success;
8993  if( !success )
8994  {
8995  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
8996  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
8998  }
8999  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9000  if( !success )
9001  {
9002  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9003  "LP Solver <%s>: clock type cannot be set\n",
9005  }
9006  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9007  if( !success )
9008  {
9009  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9010  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9012  }
9013  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9014  if( !success )
9015  {
9016  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9017  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9019  }
9020  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9021  if( !success )
9022  {
9023  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9024  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9026  }
9027  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9028  (*lp)->lpihasrowrep = success;
9029  if( !success )
9030  {
9031  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9032  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9034  }
9035  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9036  (*lp)->lpihaspolishing = success;
9037  if( !success )
9038  {
9039  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9040  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9042  }
9043  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9044  if( !success )
9045  {
9046  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9047  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9049  }
9050  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9051  if( !success )
9052  {
9053  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9054  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9056  }
9057  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9058  if( (*lp)->lpirandomseed != 0 )
9059  {
9060  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9061  if( !success )
9062  {
9063  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9064  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9066  }
9067  }
9068 
9069  return SCIP_OKAY;
9070 }
9071 
9072 /** frees LP data object */
9074  SCIP_LP** lp, /**< pointer to LP data object */
9075  BMS_BLKMEM* blkmem, /**< block memory */
9076  SCIP_SET* set, /**< global SCIP settings */
9077  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9078  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9079  )
9080 {
9081  int i;
9082 
9083  assert(lp != NULL);
9084  assert(*lp != NULL);
9085 
9086  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9087 
9088  freeDiveChgSideArrays(*lp);
9089 
9090  /* release LPI rows */
9091  for( i = 0; i < (*lp)->nlpirows; ++i )
9092  {
9093  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9094  }
9095 
9096  if( (*lp)->lpi != NULL )
9097  {
9098  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9099  }
9100 
9101  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9102  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9103  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9104  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9105  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9106  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9107  BMSfreeMemoryArrayNull(&(*lp)->cols);
9108  BMSfreeMemoryArrayNull(&(*lp)->rows);
9109  BMSfreeMemory(lp);
9110 
9111  return SCIP_OKAY;
9112 }
9113 
9114 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9115  * changes to the LP solver
9116  */
9118  SCIP_LP* lp, /**< LP data */
9119  BMS_BLKMEM* blkmem, /**< block memory */
9120  SCIP_SET* set, /**< global SCIP settings */
9121  SCIP_STAT* stat, /**< problem statistics */
9122  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9123  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9124  )
9125 {
9126  assert(stat != NULL);
9127 
9128  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9129  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9130 
9131  /* mark the empty LP to be solved */
9133  lp->lpobjval = 0.0;
9134  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9135  lp->validfarkaslp = -1;
9136  lp->solved = TRUE;
9137  lp->primalfeasible = TRUE;
9138  lp->primalchecked = TRUE;
9139  lp->dualfeasible = TRUE;
9140  lp->dualchecked = TRUE;
9141  lp->solisbasic = FALSE;
9143 
9144  return SCIP_OKAY;
9145 }
9146 
9147 /** adds a column to the LP */
9149  SCIP_LP* lp, /**< LP data */
9150  SCIP_SET* set, /**< global SCIP settings */
9151  SCIP_COL* col, /**< LP column */
9152  int depth /**< depth in the tree where the column addition is performed */
9153  )
9154 {
9155  assert(lp != NULL);
9156  assert(!lp->diving);
9157  assert(col != NULL);
9158  assert(col->len == 0 || col->rows != NULL);
9159  assert(col->lppos == -1);
9160  assert(col->var != NULL);
9161  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9162  assert(SCIPvarGetCol(col->var) == col);
9163  assert(SCIPvarIsIntegral(col->var) == col->integral);
9164 
9165  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9166 #ifdef SCIP_DEBUG
9167  {
9168  int i;
9169  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9170  for( i = 0; i < col->len; ++i )
9171  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9172  SCIPsetDebugMsgPrint(set, "\n");
9173  }
9174 #endif
9175 
9176  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9177  lp->cols[lp->ncols] = col;
9178  col->lppos = lp->ncols;
9179  col->lpdepth = depth;
9180  col->age = 0;
9181  lp->ncols++;
9182  if( col->removable )
9183  lp->nremovablecols++;
9184 
9185  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9186  {
9187  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9188  lp->lazycols[lp->nlazycols] = col;
9189  lp->nlazycols++;
9190  }
9191 
9192  /* mark the current LP unflushed */
9193  lp->flushed = FALSE;
9194 
9195  /* update column arrays of all linked rows */
9196  colUpdateAddLP(col, set);
9197 
9198  /* update the objective function vector norms */
9199  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9200 
9201  checkLinks(lp);
9202 
9203  return SCIP_OKAY;
9204 }
9205 
9206 /** adds a row to the LP and captures it */
9208  SCIP_LP* lp, /**< LP data */
9209  BMS_BLKMEM* blkmem, /**< block memory buffers */
9210  SCIP_SET* set, /**< global SCIP settings */
9211  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9212  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9213  SCIP_ROW* row, /**< LP row */
9214  int depth /**< depth in the tree where the row addition is performed */
9215  )
9216 {
9217  assert(lp != NULL);
9218  assert(row != NULL);
9219  assert(row->len == 0 || row->cols != NULL);
9220  assert(row->lppos == -1);
9221 
9222  SCIProwCapture(row);
9223  SCIProwLock(row);
9224 
9225  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9226 #ifdef SCIP_DEBUG
9227  {
9228  int i;
9229  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9230  for( i = 0; i < row->len; ++i )
9231  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9232  if( !SCIPsetIsZero(set, row->constant) )
9233  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9234  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9235  }
9236 #endif
9237 
9238  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9239  lp->rows[lp->nrows] = row;
9240  row->lppos = lp->nrows;
9241  row->lpdepth = depth;
9242  row->age = 0;
9243  lp->nrows++;
9244  if( row->removable )
9245  lp->nremovablerows++;
9246 
9247  /* mark the current LP unflushed */
9248  lp->flushed = FALSE;
9249 
9250  /* update row arrays of all linked columns */
9251  rowUpdateAddLP(row);
9252 
9253  checkLinks(lp);
9254 
9255  rowCalcNorms(row, set);
9256 
9257  /* check, if row addition to LP events are tracked
9258  * if so, issue ROWADDEDLP event
9259  */
9260  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9261  {
9262  SCIP_EVENT* event;
9263 
9264  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9265  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9266  }
9267 
9268  return SCIP_OKAY;
9269 }
9270 
9271 
9272 #ifndef NDEBUG
9273 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9274  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9275  * the lazycols array
9276  */
9277 static
9279  SCIP_LP* lp, /**< LP data */
9280  SCIP_SET* set /**< global SCIP settings */
9281  )
9282 {
9283  SCIP_Bool contained;
9284  int c;
9285  int i;
9286 
9287  assert(lp != NULL);
9288 
9289  /* check if each column in the lazy column array has a counter part in the column array */
9290  for( i = 0; i < lp->nlazycols; ++i )
9291  {
9292  /* check if each lazy column has at least on lazy bound */
9293  assert(lp->lazycols[i] != NULL);
9294  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9295 
9296  contained = FALSE;
9297  for( c = 0; c < lp->ncols; ++c )
9298  {
9299  if( lp->lazycols[i] == lp->cols[c] )
9300  {
9301  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9302  contained = TRUE;
9303  }
9304  }
9305  assert(contained);
9306  }
9307 
9308  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9309  * array */
9310  for( c = 0; c < lp->ncols; ++c )
9311  {
9312  contained = FALSE;
9313  assert(lp->cols[c] != NULL);
9314 
9315  for( i = 0; i < lp->nlazycols; ++i )
9316  {
9317  if( lp->lazycols[i] == lp->cols[c] )
9318  {
9319  contained = TRUE;
9320  }
9321  }
9322 
9323  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9324  }
9325 }
9326 #else
9327 #define checkLazyColArray(lp, set) /**/
9328 #endif
9329 
9330 /** removes all columns after the given number of cols from the LP */
9332  SCIP_LP* lp, /**< LP data */
9333  SCIP_SET* set, /**< global SCIP settings */
9334  int newncols /**< new number of columns in the LP */
9335  )
9336 {
9337  SCIP_COL* col;
9338  int c;
9339 
9340  assert(lp != NULL);
9341 
9342  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9343  assert(0 <= newncols);
9344  assert(newncols <= lp->ncols);
9345 
9346  if( newncols < lp->ncols )
9347  {
9348  assert(!lp->diving);
9349 
9350  for( c = lp->ncols-1; c >= newncols; --c )
9351  {
9352  col = lp->cols[c];
9353  assert(col != NULL);
9354  assert(col->len == 0 || col->rows != NULL);
9355  assert(col->var != NULL);
9356  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9357  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9358  assert(col->lppos == c);
9359 
9360  /* mark column to be removed from the LP */
9361  col->lppos = -1;
9362  col->lpdepth = -1;
9363  lp->ncols--;
9364 
9365  /* count removable columns */
9366  if( col->removable )
9367  lp->nremovablecols--;
9368 
9369  /* update column arrays of all linked rows */
9370  colUpdateDelLP(col, set);
9371 
9372  /* update the objective function vector norms */
9373  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9374  }
9375  assert(lp->ncols == newncols);
9376  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9377 
9378  /* remove columns which are deleted from the lazy column array */
9379  c = 0;
9380  while( c < lp->nlazycols )
9381  {
9382  if( lp->lazycols[c]->lppos < 0 )
9383  {
9384  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9385  lp->nlazycols--;
9386  }
9387  else
9388  c++;
9389  }
9390 
9391  /* mark the current LP unflushed */
9392  lp->flushed = FALSE;
9393 
9394  checkLazyColArray(lp, set);
9395  checkLinks(lp);
9396  }
9397  assert(lp->nremovablecols <= lp->ncols);
9398 
9399  return SCIP_OKAY;
9400 }
9401 
9402 /** removes and releases all rows after the given number of rows from the LP */
9404  SCIP_LP* lp, /**< LP data */
9405  BMS_BLKMEM* blkmem, /**< block memory */
9406  SCIP_SET* set, /**< global SCIP settings */
9407  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9408  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9409  int newnrows /**< new number of rows in the LP */
9410  )
9411 {
9412  SCIP_ROW* row;
9413  int r;
9414 
9415  assert(lp != NULL);
9416  assert(0 <= newnrows && newnrows <= lp->nrows);
9417 
9418  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9419  if( newnrows < lp->nrows )
9420  {
9421  for( r = lp->nrows-1; r >= newnrows; --r )
9422  {
9423  row = lp->rows[r];
9424  assert(row != NULL);
9425  assert(row->len == 0 || row->cols != NULL);
9426  assert(row->lppos == r);
9427 
9428  /* mark row to be removed from the LP */
9429  row->lppos = -1;
9430  row->lpdepth = -1;
9431  lp->nrows--;
9432 
9433  /* count removable rows */
9434  if( row->removable )
9435  lp->nremovablerows--;
9436 
9437  /* update row arrays of all linked columns */
9438  rowUpdateDelLP(row);
9439 
9440  SCIProwUnlock(lp->rows[r]);
9441 
9442  /* check, if row deletion events are tracked
9443  * if so, issue ROWDELETEDLP event
9444  */
9445  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9446  {
9447  SCIP_EVENT* event;
9448 
9449  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9450  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9451  }
9452 
9453  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9454  }
9455  assert(lp->nrows == newnrows);
9456  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9457 
9458  /* mark the current LP unflushed */
9459  lp->flushed = FALSE;
9460 
9461  checkLinks(lp);
9462  }
9463  assert(lp->nremovablerows <= lp->nrows);
9464 
9465  return SCIP_OKAY;
9466 }
9467 
9468 /** removes all columns and rows from LP, releases all rows */
9470  SCIP_LP* lp, /**< LP data */
9471  BMS_BLKMEM* blkmem, /**< block memory */
9472  SCIP_SET* set, /**< global SCIP settings */
9473  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9474  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9475  )
9476 {
9477  assert(lp != NULL);
9478  assert(!lp->diving);
9479 
9480  SCIPsetDebugMsg(set, "clearing LP\n");
9481  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9482  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9483 
9484  return SCIP_OKAY;
9485 }
9486 
9487 /** remembers number of columns and rows to track the newly added ones */
9489  SCIP_LP* lp /**< current LP data */
9490  )
9491 {
9492  assert(lp != NULL);
9493  assert(!lp->diving);
9494 
9495  lp->firstnewrow = lp->nrows;
9496  lp->firstnewcol = lp->ncols;
9497 }
9498 
9499 /** sets the remembered number of columns and rows to the given values */
9501  SCIP_LP* lp, /**< current LP data */
9502  int nrows, /**< number of rows to set the size marker to */
9503  int ncols /**< number of columns to set the size marker to */
9504  )
9505 {
9506  assert(lp != NULL);
9507  assert(!lp->diving);
9508 
9509  lp->firstnewrow = nrows;
9510  lp->firstnewcol = ncols;
9511 }
9512 
9513 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9515  SCIP_LP* lp, /**< LP data */
9516  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9517  )
9518 {
9519  assert(lp != NULL);
9520  assert(lp->flushed);
9521  assert(lp->solved);
9522  assert(lp->solisbasic);
9523  assert(basisind != NULL);
9524 
9525  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9526 
9527  return SCIP_OKAY;
9528 }
9529 
9530 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9532  SCIP_LP* lp, /**< LP data */
9533  int* cstat, /**< array to store column basis status, or NULL */
9534  int* rstat /**< array to store row basis status, or NULL */
9535  )
9536 {
9537  assert(lp != NULL);
9538  assert(lp->flushed);
9539  assert(lp->solved);
9540  assert(lp->solisbasic);
9541 
9542  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9543 
9544  return SCIP_OKAY;
9545 }
9546 
9547 /** gets a row from the inverse basis matrix B^-1 */
9549  SCIP_LP* lp, /**< LP data */
9550  int r, /**< row number */
9551  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9552  int* inds, /**< array to store the non-zero indices, or NULL */
9553  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9554  * (-1: if we do not store sparsity informations) */
9555  )
9556 {
9557  assert(lp != NULL);
9558  assert(lp->flushed);
9559  assert(lp->solved);
9560  assert(lp->solisbasic);
9561  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9562  assert(coef != NULL);
9563 
9564  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9565 
9566  return SCIP_OKAY;
9567 }
9568 
9569 /** gets a column from the inverse basis matrix B^-1 */
9571  SCIP_LP* lp, /**< LP data */
9572  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9573  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9574  * to get the array which links the B^-1 column numbers to the row and
9575  * column numbers of the LP! c must be between 0 and nrows-1, since the
9576  * basis has the size nrows * nrows */
9577  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9578  int* inds, /**< array to store the non-zero indices, or NULL */
9579  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9580  * (-1: if we do not store sparsity informations) */
9581  )
9582 {
9583  assert(lp != NULL);
9584  assert(lp->flushed);
9585  assert(lp->solved);
9586  assert(lp->solisbasic);
9587  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9588  assert(coef != NULL);
9589 
9590  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9591 
9592  return SCIP_OKAY;
9593 }
9594 
9595 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9597  SCIP_LP* lp, /**< LP data */
9598  int r, /**< row number */
9599  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9600  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9601  int* inds, /**< array to store the non-zero indices, or NULL */
9602  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9603  * (-1: if we do not store sparsity informations) */
9604  )
9605 {
9606  assert(lp != NULL);
9607  assert(lp->flushed);
9608  assert(lp->solved);
9609  assert(lp->solisbasic);
9610  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9611  assert(coef != NULL);
9612 
9613  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9614 
9615  return SCIP_OKAY;
9616 }
9617 
9618 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9619  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9620  */
9622  SCIP_LP* lp, /**< LP data */
9623  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9624  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9625  int* inds, /**< array to store the non-zero indices, or NULL */
9626  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9627  * (-1: if we do not store sparsity informations) */
9628  )
9629 {
9630  assert(lp != NULL);
9631  assert(lp->flushed);
9632  assert(lp->solved);
9633  assert(lp->solisbasic);
9634  assert(0 <= c && c < lp->ncols);
9635  assert(coef != NULL);
9636 
9637  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9638 
9639  return SCIP_OKAY;
9640 }
9641 
9642 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9643  * LP row are swapped in the summation
9644  */
9646  SCIP_LP* lp, /**< LP data */
9647  SCIP_SET* set, /**< global SCIP settings */
9648  SCIP_PROB* prob, /**< problem data */
9649  SCIP_Real* weights, /**< row weights in row summation */
9650  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9651  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9652  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9653  )
9654 {
9655  SCIP_ROW* row;
9656  int r;
9657  int i;
9658  int idx;
9659  SCIP_Bool lhsinfinite;
9660  SCIP_Bool rhsinfinite;
9661 
9662  assert(lp != NULL);
9663  assert(prob != NULL);
9664  assert(weights != NULL);
9665  assert(sumcoef != NULL);
9666  assert(sumlhs != NULL);
9667  assert(sumrhs != NULL);
9668 
9669  /**@todo test, if a column based summation is faster */
9670 
9671  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9672  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9673  *sumlhs = 0.0;
9674  *sumrhs = 0.0;
9675  lhsinfinite = FALSE;
9676  rhsinfinite = FALSE;
9677  for( r = 0; r < lp->nrows; ++r )
9678  {
9679  if( !SCIPsetIsZero(set, weights[r]) )
9680  {
9681  row = lp->rows[r];
9682  assert(row != NULL);
9683  assert(row->len == 0 || row->cols != NULL);
9684  assert(row->len == 0 || row->cols_index != NULL);
9685  assert(row->len == 0 || row->vals != NULL);
9686 
9687  /* add the row coefficients to the sum */
9688  for( i = 0; i < row->len; ++i )
9689  {
9690  assert(row->cols[i] != NULL);
9691  assert(row->cols[i]->var != NULL);
9692  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9693  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9694  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9695  idx = row->cols[i]->var_probindex;
9696  assert(0 <= idx && idx < prob->nvars);
9697  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9698  }
9699 
9700  /* add the row sides to the sum, depending on the sign of the weight */
9701  if( weights[r] > 0.0 )
9702  {
9703  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9704  if( !lhsinfinite )
9705  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9706  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9707  if( !rhsinfinite )
9708  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9709  }
9710  else
9711  {
9712  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9713  if( !lhsinfinite )
9714  (*sumlhs) += weights[r] * (row->rhs - row->constant);
9715  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9716  if( !rhsinfinite )
9717  (*sumrhs) += weights[r] * (row->lhs - row->constant);
9718  }
9719  }
9720  }
9721 
9722  if( lhsinfinite )
9723  *sumlhs = -SCIPsetInfinity(set);
9724  if( rhsinfinite )
9725  *sumrhs = SCIPsetInfinity(set);
9726 
9727  return SCIP_OKAY;
9728 }
9729 
9730 /** stores LP state (like basis information) into LP state object */
9732  SCIP_LP* lp, /**< LP data */
9733  BMS_BLKMEM* blkmem, /**< block memory */
9734  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9735  )
9736 {
9737  assert(lp != NULL);
9738  assert(lp->flushed);
9739  assert(lp->solved);
9740  assert(blkmem != NULL);
9741  assert(lpistate != NULL);
9742 
9743  /* check whether there is no lp */
9744  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9745  *lpistate = NULL;
9746  else
9747  {
9748  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
9749  }
9750 
9751  return SCIP_OKAY;
9752 }
9753 
9754 /** loads LP state (like basis information) into solver */
9756  SCIP_LP* lp, /**< LP data */
9757  BMS_BLKMEM* blkmem, /**< block memory */
9758  SCIP_SET* set, /**< global SCIP settings */
9759  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9760  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
9761  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
9762  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
9763  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
9764  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
9765  )
9766 {
9767  assert(lp != NULL);
9768  assert(blkmem != NULL);
9769 
9770  /* flush changes to the LP solver */
9771  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9772  assert(lp->flushed);
9773 
9774  if( lp->solved && lp->solisbasic )
9775  return SCIP_OKAY;
9776 
9777  /* set LPI state in the LP solver */
9778  if( lpistate == NULL )
9779  lp->solisbasic = FALSE;
9780  else
9781  {
9782  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
9783  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
9784  }
9785  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
9786  * flushed and solved, also, e.g., when we hit the iteration limit
9787  */
9788  lp->primalfeasible = wasprimfeas;
9789  lp->primalchecked = wasprimchecked;
9790  lp->dualfeasible = wasdualfeas;
9791  lp->dualchecked = wasdualchecked;
9792 
9793  return SCIP_OKAY;
9794 }
9795 
9796 /** frees LP state information */
9798  SCIP_LP* lp, /**< LP data */
9799  BMS_BLKMEM* blkmem, /**< block memory */
9800  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9801  )
9802 {
9803  assert(lp != NULL);
9804 
9805  if( *lpistate != NULL )
9806  {
9807  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
9808  }
9809 
9810  return SCIP_OKAY;
9811 }
9812 
9813 /** stores pricing norms into LP norms object */
9815  SCIP_LP* lp, /**< LP data */
9816  BMS_BLKMEM* blkmem, /**< block memory */
9817  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9818  )
9819 {
9820  assert(lp != NULL);
9821  assert(lp->flushed);
9822  assert(lp->solved);
9823  assert(blkmem != NULL);
9824  assert(lpinorms != NULL);
9825 
9826  /* check whether there is no lp */
9827  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9828  *lpinorms = NULL;
9829  else
9830  {
9831  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
9832  }
9833 
9834  return SCIP_OKAY;
9835 }
9836 
9837 /** loads pricing norms from LP norms object into solver */
9839  SCIP_LP* lp, /**< LP data */
9840  BMS_BLKMEM* blkmem, /**< block memory */
9841  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
9842  )
9843 {
9844  assert(lp != NULL);
9845  assert(blkmem != NULL);
9846  assert(lp->flushed);
9847 
9848  /* set LPI norms in the LP solver */
9849  if( lpinorms != NULL )
9850  {
9851  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
9852  }
9853 
9854  return SCIP_OKAY;
9855 }
9856 
9857 /** frees pricing norms information */
9859  SCIP_LP* lp, /**< LP data */
9860  BMS_BLKMEM* blkmem, /**< block memory */
9861  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
9862  )
9863 {
9864  assert(lp != NULL);
9865 
9866  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
9867 
9868  return SCIP_OKAY;
9869 }
9870 
9871 /** return the current cutoff bound of the lp */
9873  SCIP_LP* lp /**< current LP data */
9874  )
9875 {
9876  assert(lp != NULL);
9877 
9878  return lp->cutoffbound;
9879 }
9880 
9881 /** sets the upper objective limit of the LP solver */
9883  SCIP_LP* lp, /**< current LP data */
9884  SCIP_SET* set, /**< global SCIP settings */
9885  SCIP_PROB* prob, /**< problem data */
9886  SCIP_Real cutoffbound /**< new upper objective limit */
9887  )
9888 {
9889  assert(lp != NULL);
9890 
9891  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
9892 
9893  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
9894  * in SCIPendDive())
9895  */
9896  if( SCIPlpDivingObjChanged(lp) )
9897  {
9898  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
9899  return SCIP_OKAY;
9900  }
9901 
9902  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
9903  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
9904  {
9905  /* mark the current solution invalid */
9906  lp->solved = FALSE;
9907  lp->lpobjval = SCIP_INVALID;
9909  }
9910  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
9911  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
9912  */
9914  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
9915  {
9916  assert(lp->flushed);
9917  assert(lp->solved);
9919  }
9920 
9921  lp->cutoffbound = cutoffbound;
9922 
9923  return SCIP_OKAY;
9924 }
9925 
9926 /** returns the name of the given LP algorithm */
9927 static
9928 const char* lpalgoName(
9929  SCIP_LPALGO lpalgo /**< LP algorithm */
9930  )
9931 {
9932  switch( lpalgo )
9933  {
9935  return "primal simplex";
9937  return "dual simplex";
9938  case SCIP_LPALGO_BARRIER:
9939  return "barrier";
9941  return "barrier/crossover";
9942  default:
9943  SCIPerrorMessage("invalid LP algorithm\n");
9944  SCIPABORT();
9945  return "invalid"; /*lint !e527*/
9946  }
9947 }
9948 
9949 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
9950 static
9952  SCIP_LP* lp, /**< current LP data */
9953  SCIP_SET* set, /**< global SCIP settings */
9954  SCIP_STAT* stat, /**< problem statistics */
9955  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
9956  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
9957  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
9958  )
9959 {
9960  SCIP_Real timedelta;
9961  SCIP_RETCODE retcode;
9962  int iterations;
9963 
9964  assert(lp != NULL);
9965  assert(lp->flushed);
9966  assert(set != NULL);
9967  assert(stat != NULL);
9968  assert(lperror != NULL);
9969 
9970  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",
9971  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
9972 
9973  *lperror = FALSE;
9974 
9975 #if 0 /* for debugging: write all root node LP's */
9976  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
9977  {
9978  char fname[SCIP_MAXSTRLEN];
9979  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
9980  SCIP_CALL( SCIPlpWrite(lp, fname) );
9981  SCIPsetDebugMsg("wrote LP to file <%s> (primal simplex, uobjlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
9982  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol,
9983  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
9984  }
9985 #endif
9986 
9987  /* start timing */
9988  if( lp->diving || lp->probing )
9989  {
9990  if( lp->strongbranchprobing )
9991  SCIPclockStart(stat->strongbranchtime, set);
9992  else
9993  SCIPclockStart(stat->divinglptime, set);
9994 
9995  timedelta = 0.0; /* unused for diving or probing */
9996  }
9997  else
9998  {
9999  SCIPclockStart(stat->primallptime, set);
10000  timedelta = -SCIPclockGetTime(stat->primallptime);
10001  }
10002 
10003  /* call primal simplex */
10004  retcode = SCIPlpiSolvePrimal(lp->lpi);
10005  if( retcode == SCIP_LPERROR )
10006  {
10007  *lperror = TRUE;
10008  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10009  }
10010  else
10011  {
10012  SCIP_CALL( retcode );
10013  }
10015  lp->solisbasic = TRUE;
10016 
10017  /* stop timing */
10018  if( lp->diving || lp->probing )
10019  {
10020  if( lp->strongbranchprobing )
10021  SCIPclockStop(stat->strongbranchtime, set);
10022  else
10023  SCIPclockStop(stat->divinglptime, set);
10024  }
10025  else
10026  {
10027  timedelta += SCIPclockGetTime(stat->primallptime);
10028  SCIPclockStop(stat->primallptime, set);
10029  }
10030 
10031  /* count number of iterations */
10032  SCIPstatIncrement(stat, set, lpcount);
10033  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10034  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10035  {
10036  if( !lp->strongbranchprobing )
10037  {
10038  SCIPstatIncrement(stat, set, nlps);
10039  SCIPstatAdd( stat, set, nlpiterations, iterations );
10040  }
10041  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10042  {
10043  SCIPstatIncrement(stat, set, nprimalresolvelps );
10044  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10045  }
10046  if( lp->diving || lp->probing )
10047  {
10048  if( lp->strongbranchprobing )
10049  {
10050  SCIPstatIncrement(stat, set, nsbdivinglps);
10051  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10052  }
10053  else
10054  {
10055  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10056  SCIPstatIncrement(stat, set, ndivinglps);
10057  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10058  }
10059  }
10060  else
10061  {
10062  SCIPstatIncrement(stat, set, nprimallps);
10063  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10064  }
10065  }
10066  else
10067  {
10068  if ( ! lp->diving && ! lp->probing )
10069  {
10070  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10071  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10072  }
10073 
10074  if ( keepsol && !(*lperror) )
10075  {
10076  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10077  if( lp->validsollp == stat->lpcount-1 )
10078  lp->validsollp = stat->lpcount;
10079  if( lp->validfarkaslp == stat->lpcount-1 )
10080  lp->validfarkaslp = stat->lpcount;
10081  }
10082  }
10083 
10084  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10085  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10086 
10087  return SCIP_OKAY;
10088 }
10089 
10090 /** calls LPI to perform dual simplex, measures time and counts iterations */
10091 static
10093  SCIP_LP* lp, /**< current LP data */
10094  SCIP_SET* set, /**< global SCIP settings */
10095  SCIP_STAT* stat, /**< problem statistics */
10096  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10097  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10098  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10099  )
10100 {
10101  SCIP_Real timedelta;
10102  SCIP_RETCODE retcode;
10103  int iterations;
10104 
10105  assert(lp != NULL);
10106  assert(lp->flushed);
10107  assert(set != NULL);
10108  assert(stat != NULL);
10109  assert(lperror != NULL);
10110 
10111  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",
10112  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10113 
10114  *lperror = FALSE;
10115 
10116 #if 0 /* for debugging: write all root node LP's */
10117  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10118  {
10119  char fname[SCIP_MAXSTRLEN];
10120  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10121  SCIP_CALL( SCIPlpWrite(lp, fname) );
10122  SCIPsetDebugMsg("wrote LP to file <%s> (dual simplex, uobjlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10123  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol,
10124  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10125  }
10126 #endif
10127 
10128  /* start timing */
10129  if( lp->diving || lp->probing )
10130  {
10131  if( lp->strongbranchprobing )
10132  SCIPclockStart(stat->strongbranchtime, set);
10133  else
10134  SCIPclockStart(stat->divinglptime, set);
10135 
10136  timedelta = 0.0; /* unused for diving or probing */
10137  }
10138  else
10139  {
10140  SCIPclockStart(stat->duallptime, set);
10141  timedelta = -SCIPclockGetTime(stat->duallptime);
10142  }
10143 
10144  /* call dual simplex */
10145  retcode = SCIPlpiSolveDual(lp->lpi);
10146  if( retcode == SCIP_LPERROR )
10147  {
10148  *lperror = TRUE;
10149  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10150  }
10151  else
10152  {
10153  SCIP_CALL( retcode );
10154  }
10156  lp->solisbasic = TRUE;
10157 
10158  /* stop timing */
10159  if( lp->diving || lp->probing )
10160  {
10161  if( lp->strongbranchprobing )
10162  SCIPclockStop(stat->strongbranchtime, set);
10163  else
10164  SCIPclockStop(stat->divinglptime, set);
10165  }
10166  else
10167  {
10168  timedelta += SCIPclockGetTime(stat->duallptime);
10169  SCIPclockStop(stat->duallptime, set);
10170  }
10171 
10172  /* count number of iterations */
10173  SCIPstatIncrement(stat, set, lpcount);
10174  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10175  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10176  {
10177  if( !lp->strongbranchprobing )
10178  {
10179  SCIPstatIncrement(stat, set, nlps);
10180  SCIPstatAdd(stat, set, nlpiterations, iterations);
10181  }
10182  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10183  {
10184  SCIPstatIncrement(stat, set, ndualresolvelps);
10185  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10186  }
10187  if( lp->diving || lp->probing )
10188  {
10189  if( lp->strongbranchprobing )
10190  {
10191  SCIPstatIncrement(stat, set, nsbdivinglps);
10192  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10193  }
10194  else
10195  {
10196  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10197  SCIPstatIncrement(stat, set, ndivinglps);
10198  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10199  }
10200  }
10201  else
10202  {
10203  SCIPstatIncrement(stat, set, nduallps);
10204  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10205  }
10206  }
10207  else
10208  {
10209  if ( ! lp->diving && ! lp->probing )
10210  {
10211  SCIPstatIncrement(stat, set, ndualzeroitlps);
10212  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10213  }
10214 
10215  if( keepsol && !(*lperror) )
10216  {
10217  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10218  if( lp->validsollp == stat->lpcount-1 )
10219  lp->validsollp = stat->lpcount;
10220  if( lp->validfarkaslp == stat->lpcount-1 )
10221  lp->validfarkaslp = stat->lpcount;
10222  }
10223  }
10224 
10225  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10226  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10227 
10228  return SCIP_OKAY;
10229 }
10230 
10231 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10232  *
10233  * We follow the approach of the following paper to find a lexicographically minimal optimal
10234  * solution:
10235  *
10236  * Zanette, Fischetti, Balas@n
10237  * Can pure cutting plane algorithms work?@n
10238  * IPCO 2008, Bertinoro, Italy.
10239  *
10240  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10241  * heuristic, i.e., we limit the number of components which are minimized.
10242  *
10243  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10244  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10245  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10246  * pivots that will not change the objective are allowed afterwards.
10247  *
10248  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10249  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10250  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10251  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10252  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10253  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10254  * reduced cost. We then choose the next variable and iterate.
10255  *
10256  * We stop the process once we do not find candidates or have performed a maximum number of
10257  * iterations.
10258  *
10259  * @todo Does this really produce a lexicographically minimal solution?
10260  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10261  * guarantee that these variables will not be changed in later stages? We can fix these variables
10262  * to their lower bound, but this destroys the basis.
10263  * @todo Should we use lexicographical minimization in diving/probing or not?
10264  */
10265 static
10267  SCIP_LP* lp, /**< current LP data */
10268  SCIP_SET* set, /**< global SCIP settings */
10269  SCIP_STAT* stat, /**< problem statistics */
10270  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10271  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10272  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10273  )
10274 {
10275  SCIP_Real timedelta;
10276  SCIP_RETCODE retcode;
10277  int totalIterations;
10278  int lexIterations;
10279  int iterations;
10280  int rounds;
10281 
10282  assert(lp != NULL);
10283  assert(lp->flushed);
10284  assert(set != NULL);
10285  assert(stat != NULL);
10286  assert(lperror != NULL);
10287 
10288  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",
10289  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10290 
10291  *lperror = FALSE;
10292 
10293  /* start timing */
10294  if( lp->diving || lp->probing )
10295  {
10296  if( lp->strongbranchprobing )
10297  SCIPclockStart(stat->strongbranchtime, set);
10298  else
10299  SCIPclockStart(stat->divinglptime, set);
10300 
10301  timedelta = 0.0; /* unused for diving or probing */
10302  }
10303  else
10304  {
10305  SCIPclockStart(stat->duallptime, set);
10306  timedelta = -SCIPclockGetTime(stat->duallptime);
10307  }
10308 
10309  /* call dual simplex for first lp */
10310  retcode = SCIPlpiSolveDual(lp->lpi);
10311  if( retcode == SCIP_LPERROR )
10312  {
10313  *lperror = TRUE;
10314  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10315  }
10316  else
10317  {
10318  SCIP_CALL( retcode );
10319  }
10320  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10321  totalIterations = iterations;
10322 
10323  /* stop timing */
10324  if( lp->diving || lp->probing )
10325  {
10326  if( lp->strongbranchprobing )
10327  SCIPclockStop(stat->strongbranchtime, set);
10328  else
10329  SCIPclockStop(stat->divinglptime, set);
10330  }
10331  else
10332  {
10333  timedelta += SCIPclockGetTime(stat->duallptime);
10334  SCIPclockStop(stat->duallptime, set);
10335  }
10336 
10337  /* count number of iterations */
10338  SCIPstatIncrement(stat, set, lpcount);
10339  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10340  {
10341  if( lp->strongbranchprobing )
10342  {
10343  SCIPstatAdd(stat, set, nlpiterations, iterations);
10344  }
10345  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10346  {
10347  SCIPstatIncrement(stat, set, ndualresolvelps);
10348  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10349  }
10350  if( lp->diving || lp->probing )
10351  {
10352  if( lp->strongbranchprobing )
10353  {
10354  SCIPstatIncrement(stat, set, nsbdivinglps);
10355  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10356  }
10357  else
10358  {
10359  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10360  SCIPstatIncrement(stat, set, ndivinglps);
10361  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10362  }
10363  }
10364  else
10365  {
10366  SCIPstatIncrement(stat, set, nduallps);
10367  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10368  }
10369  }
10370  else
10371  {
10372  if ( ! lp->diving && ! lp->probing )
10373  {
10374  SCIPstatIncrement(stat, set, ndualzeroitlps);
10375  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10376  }
10377  }
10378  lexIterations = 0;
10379 
10380  /* search for lexicographically minimal optimal solution */
10381  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10382  {
10383  SCIP_Bool chooseBasic;
10384  SCIP_Real* primsol;
10385  SCIP_Real* dualsol;
10386  SCIP_Real* redcost;
10387  int* cstat;
10388  int* rstat;
10389  SCIP_Real* newobj;
10390  SCIP_Real* newlb;
10391  SCIP_Real* newub;
10392  SCIP_Real* newlhs;
10393  SCIP_Real* newrhs;
10394  SCIP_Real* oldlb;
10395  SCIP_Real* oldub;
10396  SCIP_Real* oldlhs;
10397  SCIP_Real* oldrhs;
10398  SCIP_Real* oldobj;
10399  SCIP_Bool* fixedc;
10400  SCIP_Bool* fixedr;
10401  int* indcol;
10402  int* indrow;
10403  int* indallcol;
10404  int* indallrow;
10405  int nDualDeg;
10406  int r, c;
10407  int cntcol;
10408  int cntrow;
10409  int nruns;
10410  int pos;
10411 
10412  chooseBasic = set->lp_lexdualbasic;
10413 
10414  /* start timing */
10415  SCIPclockStart(stat->lexduallptime, set);
10416 
10417  /* get all solution information */
10418  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10419  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10420  if( chooseBasic )
10421  {
10422  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10423  }
10424  else
10425  primsol = NULL;
10426 
10427  /* get basic and nonbasic information */
10428  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10429  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10430 
10431  /* save bounds, lhs/rhs, and objective */
10432  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10433  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10434  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10435  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10436  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10437  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10438  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10439  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10440 
10441  /* get storage for several arrays */
10442  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10443  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10444  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10445 
10446  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10447  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10448  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10449 
10450  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10451  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10452 
10453  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10454  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10455 
10456  /* initialize: set objective to 0, get fixed variables */
10457  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10458  for( c = 0; c < lp->nlpicols; ++c )
10459  {
10460  newobj[c] = 0.0;
10461  indallcol[c] = c;
10462  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10463  fixedc[c] = TRUE;
10464  else
10465  fixedc[c] = FALSE;
10466  }
10467 
10468  /* initialize: get fixed slack variables */
10469  for( r = 0; r < lp->nlpirows; ++r )
10470  {
10471  indallrow[r] = r;
10472  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10473  fixedr[r] = TRUE;
10474  else
10475  fixedr[r] = FALSE;
10476  }
10477 
10478 #ifdef DEBUG_LEXDUAL
10479  {
10480  int j;
10481 
10482  if( !chooseBasic )
10483  {
10484  assert(primsol == NULL);
10485  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10486  }
10487  assert(primsol != NULL);
10488  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10489  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10490 
10491  for( j = 0; j < lp->nlpicols; ++j )
10492  {
10493  if( fixedc[j] )
10494  {
10495  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10496  }
10497  else
10498  {
10499  char type;
10500  switch( (SCIP_BASESTAT) cstat[j] )
10501  {
10502  case SCIP_BASESTAT_LOWER:
10503  type = 'l';
10504  break;
10505  case SCIP_BASESTAT_UPPER:
10506  type = 'u';
10507  break;
10508  case SCIP_BASESTAT_ZERO:
10509  type = 'z';
10510  break;
10511  case SCIP_BASESTAT_BASIC:
10512  type = 'b';
10513  break;
10514  default:
10515  type = '?';
10516  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10517  SCIPABORT();
10518  }
10519  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10520  }
10521  }
10522  SCIPsetDebugMsg(set, "\n\n");
10523 
10524  if( !chooseBasic )
10525  {
10526  SCIPsetFreeBufferArray(set, &primsol);
10527  assert(primsol == NULL);
10528  }
10529  }
10530 #endif
10531 
10532  /* perform lexicographic rounds */
10533  pos = -1;
10534  nruns = 0;
10535  rounds = 0;
10536  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10537  do
10538  {
10539  int oldpos;
10540 
10541  /* get current solution */
10542  if( chooseBasic )
10543  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10544  else
10545  {
10546  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10547  assert(primsol == NULL);
10548  }
10549 
10550  /* get current basis */
10551  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10552 
10553  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10554  nDualDeg = 0;
10555  cntcol = 0;
10556  oldpos = pos;
10557  pos = -1;
10558  for( c = 0; c < lp->nlpicols; ++c )
10559  {
10560  if( !fixedc[c] )
10561  {
10562  /* check whether variable is in basis */
10563  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10564  {
10565  /* store first candidate */
10566  if( pos == -1 && c > oldpos )
10567  {
10568  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10569  pos = c;
10570  }
10571  }
10572  else
10573  {
10574  /* reduced cost == 0 -> possible candidate */
10575  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10576  {
10577  ++nDualDeg;
10578  /* only if we have not yet found a candidate */
10579  if( pos == -1 && c > oldpos )
10580  {
10581  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10582  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10583  {
10584  newlb[cntcol] = oldlb[c];
10585  newub[cntcol] = oldlb[c];
10586  indcol[cntcol++] = c;
10587  fixedc[c] = TRUE;
10588  }
10589  else /* found a non-fixed candidate */
10590  {
10591  if( !chooseBasic )
10592  pos = c;
10593  }
10594  }
10595  }
10596  else
10597  {
10598  /* nonzero reduced cost -> variable can be fixed */
10599  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10600  {
10601  newlb[cntcol] = oldlb[c];
10602  newub[cntcol] = oldlb[c];
10603  }
10604  else
10605  {
10606  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10607  {
10608  newlb[cntcol] = oldub[c];
10609  newub[cntcol] = oldub[c];
10610  }
10611  else
10612  {
10613  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10614  newlb[cntcol] = 0.0;
10615  newub[cntcol] = 0.0;
10616  }
10617  }
10618  indcol[cntcol++] = c;
10619  fixedc[c] = TRUE;
10620  }
10621  }
10622  }
10623  }
10624 
10625  /* check rows */
10626  cntrow = 0;
10627  for( r = 0; r < lp->nlpirows; ++r )
10628  {
10629  if( !fixedr[r] )
10630  {
10631  /* consider only nonbasic rows */
10632  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
10633  {
10634  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
10635  if( SCIPsetIsFeasZero(set, dualsol[r]) )
10636  ++nDualDeg;
10637  else
10638  {
10639  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
10640  {
10641  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
10642  newlhs[cntrow] = oldlhs[r];
10643  newrhs[cntrow] = oldlhs[r];
10644  }
10645  else
10646  {
10647  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
10648  newlhs[cntrow] = oldrhs[r];
10649  newrhs[cntrow] = oldrhs[r];
10650  }
10651  indrow[cntrow++] = r;
10652  fixedr[r] = TRUE;
10653  }
10654  }
10655  }
10656  }
10657 
10658  if( nDualDeg > 0 && pos >= 0 )
10659  {
10660  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
10661 
10662  /* change objective */
10663  if( nruns == 0 )
10664  {
10665  /* set objective to appropriate unit vector for first run */
10666  newobj[pos] = 1.0;
10667  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
10668  }
10669  else
10670  {
10671  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
10672  SCIP_Real obj = 1.0;
10673  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
10674  }
10675 
10676  /* fix variables */
10677  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
10678  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
10679 
10680  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
10681  retcode = SCIPlpiSolvePrimal(lp->lpi);
10682  if( retcode == SCIP_LPERROR )
10683  {
10684  *lperror = TRUE;
10685  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10686  }
10687  else
10688  {
10689  SCIP_CALL( retcode );
10690  }
10691  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10692  lexIterations += iterations;
10693 
10694 #ifdef DEBUG_LEXDUAL
10695  if( iterations > 0 )
10696  {
10697  int j;
10698 
10699  if( !chooseBasic )
10700  {
10701  assert(primsol == NULL);
10702  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10703  }
10704  assert(primsol != NULL);
10705  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10706 
10707  for( j = 0; j < lp->nlpicols; ++j )
10708  {
10709  if( fixedc[j] )
10710  {
10711  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10712  }
10713  else
10714  {
10715  char cstart = '[';
10716  char cend = ']';
10717  char type;
10718 
10719  if(j == pos)
10720  {
10721  cstart = '*';
10722  cend = '*';
10723  }
10724 
10725  switch( (SCIP_BASESTAT) cstat[j] )
10726  {
10727  case SCIP_BASESTAT_LOWER:
10728  type = 'l';
10729  break;
10730  case SCIP_BASESTAT_UPPER:
10731  type = 'u';
10732  break;
10733  case SCIP_BASESTAT_ZERO:
10734  type = 'z';
10735  break;
10736  case SCIP_BASESTAT_BASIC:
10737  type = 'b';
10738  break;
10739  default:
10740  type = '?';
10741  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
10742  SCIPABORT();
10743  }
10744  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
10745  }
10746  }
10747  SCIPsetDebugMsg(set, "\n\n");
10748 
10749  if( !chooseBasic )
10750  {
10751  SCIPsetFreeBufferArray(set, &primsol);
10752  assert(primsol == NULL);
10753  }
10754  }
10755 #endif
10756 
10757  /* count only as round if iterations have been performed */
10758  if( iterations > 0 )
10759  ++rounds;
10760  ++nruns;
10761  }
10762  }
10763  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
10764 
10765  /* reset bounds, lhs/rhs, and obj */
10766  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
10767  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
10768  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
10769 
10770  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
10771  retcode = SCIPlpiSolveDual(lp->lpi);
10772  if( retcode == SCIP_LPERROR )
10773  {
10774  *lperror = TRUE;
10775  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10776  }
10777  else
10778  {
10779  SCIP_CALL( retcode );
10780  }
10781  assert(SCIPlpiIsOptimal(lp->lpi));
10782  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10783  lexIterations += iterations;
10784 
10785  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
10786 
10787  /* count number of iterations */
10788  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
10789  SCIPstatIncrement(stat, set, nlps);
10790 
10791  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10792  {
10793  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
10794  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10795  {
10796  SCIPstatIncrement(stat, set, nlexdualresolvelps);
10797  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
10798  }
10799  SCIPstatIncrement(stat, set, nlexduallps);
10800  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
10801 
10802  totalIterations += lexIterations;
10803  }
10804 
10805  /* free space */
10806  SCIPsetFreeBufferArray(set, &newobj);
10807 
10808  SCIPsetFreeBufferArray(set, &fixedr);
10809  SCIPsetFreeBufferArray(set, &fixedc);
10810 
10811  SCIPsetFreeBufferArray(set, &indallrow);
10812  SCIPsetFreeBufferArray(set, &indallcol);
10813 
10814  SCIPsetFreeBufferArray(set, &indrow);
10815  SCIPsetFreeBufferArray(set, &newrhs);
10816  SCIPsetFreeBufferArray(set, &newlhs);
10817 
10818  SCIPsetFreeBufferArray(set, &indcol);
10819  SCIPsetFreeBufferArray(set, &newub);
10820  SCIPsetFreeBufferArray(set, &newlb);
10821 
10822  SCIPsetFreeBufferArray(set, &oldobj);
10823  SCIPsetFreeBufferArray(set, &oldrhs);
10824  SCIPsetFreeBufferArray(set, &oldlhs);
10825  SCIPsetFreeBufferArray(set, &oldub);
10826  SCIPsetFreeBufferArray(set, &oldlb);
10827 
10828  SCIPsetFreeBufferArray(set, &rstat);
10829  SCIPsetFreeBufferArray(set, &cstat);
10830 
10831  SCIPsetFreeBufferArray(set, &redcost);
10832  SCIPsetFreeBufferArray(set, &dualsol);
10833  if( chooseBasic )
10834  SCIPsetFreeBufferArray(set, &primsol);
10835 
10836  /* stop timing */
10837  SCIPclockStop(stat->lexduallptime, set);
10838 
10839  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10840  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10841  }
10843  lp->solisbasic = TRUE;
10844 
10845  if( totalIterations > 0 && !lp->strongbranchprobing )
10846  SCIPstatIncrement(stat, set, nlps);
10847  else
10848  {
10849  if( keepsol && !(*lperror) )
10850  {
10851  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10852  if( lp->validsollp == stat->lpcount-1 )
10853  lp->validsollp = stat->lpcount;
10854  if( lp->validfarkaslp == stat->lpcount-1 )
10855  lp->validfarkaslp = stat->lpcount;
10856  }
10857  }
10858 
10859  return SCIP_OKAY;
10860 }
10861 
10862 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
10863 static
10865  SCIP_LP* lp, /**< current LP data */
10866  SCIP_SET* set, /**< global SCIP settings */
10867  SCIP_STAT* stat, /**< problem statistics */
10868  SCIP_Bool crossover, /**< should crossover be performed? */
10869  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10870  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10871  )
10872 {
10873  SCIP_Real timedelta;
10874  SCIP_RETCODE retcode;
10875  int iterations;
10876 
10877  assert(lp != NULL);
10878  assert(lp->flushed);
10879  assert(set != NULL);
10880  assert(stat != NULL);
10881  assert(lperror != NULL);
10882 
10883  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",
10884  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
10885  stat->nbarrierlps, stat->ndivinglps);
10886 
10887  *lperror = FALSE;
10888 
10889 #if 0 /* for debugging: write all root node LP's */
10890  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10891  {
10892  char fname[SCIP_MAXSTRLEN];
10893  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10894  SCIP_CALL( SCIPlpWrite(lp, fname) );
10895  SCIPsetDebugMsg("wrote LP to file <%s> (barrier, uobjlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10896  fname, lp->lpiuobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
10897  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10898  }
10899 #endif
10900 
10901  /* start timing */
10902  if( lp->diving || lp->probing )
10903  {
10904  if( lp->strongbranchprobing )
10905  SCIPclockStart(stat->strongbranchtime, set);
10906  else
10907  SCIPclockStart(stat->divinglptime, set);
10908 
10909  timedelta = 0.0; /* unused for diving or probing */
10910  }
10911  else
10912  {
10913  SCIPclockStart(stat->barrierlptime, set);
10914  timedelta = -SCIPclockGetTime(stat->duallptime);
10915  }
10916 
10917  /* call barrier algorithm */
10918  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
10919  if( retcode == SCIP_LPERROR )
10920  {
10921  *lperror = TRUE;
10922  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10923  }
10924  else
10925  {
10926  SCIP_CALL( retcode );
10927  }
10929  lp->solisbasic = crossover;
10930 
10931  /* stop timing */
10932  if( lp->diving || lp->probing )
10933  {
10934  if( lp->strongbranchprobing )
10935  SCIPclockStop(stat->strongbranchtime, set);
10936  else
10937  SCIPclockStop(stat->divinglptime, set);
10938  }
10939  else
10940  {
10941  SCIPclockStop(stat->barrierlptime, set);
10942  timedelta = -SCIPclockGetTime(stat->duallptime);
10943  }
10944 
10945  /* count number of iterations */
10946  SCIPstatIncrement(stat, set, lpcount);
10947  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10948  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10949  {
10950  if( !lp->strongbranchprobing )
10951  {
10952  SCIPstatIncrement(stat, set, nlps);
10953  SCIPstatAdd(stat, set, nlpiterations, iterations);
10954  }
10955  if( lp->diving || lp->probing )
10956  {
10957  if( lp->strongbranchprobing )
10958  {
10959  SCIPstatIncrement(stat, set, nsbdivinglps);
10960  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10961  }
10962  else
10963  {
10964  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10965  SCIPstatIncrement(stat, set, ndivinglps);
10966  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10967  }
10968  }
10969  else
10970  {
10971  SCIPstatIncrement(stat, set, nbarrierlps);
10972  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
10973  }
10974  }
10975  else
10976  {
10977  if ( ! lp->diving && ! lp->probing )
10978  {
10979  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
10980  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
10981  }
10982 
10983  if( keepsol && !(*lperror) )
10984  {
10985  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10986  if( lp->validsollp == stat->lpcount-1 )
10987  lp->validsollp = stat->lpcount;
10988  if( lp->validfarkaslp == stat->lpcount-1 )
10989  lp->validfarkaslp = stat->lpcount;
10990  }
10991  }
10992 
10993  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
10994  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
10995 
10996  return SCIP_OKAY;
10997 }
10998 
10999 /** solves the LP with the given algorithm */
11000 static
11002  SCIP_LP* lp, /**< current LP data */
11003  SCIP_SET* set, /**< global SCIP settings */
11004  SCIP_STAT* stat, /**< problem statistics */
11005  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11006  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11007  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11008  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11009  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11010  )
11011 {
11012  SCIP_Real lptimelimit;
11013  SCIP_Bool success;
11014 
11015  assert(lp != NULL);
11016  assert(lp->flushed);
11017  assert(lperror != NULL);
11018 
11019  /* check if a time limit is set, and set time limit for LP solver accordingly */
11020  lptimelimit = SCIPlpiInfinity(lp->lpi);
11021  if( set->istimelimitfinite )
11022  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11023 
11024  success = FALSE;
11025  if( lptimelimit > 0.0 )
11026  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11027 
11028  if( lptimelimit <= 0.0 || !success )
11029  {
11030  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11031  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11032  *timelimit = TRUE;
11033  return SCIP_OKAY;
11034  }
11035  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %f seconds\n", lpalgoName(lpalgo), lptimelimit);
11036 
11037  /* call appropriate LP algorithm */
11038  switch( lpalgo )
11039  {
11041  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, lperror) );
11042  break;
11043 
11045  /* run dual lexicographic simplex if required */
11046  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11047  {
11048  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11049  }
11050  else
11051  {
11052  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11053  }
11054  break;
11055 
11056  case SCIP_LPALGO_BARRIER:
11057  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11058  break;
11059 
11061  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11062  break;
11063 
11064  default:
11065  SCIPerrorMessage("invalid LP algorithm\n");
11066  return SCIP_INVALIDDATA;
11067  }
11068 
11069  if( !(*lperror) )
11070  {
11071  /* check for primal and dual feasibility */
11073 
11074  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11075  }
11076 
11077  return SCIP_OKAY;
11078 }
11079 
11080 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11081  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11082  */
11083 #define MAXNUMTROUBLELPMSGS 10
11084 
11085 /** prints message about numerical trouble
11086  *
11087  * If message has verblevel at most high and display/verblevel is not full,
11088  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11089  * were printed before in the current run.
11090  */
11091 static
11093  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11094  SCIP_SET* set, /**< global SCIP settings */
11095  SCIP_STAT* stat, /**< problem statistics */
11096  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11097  const char* formatstr, /**< message format string */
11098  ... /**< arguments to format string */
11099  )
11100 {
11101  va_list ap;
11102 
11103  assert(verblevel > SCIP_VERBLEVEL_NONE);
11104  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11105  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11106 
11107  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11108  {
11109  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11110  {
11111  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11113  return;
11114 
11115  /* increase count on messages with verblevel high */
11116  ++stat->nnumtroublelpmsgs ;
11117  }
11118 
11119  /* if messages wouldn't be printed, then return already */
11120  if( verblevel > set->disp_verblevel )
11121  return;
11122  }
11123 
11124  /* print common begin of message */
11125  SCIPmessagePrintInfo(messagehdlr,
11126  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11127  stat->nnodes, stat->nlps);
11128 
11129  /* print individual part of message */
11130  va_start(ap, formatstr); /*lint !e838*/
11131  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11132  va_end(ap);
11133 
11134  /* warn that further messages will be suppressed */
11135  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11136  {
11137  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11138  }
11139 
11140  /* print closing new-line */
11141  SCIPmessagePrintInfo(messagehdlr, "\n");
11142 }
11143 
11144 #define FEASTOLTIGHTFAC 0.001
11145 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11146 static
11148  SCIP_LP* lp, /**< current LP data */
11149  SCIP_SET* set, /**< global SCIP settings */
11150  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11151  SCIP_STAT* stat, /**< problem statistics */
11152  SCIP_PROB* prob, /**< problem data */
11153  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11154  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11155  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11156  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11157  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11158  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11159  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11160  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11161  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11162  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11163  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11164  )
11165 {
11166  SCIP_Bool success;
11167  SCIP_Bool success2;
11168  SCIP_Bool success3;
11169  SCIP_Bool simplex;
11170  SCIP_Bool itlimishard;
11171  SCIP_Bool usepolishing;
11172 
11173  assert(lp != NULL);
11174  assert(lp->flushed);
11175  assert(set != NULL);
11176  assert(stat != NULL);
11177  assert(lperror != NULL);
11178  assert(timelimit != NULL);
11179 
11180  *lperror = FALSE;
11181 
11182  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11183  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11184  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11185  * SCIP_LP such that we can return a primal ray
11186  */
11187  if( lp->looseobjvalinf > 0 )
11188  {
11189  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11190  return SCIP_ERROR;
11191  }
11192 
11193  /* check, whether we solve with a simplex algorithm */
11194  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11195 
11196  /* check whether the iteration limit is a hard one */
11197  itlimishard = (itlim == harditlim);
11198 
11199  /* check whether solution polishing should be used */
11200  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)))
11201  {
11202  usepolishing = TRUE;
11203  if( lp->updateintegrality )
11204  {
11205  SCIP_CALL( lpCopyIntegrality(lp, set) );
11206  }
11207  }
11208  else
11209  usepolishing = FALSE;
11210 
11211  /* solve with given settings (usually fast but imprecise) */
11212  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11213  {
11214  SCIP_CALL( lpSetUobjlim(lp, set, lp->cutoffbound) );
11215  }
11216  else
11217  {
11218  SCIP_CALL( lpSetUobjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) );
11219  }
11220  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11221  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * SCIPsetLpfeastol(set) : SCIPsetLpfeastol(set), &success) );
11222  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11223  &success) );
11224  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11225  : SCIPsetBarrierconvtol(set), &success) );
11226  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11227  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11228  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11229  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11230  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11231  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11232  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11233  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11234  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11235  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11236  SCIP_CALL( lpSetRandomseed(lp, SCIPsetInitializeRandomSeed(set, set->random_randomseed), &success) );
11237  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11238  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11239  resolve = FALSE; /* only the first solve should be counted as resolving call */
11240 
11241  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11242  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11243  return SCIP_OKAY;
11244  else if( !set->lp_checkstability )
11245  {
11246  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11247  if( success )
11248  {
11249  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11250  return SCIP_OKAY;
11251  }
11252  }
11253 
11254  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11255  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11256  */
11257 
11258  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11259  * do this only if the iteration limit was not exceeded in the last LP solving call
11260  */
11261  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11262  {
11263  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11264  if( success )
11265  {
11266  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11267  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11268 
11269  /* check for stability */
11270  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11271  return SCIP_OKAY;
11272  else if( !set->lp_checkstability )
11273  {
11274  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11275  if( success )
11276  {
11277  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11278  return SCIP_OKAY;
11279  }
11280  }
11281  }
11282  }
11283 
11284  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11285  * and go directly to solving the LP from scratch
11286  */
11287  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11288  {
11289  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11290  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11291  if( success )
11292  {
11293  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling", lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11294  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11295 
11296  /* check for stability */
11297  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11298  return SCIP_OKAY;
11299  else if( !set->lp_checkstability )
11300  {
11301  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11302  if( success )
11303  {
11304  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11305  return SCIP_OKAY;
11306  }
11307  }
11308 
11309  /* reset scaling */
11310  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11311  assert(success);
11312  }
11313  }
11314 
11315  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11316  * and go directly to solving the LP from scratch
11317  */
11318  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11319  {
11320  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11321  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11322  if( success )
11323  {
11324  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11325  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11326  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11327 
11328  /* check for stability */
11329  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11330  return SCIP_OKAY;
11331  else if( !set->lp_checkstability )
11332  {
11333  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11334  if( success )
11335  {
11336  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11337  return SCIP_OKAY;
11338  }
11339  }
11340 
11341  /* reset presolving */
11342  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11343  assert(success);
11344  }
11345  }
11346 
11347  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11348  * do this only if the iteration limit was not exceeded in the last LP solving call
11349  */
11350  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11351  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11352  {
11353  success = FALSE;
11354  if( !tightprimfeastol )
11355  {
11356  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11357  }
11358 
11359  success2 = FALSE;
11360  if( !tightdualfeastol )
11361  {
11363  }
11364 
11365  success3 = FALSE;
11366  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11367  {
11369  }
11370 
11371  if( success || success2 || success3 )
11372  {
11373  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance", lpalgoName(lpalgo));
11374  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11375 
11376  /* check for stability */
11377  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11378  return SCIP_OKAY;
11379  else if( !set->lp_checkstability )
11380  {
11381  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11382  if( success )
11383  {
11384  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11385  return SCIP_OKAY;
11386  }
11387  }
11388 
11389  /* reset feasibility tolerance */
11390  if( !tightprimfeastol )
11391  {
11392  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11393  }
11394  if( !tightdualfeastol )
11395  {
11396  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11397  }
11398  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11399  {
11400  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11401  }
11402  }
11403  }
11404 
11405  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11406  * the given iteration limit might be a soft one to restrict resolving calls only */
11407  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11408 
11409  /* if not already done, solve again from scratch */
11410  if( !fromscratch && simplex )
11411  {
11412  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11413  if( success )
11414  {
11415  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11416  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11417 
11418  /* check for stability */
11419  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11420  return SCIP_OKAY;
11421  else if( !set->lp_checkstability )
11422  {
11423  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11424  if( success )
11425  {
11426  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11427  return SCIP_OKAY;
11428  }
11429  }
11430  }
11431  }
11432 
11433  /* solve again, use other simplex this time */
11434  if( simplex )
11435  {
11437  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11438  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11439 
11440  /* check for stability */
11441  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11442  return SCIP_OKAY;
11443  else if( !set->lp_checkstability )
11444  {
11445  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11446  if( success )
11447  {
11448  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11449  return SCIP_OKAY;
11450  }
11451  }
11452 
11453  /* solve again with opposite scaling and other simplex */
11454  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11455  if( success )
11456  {
11457  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11458  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11459  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11460 
11461  /* check for stability */
11462  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11463  return SCIP_OKAY;
11464  else if( !set->lp_checkstability )
11465  {
11466  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11467  if( success )
11468  {
11469  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11470  return SCIP_OKAY;
11471  }
11472  }
11473 
11474  /* reset scaling */
11475  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11476  assert(success);
11477  }
11478 
11479  /* solve again with opposite presolving and other simplex */
11480  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11481  if( success )
11482  {
11483  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11484  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11485  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11486 
11487  /* check for stability */
11488  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11489  return SCIP_OKAY;
11490  else if( !set->lp_checkstability )
11491  {
11492  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11493  if( success )
11494  {
11495  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11496  return SCIP_OKAY;
11497  }
11498  }
11499 
11500  /* reset presolving */
11501  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11502  assert(success);
11503  }
11504 
11505  /* solve again with tighter feasibility tolerance, use other simplex this time */
11506  if( !tightprimfeastol || !tightdualfeastol )
11507  {
11508  success = FALSE;
11509  if( !tightprimfeastol )
11510  {
11511  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11512  }
11513 
11514  success2 = FALSE;
11515  if( !tightdualfeastol )
11516  {
11518  }
11519 
11520  if( success || success2 )
11521  {
11522  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance", lpalgoName(lpalgo));
11523  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, timelimit, lperror) );
11524 
11525  /* check for stability */
11526  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11527  return SCIP_OKAY;
11528  else if( !set->lp_checkstability )
11529  {
11530  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11531  if( success )
11532  {
11533  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11534  return SCIP_OKAY;
11535  }
11536  }
11537 
11538  /* reset feasibility tolerance */
11539  if( !tightprimfeastol )
11540  {
11541  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11542  }
11543  if( !tightdualfeastol )
11544  {
11545  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11546  }
11547  }
11548  }
11549  }
11550 
11551  /* nothing worked -- exit with an LPERROR */
11552  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11553  *lperror = TRUE;
11554 
11555  return SCIP_OKAY;
11556 }
11557 
11558 /** adjust the LP objective value if its greater/less than +/- SCIPsetInfinity() */
11559 static
11561  SCIP_LP* lp, /**< current LP data */
11562  SCIP_SET* set, /**< global SCIP settings */
11563  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11564  )
11565 {
11566  assert(lp != NULL);
11567  assert(set != NULL);
11568 
11569  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11570  {
11571  if( !lp->adjustlpval )
11572  {
11573  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11574  lp->adjustlpval = TRUE;
11575  }
11576  lp->lpobjval = SCIPsetInfinity(set);
11577  }
11578  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11579  {
11580  if( !lp->adjustlpval )
11581  {
11582  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11583  lp->adjustlpval = TRUE;
11584  }
11585  lp->lpobjval = -SCIPsetInfinity(set);
11586  }
11587 }
11588 
11589 /** solves the LP with the given algorithm and evaluates return status */
11590 static
11592  SCIP_LP* lp, /**< current LP data */
11593  SCIP_SET* set, /**< global SCIP settings */
11594  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11595  SCIP_STAT* stat, /**< problem statistics */
11596  SCIP_PROB* prob, /**< problem data */
11597  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11598  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11599  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11600  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11601  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11602  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11603  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11604  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11605  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11606  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11607  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11608  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11609  )
11610 {
11611  SCIP_Bool solvedprimal;
11612  SCIP_Bool solveddual;
11613  SCIP_Bool timelimit;
11614  int itlim;
11615 
11616  assert(lp != NULL);
11617  assert(lp->flushed);
11618  assert(set != NULL);
11619  assert(stat != NULL);
11620  assert(lperror != NULL);
11621 
11622  checkLinks(lp);
11623 
11624  solvedprimal = FALSE;
11625  solveddual = FALSE;
11626  timelimit = FALSE;
11627 
11628  /* select the basic iteration limit depending on whether this is a resolving call or not */
11629  itlim = ( resolve ? resolveitlim : harditlim );
11630 
11631  SOLVEAGAIN:
11632  /* call simplex */
11633  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11634  keepsol, &timelimit, lperror) );
11635  resolve = FALSE; /* only the first solve should be counted as resolving call */
11636  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11637  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11638 
11639  /* check, if an error occurred */
11640  if( *lperror )
11641  {
11642  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11643  lp->solved = FALSE;
11645  return SCIP_OKAY;
11646  }
11647 
11648  /* check, if a time limit was exceeded */
11649  if( timelimit )
11650  {
11651  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11652  lp->solved = TRUE;
11654  lp->lpobjval = -SCIPsetInfinity(set);
11655  return SCIP_OKAY;
11656  }
11657 
11658  /* only one should return true */
11659  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11661 
11662  /* evaluate solution status */
11663  if( SCIPlpiIsOptimal(lp->lpi) )
11664  {
11665  assert(lp->primalfeasible);
11666  assert(lp->dualfeasible);
11668  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11669  adjustLPobjval(lp, set, messagehdlr);
11670 
11671  if( !SCIPsetIsInfinity(set, lp->lpiuobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) )
11672  {
11673  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11674  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiuobjlim);
11676  lp->lpobjval = SCIPsetInfinity(set);
11677  }
11678  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11679  * reached if the LP objective value is greater than the cutoff bound
11680  */
11682  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11683  }
11684  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11685  {
11686  assert(!lpCutoffDisabled(set));
11688  lp->lpobjval = SCIPsetInfinity(set);
11689  }
11690  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11691  {
11692  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11693  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11694  {
11695  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11696  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11697  goto SOLVEAGAIN;
11698  }
11700  lp->lpobjval = SCIPsetInfinity(set);
11701  }
11702  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11703  {
11704  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11705  if( needprimalray && !SCIPlpiHasPrimalRay(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11706  {
11707  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11708  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11709  goto SOLVEAGAIN;
11710  }
11712  lp->lpobjval = -SCIPsetInfinity(set);
11713  }
11714  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11715  {
11716  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11717  adjustLPobjval(lp, set, messagehdlr);
11719  }
11720  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11721  {
11722  lp->lpobjval = -SCIPsetInfinity(set);
11724  }
11725  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11726  {
11727  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11728  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11729  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11730  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11731  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11732  goto SOLVEAGAIN;
11733  }
11734  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11735  {
11736  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11737  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11738  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11739  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11740  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11741  goto SOLVEAGAIN;
11742  }
11743  else
11744  {
11745  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
11746  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
11748  return SCIP_LPERROR;
11749  }
11750 
11751  lp->solved = TRUE;
11752 
11753  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
11756 
11757  return SCIP_OKAY;
11758 }
11759 
11760 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
11761 static
11763  SCIP_LP* lp, /**< current LP data */
11764  BMS_BLKMEM* blkmem, /**< block memory */
11765  SCIP_SET* set, /**< global SCIP settings */
11766  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11767  SCIP_STAT* stat, /**< problem statistics */
11768  SCIP_PROB* prob, /**< problem data */
11769  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11770  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11771  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11772  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11773  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11774  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11775  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11776  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11777  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11778  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11779  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11780  )
11781 {
11782  SCIP_Bool resolve;
11783  char algo;
11784 
11785  assert(lp != NULL);
11786  assert(set != NULL);
11787  assert(lperror != NULL);
11788 
11789  /* flush changes to the LP solver */
11790  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
11791  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
11792 
11793  /* select LP algorithm to apply */
11794  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
11795  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
11796 
11797  switch( algo )
11798  {
11799  case 's':
11800  /* select simplex method */
11801  if( lp->dualfeasible || !lp->primalfeasible )
11802  {
11803  SCIPsetDebugMsg(set, "solving dual LP\n");
11804  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11805  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11806  }
11807  else
11808  {
11809  SCIPsetDebugMsg(set, "solving primal LP\n");
11810  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11811  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11812  }
11813  break;
11814 
11815  case 'p':
11816  SCIPsetDebugMsg(set, "solving primal LP\n");
11817  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
11818  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11819  break;
11820 
11821  case 'd':
11822  SCIPsetDebugMsg(set, "solving dual LP\n");
11823  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
11824  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11825  break;
11826 
11827  case 'b':
11828  SCIPsetDebugMsg(set, "solving barrier LP\n");
11829  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
11830  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11831  break;
11832 
11833  case 'c':
11834  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
11835  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
11836  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
11837  break;
11838 
11839  default:
11840  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
11841  return SCIP_PARAMETERWRONGVAL;
11842  }
11843  assert(!(*lperror) || !lp->solved);
11844 
11845  return SCIP_OKAY;
11846 }
11847 
11848 #ifndef NDEBUG
11849 /** checks if the lazy bounds are valid */
11850 static
11852  SCIP_LP* lp, /**< LP data */
11853  SCIP_SET* set /**< global SCIP settings */
11854  )
11855 {
11856  SCIP_COL* col;
11857  int c;
11858 
11859  assert(lp->flushed);
11860 
11861  for( c = 0; c < lp->nlazycols; ++c )
11862  {
11863  col = lp->lazycols[c];
11864 
11865  /* in case lazy bounds are given, check that the primal solution satisfies them */
11866  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
11867  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
11868  }
11869 }
11870 #else
11871 #define checkLazyBounds(lp, set) /**/
11872 #endif
11873 
11874 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
11875  * diving
11876  */
11877 static
11879  SCIP_LP* lp, /**< LP data */
11880  SCIP_SET* set /**< global SCIP settings */
11881  )
11882 {
11883  SCIP_COL* col;
11884  int c;
11885 
11886  assert(lp->nlazycols > 0);
11887 
11888  /* return, if we are in diving, and bounds were already applied
11889  * or if we are not in diving and bounds were not applied
11890  */
11891  if( lp->diving == lp->divinglazyapplied )
11892  return SCIP_OKAY;
11893 
11894  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
11895  lp->diving, lp->divinglazyapplied);
11896 
11897  for( c = 0; c < lp->nlazycols; ++c )
11898  {
11899  col = lp->lazycols[c];
11900 
11901  /* if the column has a lazy lower bound, mark its lower bounds as changed */
11902  if( !SCIPsetIsInfinity(set, -col->lazylb) )
11903  {
11904  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
11905  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
11906  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11907 
11908  /* insert column in the chgcols list (if not already there) */
11909  SCIP_CALL( insertColChgcols(col, set, lp) );
11910 
11911  /* mark bound change in the column */
11912  col->lbchanged = TRUE;
11913  }
11914 
11915  /* if the column has a lazy upper bound, mark its upper bounds as changed */
11916  if( !SCIPsetIsInfinity(set, col->lazyub) )
11917  {
11918  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
11919  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
11920  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
11921 
11922  /* insert column in the chgcols list (if not already there) */
11923  SCIP_CALL( insertColChgcols(col, set, lp) );
11924 
11925  /* mark bound change in the column */
11926  col->ubchanged = TRUE;
11927  }
11928  }
11929 
11930  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
11931  * if not, we just removed them
11932  */
11933  lp->divinglazyapplied = lp->diving;
11934 
11935  return SCIP_OKAY;
11936 }
11937 
11938 /** returns the iteration limit for an LP resolving call */
11939 static
11941  SCIP_SET* set, /**< global SCIP settings */
11942  SCIP_STAT* stat, /**< dynamic problem statistics */
11943  int itlim /**< hard iteration limit */
11944  )
11945 {
11946  /* no limit set or average not yet reliable */
11947  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
11948  return itlim;
11949  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
11950  if( itlim == -1 )
11951  itlim = INT_MAX;
11952  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
11953  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
11954  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
11955 }
11956 
11957 
11958 
11959 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
11961  SCIP_LP* lp, /**< LP data */
11962  SCIP_SET* set, /**< global SCIP settings */
11963  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11964  BMS_BLKMEM* blkmem, /**< block memory buffers */
11965  SCIP_STAT* stat, /**< problem statistics */
11966  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
11967  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
11968  SCIP_PROB* prob, /**< problem data */
11969  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
11970  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
11971  * (limit is computed within the method w.r.t. the average LP iterations) */
11972  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
11973  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11974  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11975  )
11976 {
11977  SCIP_RETCODE retcode;
11978  SCIP_Bool needprimalray;
11979  SCIP_Bool needdualray;
11980  int harditlim;
11981  int resolveitlim;
11982 
11983  assert(lp != NULL);
11984  assert(prob != NULL);
11985  assert(prob->nvars >= lp->ncols);
11986  assert(lperror != NULL);
11987 
11988  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
11989  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
11990 
11991  retcode = SCIP_OKAY;
11992  *lperror = FALSE;
11993 
11994  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
11995  needprimalray = TRUE;
11996  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
11997  || (set->conf_enable && set->conf_useinflp != 'o'));
11998 
11999  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12000  harditlim = (int) MIN(itlim, INT_MAX);
12001  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12002  assert(harditlim == -1 || (resolveitlim <= harditlim));
12003 
12004  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12005  * or removed from the LP (diving was ended)
12006  */
12007  if( lp->nlazycols > 0 )
12008  {
12009  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12010  * first resolve LP?
12011  */
12012  SCIP_CALL( updateLazyBounds(lp, set) );
12013  assert(lp->diving == lp->divinglazyapplied);
12014  }
12015 
12016  /* flush changes to the LP solver */
12017  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12018  assert(lp->flushed);
12019 
12020  /* 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
12021  * to run again anyway, since there seems to be some time left / the time limit was increased
12022  */
12023  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12024  {
12025  SCIP_Bool* primalfeaspointer;
12026  SCIP_Bool* dualfeaspointer;
12027  SCIP_Bool primalfeasible;
12028  SCIP_Bool dualfeasible;
12029  SCIP_Bool rayfeasible;
12030  SCIP_Bool tightprimfeastol;
12031  SCIP_Bool tightdualfeastol;
12032  SCIP_Bool fromscratch;
12033  SCIP_Bool wasfromscratch;
12034  SCIP_Longint oldnlps;
12035  int fastmip;
12036 
12037  /* set initial LP solver settings */
12038  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12039  tightprimfeastol = FALSE;
12040  tightdualfeastol = FALSE;
12041  fromscratch = FALSE;
12042  primalfeasible = FALSE;
12043  dualfeasible = FALSE;
12044  wasfromscratch = (stat->nlps == 0);
12045 
12046  SOLVEAGAIN:
12047  /* solve the LP */
12048  oldnlps = stat->nlps;
12049  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12050  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12051  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12052  assert(!(*lperror) || !lp->solved);
12053 
12054  /* check for error */
12055  if( *lperror )
12056  {
12057  retcode = SCIP_OKAY;
12058  goto TERMINATE;
12059  }
12060 
12061  /* evaluate solution status */
12062  switch( SCIPlpGetSolstat(lp) )
12063  {
12065  /* get LP solution and possibly check the solution's feasibility again */
12066  if( set->lp_checkprimfeas )
12067  {
12068  primalfeaspointer = &primalfeasible;
12069  lp->primalchecked = TRUE;
12070  }
12071  else
12072  {
12073  /* believe in the primal feasibility of the LP solution */
12074  primalfeasible = TRUE;
12075  primalfeaspointer = NULL;
12076  lp->primalchecked = FALSE;
12077  }
12078  if( set->lp_checkdualfeas )
12079  {
12080  dualfeaspointer = &dualfeasible;
12081  lp->dualchecked = TRUE;
12082  }
12083  else
12084  {
12085  /* believe in the dual feasibility of the LP solution */
12086  dualfeasible = TRUE;
12087  dualfeaspointer = NULL;
12088  lp->dualchecked = FALSE;
12089  }
12090 
12091  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12092 
12093  /* in debug mode, check that lazy bounds (if present) are not violated */
12094  checkLazyBounds(lp, set);
12095 
12096  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12097  {
12098  /* update ages and remove obsolete columns and rows from LP */
12099  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12100  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12101  {
12102  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12103  }
12104 
12105  if( !lp->solved )
12106  {
12107  /* resolve LP after removing obsolete columns and rows */
12108  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12109  aging = FALSE; /* to prevent infinite loops */
12110  goto SOLVEAGAIN;
12111  }
12112  }
12113  if( !primalfeasible || !dualfeasible )
12114  {
12116 
12117  if( (fastmip > 0) && simplex )
12118  {
12119  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12120  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12121  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12122  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12123  fastmip = 0;
12124  goto SOLVEAGAIN;
12125  }
12126  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12127  {
12128  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12129  * tolerance
12130  */
12131  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12132  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12133  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12134  tightprimfeastol = tightprimfeastol || !primalfeasible;
12135  tightdualfeastol = tightdualfeastol || !dualfeasible;
12136  goto SOLVEAGAIN;
12137  }
12138  else if( !fromscratch && !wasfromscratch && simplex )
12139  {
12140  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12141  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12142  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12143  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12144  fromscratch = TRUE;
12145  goto SOLVEAGAIN;
12146  }
12147  else
12148  {
12149  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12150  lp->solved = FALSE;
12152  *lperror = TRUE;
12153  }
12154  }
12155  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12156  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12157  lp->lpsolstat, lp->cutoffbound);
12158  break;
12159 
12161  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12162  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12163  {
12164  if( SCIPlpiHasDualRay(lp->lpi) )
12165  {
12166  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12167  }
12168  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12169  * with the primal simplex due to numerical problems) - treat this case like an LP error
12170  */
12171  else
12172  {
12173  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12174  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12175  lp->solved = FALSE;
12177  *lperror = TRUE;
12178  }
12179  }
12180  break;
12181 
12183  if( set->lp_checkprimfeas )
12184  {
12185  /* get unbounded LP solution and check the solution's feasibility again */
12186  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12187 
12188  lp->primalchecked = TRUE;
12189  }
12190  else
12191  {
12192  /* get unbounded LP solution believing in the feasibility of the LP solution */
12193  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12194 
12195  primalfeasible = TRUE;
12196  rayfeasible = TRUE;
12197  lp->primalchecked = FALSE;
12198  }
12199 
12200  /* in debug mode, check that lazy bounds (if present) are not violated */
12201  checkLazyBounds(lp, set);
12202 
12203  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12204  primalfeasible, rayfeasible);
12205 
12206  if( !primalfeasible || !rayfeasible )
12207  {
12209 
12210  if( (fastmip > 0) && simplex )
12211  {
12212  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12213  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12214  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12215  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12216  fastmip = 0;
12217  goto SOLVEAGAIN;
12218  }
12219  else if( !tightprimfeastol )
12220  {
12221  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12222  * tolerance
12223  */
12224  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12225  "(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",
12226  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12227  tightprimfeastol = TRUE;
12228  goto SOLVEAGAIN;
12229  }
12230  else if( !fromscratch && simplex )
12231  {
12232  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12233  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12234  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12235  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12236  fromscratch = TRUE;
12237  goto SOLVEAGAIN;
12238  }
12239  else
12240  {
12241  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12242  * forget about the LP at this node and mark it to be unsolved
12243  */
12244  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12245  lp->solved = FALSE;
12247  *lperror = TRUE;
12248  }
12249  }
12250 
12251  break;
12252 
12254  assert(!lpCutoffDisabled(set));
12255  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12256  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12257  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12258  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12259  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12260  * FASTMIP and solve again.
12261  */
12262  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12263  {
12264  SCIP_LPI* lpi;
12265  SCIP_Real objval;
12266 
12267  lpi = SCIPlpGetLPI(lp);
12268 
12269  assert(lpi != NULL);
12270  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12271  * the assert by using !SCIPsetIsFeasNegative()
12272  */
12273  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiuobjlim));
12274 
12275  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12276 
12277  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12278  if( SCIPsetIsLT(set, objval, lp->lpiuobjlim) )
12279  {
12280  SCIP_Real tmpcutoff;
12281  char tmppricingchar;
12282  SCIP_LPSOLSTAT solstat;
12283 
12284  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiuobjlim, but status objlimit\n", objval, lp->lpiuobjlim);
12285 
12286  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12287  fromscratch = FALSE;
12288 
12289  /* temporarily disable cutoffbound, which also disables the objective limit */
12290  tmpcutoff = lp->cutoffbound;
12291  lp->cutoffbound = SCIPlpiInfinity(lpi);
12292 
12293  /* set lp pricing strategy to steepest edge */
12294  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12295  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12296 
12297  /* resolve LP with an iteration limit of 1 */
12298  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12299  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12300 
12301  /* reinstall old cutoff bound and lp pricing strategy */
12302  lp->cutoffbound = tmpcutoff;
12303  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12304 
12305  /* get objective value */
12306  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12307 
12308  /* get solution status for the lp */
12309  solstat = SCIPlpGetSolstat(lp);
12310  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12311 
12312  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12313  {
12314  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12315  }
12316 
12317  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12318  fastmip = 0;
12319 
12320  /* the solution is still not exceeding the objective limit and the solving process
12321  * was stopped due to time or iteration limit, solve again with fastmip turned off
12322  */
12323  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12324  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12325  {
12326  assert(!(*lperror));
12327 
12328  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12329  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12330 
12331  /* get objective value */
12332  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12333 
12334  /* get solution status for the lp */
12335  solstat = SCIPlpGetSolstat(lp);
12336 
12337  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12338  }
12339 
12340  /* check for lp errors */
12341  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12342  {
12343  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12344  lp->solved = FALSE;
12346 
12347  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12348  goto TERMINATE;
12349  }
12350 
12351  lp->solved = TRUE;
12352 
12353  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12354  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12355  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12356  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12357  {
12358  /* get LP solution and possibly check the solution's feasibility again */
12359  if( set->lp_checkprimfeas )
12360  {
12361  primalfeaspointer = &primalfeasible;
12362  lp->primalchecked = TRUE;
12363  }
12364  else
12365  {
12366  /* believe in the primal feasibility of the LP solution */
12367  primalfeasible = TRUE;
12368  primalfeaspointer = NULL;
12369  lp->primalchecked = FALSE;
12370  }
12371  if( set->lp_checkdualfeas )
12372  {
12373  dualfeaspointer = &dualfeasible;
12374  lp->dualchecked = TRUE;
12375  }
12376  else
12377  {
12378  /* believe in the dual feasibility of the LP solution */
12379  dualfeasible = TRUE;
12380  dualfeaspointer = NULL;
12381  lp->dualchecked = FALSE;
12382  }
12383 
12384  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12385 
12386  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12387  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12388  {
12389  checkLazyBounds(lp, set);
12390  }
12391 
12392  /* if objective value is larger than the cutoff bound, set solution status to objective
12393  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12394  * this was already done in the lpSolve() method
12395  */
12396  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12397  {
12399  lp->lpobjval = SCIPsetInfinity(set);
12400  }
12401 
12402  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12403  * the cutoffbound; mark the LP to be unsolved
12404  */
12405  if( !primalfeasible || !dualfeasible
12406  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12407  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12408  {
12409  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12410  lp->solved = FALSE;
12412  *lperror = TRUE;
12413  }
12414 
12415  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12416  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12417  lp->lpsolstat, lp->cutoffbound);
12418  }
12419  /* infeasible solution */
12420  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12421  {
12422  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
12423  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12424  }
12425  /* unbounded solution */
12426  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12427  {
12428  if( set->lp_checkprimfeas )
12429  {
12430  /* get unbounded LP solution and check the solution's feasibility again */
12431  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12432 
12433  lp->primalchecked = TRUE;
12434  }
12435  else
12436  {
12437  /* get unbounded LP solution believing in its feasibility */
12438  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12439 
12440  primalfeasible = TRUE;
12441  rayfeasible = TRUE;
12442  lp->primalchecked = FALSE;
12443  }
12444 
12445  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12446 
12447  /* in debug mode, check that lazy bounds (if present) are not violated */
12448  checkLazyBounds(lp, set);
12449 
12450  if( !primalfeasible || !rayfeasible )
12451  {
12452  /* unbounded solution is infeasible (this can happen due to numerical problems):
12453  * forget about the LP at this node and mark it to be unsolved
12454 
12455  * @todo: like in the default LP solving evaluation, solve without fastmip,
12456  * with tighter feasibility tolerance and from scratch
12457  */
12458  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12459  lp->solved = FALSE;
12461  *lperror = TRUE;
12462  }
12463 
12464  }
12465 
12466  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12467  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12469  }
12470  else
12471  {
12472  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12473  }
12474  }
12475  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12476  {
12477  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12478  }
12479  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12480  break;
12481 
12483  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12484  break;
12485 
12487  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12488 
12489  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12490  stat->nclockskipsleft = 0;
12491  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12492  {
12493  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12494  "you might consider switching the clock type of SCIP\n");
12495  stat->status = SCIP_STATUS_TIMELIMIT;
12496  }
12497  break;
12498 
12499  case SCIP_LPSOLSTAT_ERROR:
12501  SCIPerrorMessage("error in LP solver\n");
12502  retcode = SCIP_LPERROR;
12503  goto TERMINATE;
12504 
12505  default:
12506  SCIPerrorMessage("unknown LP solution status\n");
12507  retcode = SCIP_ERROR;
12508  goto TERMINATE;
12509  }
12510  }
12511  assert(!(*lperror) || !lp->solved);
12512 
12513  TERMINATE:
12514  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12515  * may happen that we continue to solve from scratch during strong branching */
12516  if( lp->lpifromscratch )
12517  {
12518  SCIP_Bool success;
12519  (void) lpSetFromscratch(lp, FALSE, &success);
12520  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12521  }
12522 
12523  return retcode;
12524 }
12525 
12526 /** gets solution status of current LP */
12528  SCIP_LP* lp /**< current LP data */
12529  )
12530 {
12531  assert(lp != NULL);
12532  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12533 
12534  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12535 }
12536 
12537 /** gets objective value of current LP
12538  *
12539  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12540  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12541  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12542  */
12544  SCIP_LP* lp, /**< current LP data */
12545  SCIP_SET* set, /**< global SCIP settings */
12546  SCIP_PROB* prob /**< problem data */
12547  )
12548 {
12549  assert(lp != NULL);
12550  assert(lp->solved);
12551  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12552  assert(set != NULL);
12553 
12554  if( !lp->flushed )
12555  return SCIP_INVALID;
12556  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12557  return lp->lpobjval;
12558  else if( lp->looseobjvalinf > 0 )
12559  return -SCIPsetInfinity(set);
12560  else
12561  {
12562  /* recalculate the loose objective value, if needed */
12563  if( !lp->looseobjvalid )
12564  recomputeLooseObjectiveValue(lp, set, prob);
12565 
12566  return lp->lpobjval + lp->looseobjval;
12567  }
12568 }
12569 
12570 /** gets part of objective value of current LP that results from COLUMN variables only */
12572  SCIP_LP* lp /**< current LP data */
12573  )
12574 {
12575  assert(lp != NULL);
12576  assert(lp->solved);
12577 
12578  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12579 }
12580 
12581 /** gets part of objective value of current LP that results from LOOSE variables only */
12583  SCIP_LP* lp, /**< current LP data */
12584  SCIP_SET* set, /**< global SCIP settings */
12585  SCIP_PROB* prob /**< problem data */
12586  )
12587 {
12588  assert(lp != NULL);
12589  assert(lp->solved);
12590  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12591  assert(set != NULL);
12592 
12593  if( !lp->flushed )
12594  return SCIP_INVALID;
12595  else if( lp->looseobjvalinf > 0 )
12596  return -SCIPsetInfinity(set);
12597  else
12598  return getFiniteLooseObjval(lp, set, prob);
12599 }
12600 
12601 /** remembers the current LP objective value as root solution value */
12603  SCIP_LP* lp, /**< current LP data */
12604  SCIP_SET* set, /**< global SCIP settings */
12605  SCIP_PROB* prob /**< problem data */
12606  )
12607 {
12608  assert(lp != NULL);
12609 
12611  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12612 }
12613 
12614 /** invalidates the root LP solution value */
12616  SCIP_LP* lp /**< current LP data */
12617  )
12618 {
12619  assert(lp != NULL);
12620 
12621  lp->rootlpobjval = SCIP_INVALID;
12623 }
12624 
12625 /** recomputes local and global pseudo objective values */
12627  SCIP_LP* lp, /**< current LP data */
12628  SCIP_SET* set, /**< global SCIP settings */
12629  SCIP_PROB* prob /**< problem data */
12630  )
12631 {
12632  SCIP_VAR** vars;
12633  int nvars;
12634  int v;
12635 
12636  assert(lp != NULL);
12637  assert(set != NULL);
12638  assert(prob != NULL);
12639 
12640  vars = prob->vars;
12641  nvars = prob->nvars;
12642 
12643  lp->glbpseudoobjvalinf = 0;
12644  lp->glbpseudoobjval = 0.0;
12645 
12646  lp->pseudoobjvalinf = 0;
12647  lp->pseudoobjval = 0.0;
12648 
12649  for( v = 0; v < nvars; ++v )
12650  {
12651  SCIP_Real obj = SCIPvarGetObj(vars[v]);
12652 
12653  if( SCIPsetIsPositive(set, obj) )
12654  {
12655  /* update the global pseudo objective value */
12656  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
12657  ++(lp->glbpseudoobjvalinf);
12658  else
12659  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
12660 
12661  /* update the local pseudo objective value */
12662  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
12663  ++(lp->pseudoobjvalinf);
12664  else
12665  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
12666  }
12667 
12668  if( SCIPsetIsNegative(set, obj) )
12669  {
12670  /* update the global pseudo objective value */
12671  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
12672  ++(lp->glbpseudoobjvalinf);
12673  else
12674  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
12675 
12676  /* update the local pseudo objective value */
12677  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
12678  ++(lp->pseudoobjvalinf);
12679  else
12680  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
12681  }
12682  }
12683 
12684  /* the recomputed values are reliable */
12686  lp->glbpseudoobjvalid = TRUE;
12687  lp->relpseudoobjval = lp->pseudoobjval;
12688  lp->pseudoobjvalid = TRUE;
12689 }
12690 
12691 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
12692  * global bound
12693  */
12695  SCIP_LP* lp, /**< current LP data */
12696  SCIP_SET* set, /**< global SCIP settings */
12697  SCIP_PROB* prob /**< problem data */
12698  )
12699 {
12700  assert(lp != NULL);
12701  assert(lp->glbpseudoobjvalinf >= 0);
12702  assert(set != NULL);
12703 
12704  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
12705  return -SCIPsetInfinity(set);
12706  else
12707  {
12708  /* recalculate the global pseudo solution value, if needed */
12709  if( !lp->glbpseudoobjvalid )
12710  recomputeGlbPseudoObjectiveValue(lp, set, prob);
12711 
12712  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
12713  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
12714  return -SCIPsetInfinity(set);
12715 
12716  return lp->glbpseudoobjval;
12717  }
12718 }
12719 
12720 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
12721  * objective function) local bound
12722  */
12724  SCIP_LP* lp, /**< current LP data */
12725  SCIP_SET* set, /**< global SCIP settings */
12726  SCIP_PROB* prob /**< problem data */
12727  )
12728 {
12729  assert(lp != NULL);
12730  assert(lp->pseudoobjvalinf >= 0);
12731  assert(set != NULL);
12732 
12733  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12734  return -SCIPsetInfinity(set);
12735  else
12736  {
12737  /* recalculate the pseudo solution value, if needed */
12738  if( !lp->pseudoobjvalid )
12739  recomputePseudoObjectiveValue(lp, set, prob);
12740 
12741  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
12742  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
12743  return -SCIPsetInfinity(set);
12744 
12745  return lp->pseudoobjval;
12746  }
12747 }
12748 
12749 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
12751  SCIP_LP* lp, /**< current LP data */
12752  SCIP_SET* set, /**< global SCIP settings */
12753  SCIP_PROB* prob, /**< problem data */
12754  SCIP_VAR* var, /**< problem variable */
12755  SCIP_Real oldbound, /**< old value for bound */
12756  SCIP_Real newbound, /**< new value for bound */
12757  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12758  )
12759 {
12760  SCIP_Real pseudoobjval;
12761  int pseudoobjvalinf;
12762  SCIP_Real obj;
12763 
12764  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
12765  pseudoobjvalinf = lp->pseudoobjvalinf;
12766  obj = SCIPvarGetObj(var);
12767  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12768  {
12769  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12770  pseudoobjvalinf--;
12771  else
12772  pseudoobjval -= oldbound * obj;
12773  assert(pseudoobjvalinf >= 0);
12774  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12775  pseudoobjvalinf++;
12776  else
12777  pseudoobjval += newbound * obj;
12778  }
12779  assert(pseudoobjvalinf >= 0);
12780 
12781  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12782  return -SCIPsetInfinity(set);
12783  else
12784  return pseudoobjval;
12785 }
12786 
12787 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
12788  * perform calculations with interval arithmetic to get an exact lower bound
12789  */
12791  SCIP_LP* lp, /**< current LP data */
12792  SCIP_SET* set, /**< global SCIP settings */
12793  SCIP_VAR* var, /**< problem variable */
12794  SCIP_Real oldbound, /**< old value for bound */
12795  SCIP_Real newbound, /**< new value for bound */
12796  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
12797  )
12798 {
12799  SCIP_Real pseudoobjval;
12800  int pseudoobjvalinf;
12801  SCIP_Real obj;
12802 
12803  assert(lp->pseudoobjvalid);
12804 
12805  pseudoobjval = lp->pseudoobjval;
12806  pseudoobjvalinf = lp->pseudoobjvalinf;
12807  obj = SCIPvarGetObj(var);
12808  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
12809  {
12810  SCIP_INTERVAL objint;
12811  SCIP_INTERVAL bd;
12812  SCIP_INTERVAL prod;
12813  SCIP_INTERVAL psval;
12814 
12815  SCIPintervalSet(&psval, pseudoobjval);
12816  SCIPintervalSet(&objint, SCIPvarGetObj(var));
12817 
12818  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
12819  pseudoobjvalinf--;
12820  else
12821  {
12822  SCIPintervalSet(&bd, oldbound);
12823  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12824  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
12825  }
12826  assert(pseudoobjvalinf >= 0);
12827  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
12828  pseudoobjvalinf++;
12829  else
12830  {
12831  SCIPintervalSet(&bd, newbound);
12832  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
12833  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
12834  }
12835 
12836  pseudoobjval = SCIPintervalGetInf(psval);
12837  }
12838  assert(pseudoobjvalinf >= 0);
12839 
12840  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
12841  return -SCIPsetInfinity(set);
12842  else
12843  return pseudoobjval;
12844 }
12845 
12846 /** compute the objective delta due the new objective coefficient */
12847 static
12849  SCIP_SET* set, /**< global SCIP settings */
12850  SCIP_Real oldobj, /**< old objective value of variable */
12851  SCIP_Real newobj, /**< new objective value of variable */
12852  SCIP_Real lb, /**< lower bound of variable */
12853  SCIP_Real ub, /**< upper bound of variable */
12854  SCIP_Real* deltaval, /**< pointer to store the delta value */
12855  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12856  )
12857 {
12858  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
12859  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
12860  assert(!SCIPsetIsInfinity(set, lb));
12861  assert(!SCIPsetIsInfinity(set, -ub));
12862  assert(!SCIPsetIsEQ(set, oldobj, newobj));
12863 
12864  (*deltaval) = 0.0;
12865  (*deltainf) = 0;
12866 
12867  if( SCIPsetIsPositive(set, oldobj) )
12868  {
12869  /* sign of objective did not change */
12870  if( SCIPsetIsPositive(set, newobj) )
12871  {
12872  /* if the bound is finite, calculate the deltaval */
12873  if( !SCIPsetIsInfinity(set, -lb) )
12874  (*deltaval) = lb * (newobj - oldobj);
12875  }
12876  /* sign of objective did change, so the best bound does change */
12877  else if( SCIPsetIsNegative(set, newobj) )
12878  {
12879  if( SCIPsetIsInfinity(set, -lb) )
12880  {
12881  /* old best bound was infinite while new one is not */
12882  if( !SCIPsetIsInfinity(set, ub) )
12883  {
12884  (*deltainf) = -1;
12885  (*deltaval) = ub * newobj;
12886  }
12887  }
12888  else
12889  {
12890  /* new best bound is infinite while old one was not */
12891  if( SCIPsetIsInfinity(set, ub) )
12892  {
12893  (*deltainf) = 1;
12894  (*deltaval) = -lb * oldobj;
12895  }
12896  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12897  else
12898  {
12899  (*deltaval) = (ub * newobj) - (lb * oldobj);
12900  }
12901  }
12902  }
12903  /* new objective is 0.0 */
12904  else
12905  {
12906  if( SCIPsetIsInfinity(set, -lb) )
12907  (*deltainf) = -1;
12908  else
12909  (*deltaval) = -lb * oldobj;
12910  }
12911 
12912  }
12913  else if( SCIPsetIsNegative(set, oldobj) )
12914  {
12915  /* sign of objective did not change */
12916  if( SCIPsetIsNegative(set, newobj) )
12917  {
12918  /* if the bound is finite, calculate the deltaval */
12919  if( !SCIPsetIsInfinity(set, ub) )
12920  (*deltaval) = ub * (newobj - oldobj);
12921  }
12922  /* sign of objective did change, so the best bound does change */
12923  else if( SCIPsetIsPositive(set, newobj) )
12924  {
12925  if( SCIPsetIsInfinity(set, ub) )
12926  {
12927  /* old best bound was infinite while new one is not */
12928  if( !SCIPsetIsInfinity(set, -lb) )
12929  {
12930  (*deltainf) = -1;
12931  (*deltaval) = lb * newobj;
12932  }
12933  }
12934  else
12935  {
12936  /* new best bound is infinite while old one was not */
12937  if( SCIPsetIsInfinity(set, -lb) )
12938  {
12939  (*deltainf) = 1;
12940  (*deltaval) = -ub * oldobj;
12941  }
12942  /* neither old nor new best bound is infinite, so just calculate the deltaval */
12943  else
12944  {
12945  (*deltaval) = (lb * newobj) - (ub * oldobj);
12946  }
12947  }
12948  }
12949  /* new objective is 0.0 */
12950  else
12951  {
12952  if( SCIPsetIsInfinity(set, ub) )
12953  (*deltainf) = -1;
12954  else
12955  (*deltaval) = -ub * oldobj;
12956  }
12957  }
12958  /* old objective was 0.0 */
12959  else
12960  {
12961  if( SCIPsetIsNegative(set, newobj) )
12962  {
12963  if( SCIPsetIsInfinity(set, ub) )
12964  (*deltainf) = 1;
12965  else
12966  (*deltaval) = ub * newobj;
12967  }
12968  else if( SCIPsetIsPositive(set, newobj) )
12969  {
12970  if( SCIPsetIsInfinity(set, -lb) )
12971  (*deltainf) = 1;
12972  else
12973  (*deltaval) = lb * newobj;
12974  }
12975  }
12976 }
12977 
12978 /** compute the objective delta due the new lower bound */
12979 static
12981  SCIP_SET* set, /**< global SCIP settings */
12982  SCIP_Real obj, /**< objective value of variable */
12983  SCIP_Real oldlb, /**< old lower bound of variable */
12984  SCIP_Real newlb, /**< new lower bound of variable */
12985  SCIP_Real* deltaval, /**< pointer to store the delta value */
12986  int* deltainf /**< pointer to store the number of variables with infinite best bound */
12987  )
12988 {
12989  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
12990  assert(!SCIPsetIsInfinity(set, oldlb));
12991  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
12992  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
12993 
12994  if( SCIPsetIsInfinity(set, -oldlb) )
12995  {
12996  if( !SCIPsetIsInfinity(set, newlb) )
12997  {
12998  (*deltainf) = -1;
12999  (*deltaval) = newlb * obj;
13000  }
13001  else
13002  {
13003  (*deltainf) = 0;
13004  (*deltaval) = 0.0;
13005  }
13006  }
13007  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13008  {
13009  (*deltainf) = 1;
13010  (*deltaval) = -oldlb * obj;
13011  }
13012  else
13013  {
13014  (*deltainf) = 0;
13015  (*deltaval) = obj * (newlb - oldlb);
13016  }
13017 }
13018 
13019 /** compute the objective delta due the new upper bound */
13020 static
13022  SCIP_SET* set, /**< global SCIP settings */
13023  SCIP_Real obj, /**< objective value of variable */
13024  SCIP_Real oldub, /**< old upper bound of variable */
13025  SCIP_Real newub, /**< new upper bound of variable */
13026  SCIP_Real* deltaval, /**< pointer to store the delta value */
13027  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13028  )
13029 {
13030  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13031  assert(!SCIPsetIsInfinity(set, -oldub));
13032  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13033  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13034 
13035  if( SCIPsetIsInfinity(set, oldub) )
13036  {
13037  if( !SCIPsetIsInfinity(set, -newub) )
13038  {
13039  (*deltainf) = -1;
13040  (*deltaval) = newub * obj;
13041  }
13042  else
13043  {
13044  (*deltainf) = 0;
13045  (*deltaval) = 0.0;
13046  }
13047  }
13048  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13049  {
13050  (*deltainf) = 1;
13051  (*deltaval) = -oldub * obj;
13052  }
13053  else
13054  {
13055  (*deltainf) = 0;
13056  (*deltaval) = obj * (newub - oldub);
13057  }
13058 }
13059 
13060 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13061 static
13063  SCIP_LP* lp, /**< current LP data */
13064  SCIP_SET* set, /**< global SCIP settings */
13065  SCIP_VAR* var, /**< problem variable that changed */
13066  SCIP_Real deltaval, /**< delta value in the objective function */
13067  int deltainf, /**< delta value for the number of variables with infinite best bound */
13068  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13069  SCIP_Bool loose, /**< should the loose objective value be updated? */
13070  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13071  )
13072 {
13073  assert(lp != NULL);
13074  assert(lp->looseobjvalinf >= 0);
13075  assert(lp->pseudoobjvalinf >= 0);
13076  assert(lp->glbpseudoobjvalinf >= 0);
13077 
13078  /* update the pseudo objective value */
13079  if( local )
13080  {
13081  lp->pseudoobjvalinf += deltainf;
13082  if( lp->pseudoobjvalid )
13083  {
13084  lp->pseudoobjval += deltaval;
13085 
13086  /* if the absolute value was increased, this is regarded as reliable,
13087  * otherwise, we check whether we can still trust the updated value
13088  */
13089  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13090  lp->relpseudoobjval = lp->pseudoobjval;
13091  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13092  lp->pseudoobjvalid = FALSE;
13093  }
13094 
13095  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13097  loose = TRUE;
13098  }
13099  /* update the loose objective value */
13100  if( loose )
13101  {
13102  lp->looseobjvalinf += deltainf;
13103 
13104  if( deltaval != 0.0 && lp->looseobjvalid )
13105  {
13106  lp->looseobjval += deltaval;
13107 
13108  /* if the absolute value was increased, this is regarded as reliable,
13109  * otherwise, we check whether we can still trust the updated value
13110  */
13111  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13112  lp->rellooseobjval = lp->looseobjval;
13113  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13114  lp->looseobjvalid = FALSE;
13115  }
13116  }
13117  /* update the root pseudo objective values */
13118  if( global )
13119  {
13120  lp->glbpseudoobjvalinf += deltainf;
13121  if( lp->glbpseudoobjvalid )
13122  {
13123  lp->glbpseudoobjval += deltaval;
13124 
13125  /* if the absolute value was increased, this is regarded as reliable,
13126  * otherwise, we check whether we can still trust the updated value
13127  */
13131  lp->glbpseudoobjvalid = FALSE;
13132  }
13133  }
13134 
13135  assert(lp->looseobjvalinf >= 0);
13136  assert(lp->pseudoobjvalinf >= 0);
13137  assert(lp->glbpseudoobjvalinf >= 0);
13138 }
13139 
13140 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13141  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13142  */
13143 static
13145  SCIP_LP* lp, /**< current LP data */
13146  SCIP_SET* set, /**< global SCIP settings */
13147  SCIP_VAR* var, /**< problem variable that changed */
13148  SCIP_Real oldobj, /**< old objective value of variable */
13149  SCIP_Real oldlb, /**< old objective value of variable */
13150  SCIP_Real oldub, /**< old objective value of variable */
13151  SCIP_Real newobj, /**< new objective value of variable */
13152  SCIP_Real newlb, /**< new objective value of variable */
13153  SCIP_Real newub /**< new objective value of variable */
13154  )
13155 {
13156  SCIP_INTERVAL deltaval;
13157  SCIP_INTERVAL bd;
13158  SCIP_INTERVAL obj;
13159  SCIP_INTERVAL prod;
13160  SCIP_INTERVAL psval;
13161  int deltainf;
13162 
13163  assert(lp != NULL);
13164  assert(lp->pseudoobjvalinf >= 0);
13165  assert(lp->looseobjvalinf >= 0);
13166  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13167  assert(!SCIPsetIsInfinity(set, oldlb));
13168  assert(!SCIPsetIsInfinity(set, -oldub));
13169  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13170  assert(!SCIPsetIsInfinity(set, newlb));
13171  assert(!SCIPsetIsInfinity(set, -newub));
13172  assert(var != NULL);
13173 
13175  {
13176  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13177  return SCIP_INVALIDDATA;
13178  }
13179 
13180  assert(SCIPvarGetProbindex(var) >= 0);
13181 
13182  SCIPintervalSet(&deltaval, 0.0);
13183  deltainf = 0;
13184 
13185  /* subtract old pseudo objective value */
13186  if( oldobj > 0.0 )
13187  {
13188  if( SCIPsetIsInfinity(set, -oldlb) )
13189  deltainf--;
13190  else
13191  {
13192  SCIPintervalSet(&bd, oldlb);
13193  SCIPintervalSet(&obj, oldobj);
13194  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13195  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13196  }
13197  }
13198  else if( oldobj < 0.0 )
13199  {
13200  if( SCIPsetIsInfinity(set, oldub) )
13201  deltainf--;
13202  else
13203  {
13204  SCIPintervalSet(&bd, oldub);
13205  SCIPintervalSet(&obj, oldobj);
13206  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13207  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13208  }
13209  }
13210 
13211  /* add new pseudo objective value */
13212  if( newobj > 0.0 )
13213  {
13214  if( SCIPsetIsInfinity(set, -newlb) )
13215  deltainf++;
13216  else
13217  {
13218  SCIPintervalSet(&bd, newlb);
13219  SCIPintervalSet(&obj, newobj);
13220  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13221  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13222  }
13223  }
13224  else if( newobj < 0.0 )
13225  {
13226  if( SCIPsetIsInfinity(set, newub) )
13227  deltainf++;
13228  else
13229  {
13230  SCIPintervalSet(&bd, newub);
13231  SCIPintervalSet(&obj, newobj);
13232  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13233  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13234  }
13235  }
13236 
13237  /* update the pseudo and loose objective values */
13238  SCIPintervalSet(&psval, lp->pseudoobjval);
13239  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13240  lp->pseudoobjval = SCIPintervalGetInf(psval);
13241  lp->pseudoobjvalinf += deltainf;
13243  {
13244  SCIPintervalSet(&psval, lp->looseobjval);
13245  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13246  lp->looseobjval = SCIPintervalGetInf(psval);
13247  lp->looseobjvalinf += deltainf;
13248  }
13249 
13250  assert(lp->pseudoobjvalinf >= 0);
13251  assert(lp->looseobjvalinf >= 0);
13252 
13253  return SCIP_OKAY;
13254 }
13255 
13256 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13258  SCIP_LP* lp, /**< current LP data */
13259  SCIP_SET* set, /**< global SCIP settings */
13260  SCIP_VAR* var, /**< problem variable that changed */
13261  SCIP_Real oldobj, /**< old objective value of variable */
13262  SCIP_Real newobj /**< new objective value of variable */
13263  )
13264 {
13265  assert(set != NULL);
13266  assert(var != NULL);
13267 
13268  if( set->misc_exactsolve )
13269  {
13270  if( oldobj != newobj ) /*lint !e777*/
13271  {
13272  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13273  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13274  }
13275  }
13276  else
13277  {
13278  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13279  {
13280  SCIP_Real deltaval;
13281  int deltainf;
13282 
13284  assert(SCIPvarGetProbindex(var) >= 0);
13285 
13286  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13287  * domain of the variable are the same
13288  */
13289  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13290  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13291 
13292  /* compute the pseudo objective delta due the new objective coefficient */
13293  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13294 
13295  /* update the local pseudo objective value */
13296  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13297 
13298  /* compute the pseudo objective delta due the new objective coefficient */
13299  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13300 
13301  /* update the global pseudo objective value */
13302  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13303  }
13304  }
13305 
13306  return SCIP_OKAY;
13307 }
13308 
13309 
13310 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13312  SCIP_LP* lp, /**< current LP data */
13313  SCIP_SET* set, /**< global SCIP settings */
13314  SCIP_VAR* var, /**< problem variable that changed */
13315  SCIP_Real oldlb, /**< old lower bound of variable */
13316  SCIP_Real newlb /**< new lower bound of variable */
13317  )
13318 {
13319  assert(set != NULL);
13320  assert(var != NULL);
13321 
13322  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13323  {
13324  SCIP_Real deltaval;
13325  int deltainf;
13326 
13327  /* compute the pseudo objective delta due the new lower bound */
13328  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13329 
13330  /* update the root pseudo objective values */
13331  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13332 
13333  }
13334 
13335  return SCIP_OKAY;
13336 }
13337 
13338 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13340  SCIP_LP* lp, /**< current LP data */
13341  SCIP_SET* set, /**< global SCIP settings */
13342  SCIP_VAR* var, /**< problem variable that changed */
13343  SCIP_Real oldlb, /**< old lower bound of variable */
13344  SCIP_Real newlb /**< new lower bound of variable */
13345  )
13346 {
13347  assert(set != NULL);
13348  assert(var != NULL);
13349 
13350  if( set->misc_exactsolve )
13351  {
13352  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13353  {
13354  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13355  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13356  }
13357  }
13358  else
13359  {
13360  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13361  {
13362  SCIP_Real deltaval;
13363  int deltainf;
13364 
13366  assert(SCIPvarGetProbindex(var) >= 0);
13367 
13368  /* compute the pseudo objective delta due the new lower bound */
13369  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13370 
13371  /* update the pseudo and loose objective values */
13372  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13373  }
13374  }
13375 
13376  return SCIP_OKAY;
13377 }
13378 
13379 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13381  SCIP_LP* lp, /**< current LP data */
13382  SCIP_SET* set, /**< global SCIP settings */
13383  SCIP_VAR* var, /**< problem variable that changed */
13384  SCIP_Real oldub, /**< old upper bound of variable */
13385  SCIP_Real newub /**< new upper bound of variable */
13386  )
13387 {
13388  assert(set != NULL);
13389  assert(var != NULL);
13390 
13391  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13392  {
13393  SCIP_Real deltaval;
13394  int deltainf;
13395 
13396  /* compute the pseudo objective delta due the new upper bound */
13397  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13398 
13399  /* update the root pseudo objective values */
13400  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13401  }
13402 
13403  return SCIP_OKAY;
13404 }
13405 
13406 /** updates current pseudo objective value for a change in a variable's upper bound */
13408  SCIP_LP* lp, /**< current LP data */
13409  SCIP_SET* set, /**< global SCIP settings */
13410  SCIP_VAR* var, /**< problem variable that changed */
13411  SCIP_Real oldub, /**< old upper bound of variable */
13412  SCIP_Real newub /**< new upper bound of variable */
13413  )
13414 {
13415  assert(set != NULL);
13416  assert(var != NULL);
13417 
13418  if( set->misc_exactsolve )
13419  {
13420  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13421  {
13422  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13423  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13424  }
13425  }
13426  else
13427  {
13428  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13429  {
13430  SCIP_Real deltaval;
13431  int deltainf;
13432 
13434  assert(SCIPvarGetProbindex(var) >= 0);
13435 
13436  /* compute the pseudo objective delta due the new upper bound */
13437  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13438 
13439  /* update the pseudo and loose objective values */
13440  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13441  }
13442  }
13443 
13444  return SCIP_OKAY;
13445 }
13446 
13447 /** informs LP, that given variable was added to the problem */
13449  SCIP_LP* lp, /**< current LP data */
13450  SCIP_SET* set, /**< global SCIP settings */
13451  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13452  )
13453 {
13454  assert(lp != NULL);
13456  assert(SCIPvarGetProbindex(var) >= 0);
13457 
13458  /* add the variable to the loose objective value sum */
13459  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13460 
13461  /* update the loose variables counter */
13463  lp->nloosevars++;
13464 
13465  return SCIP_OKAY;
13466 }
13467 
13468 /** informs LP, that given variable is to be deleted from the problem */
13470  SCIP_LP* lp, /**< current LP data */
13471  SCIP_SET* set, /**< global SCIP settings */
13472  SCIP_VAR* var /**< variable that will be deleted from the problem */
13473  )
13474 {
13475  assert(lp != NULL);
13477  assert(SCIPvarGetProbindex(var) >= 0);
13478 
13479  /* subtract the variable from the loose objective value sum */
13480  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13481 
13482  /* update the loose variables counter */
13484  {
13485  SCIPlpDecNLoosevars(lp);
13486  }
13487 
13488  return SCIP_OKAY;
13489 }
13490 
13491 /** informs LP, that given formerly loose problem variable is now a column variable */
13492 static
13494  SCIP_LP* lp, /**< current LP data */
13495  SCIP_SET* set, /**< global SCIP settings */
13496  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13497  )
13498 {
13499  SCIP_Real obj;
13500  SCIP_Real lb;
13501  SCIP_Real ub;
13502 
13503  assert(lp != NULL);
13504  assert(lp->nloosevars > 0);
13505  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13506  assert(SCIPvarGetProbindex(var) >= 0);
13507  assert(lp->looseobjvalinf >= 0);
13508 
13509  obj = SCIPvarGetObj(var);
13510 
13511  /* update loose objective value */
13512  if( SCIPsetIsPositive(set, obj) )
13513  {
13514  lb = SCIPvarGetLbLocal(var);
13515  if( SCIPsetIsInfinity(set, -lb) )
13516  lp->looseobjvalinf--;
13517  else
13518  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13519  }
13520  else if( SCIPsetIsNegative(set, obj) )
13521  {
13522  ub = SCIPvarGetUbLocal(var);
13523  if( SCIPsetIsInfinity(set, ub) )
13524  lp->looseobjvalinf--;
13525  else
13526  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13527  }
13528 
13529  SCIPlpDecNLoosevars(lp);
13530 
13531  assert(lp->looseobjvalinf >= 0);
13532 
13533  return SCIP_OKAY;
13534 }
13535 
13536 /** informs LP, that given formerly loose problem variable is now a column variable
13537  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13538  */
13539 static
13541  SCIP_LP* lp, /**< current LP data */
13542  SCIP_SET* set, /**< global SCIP settings */
13543  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13544  )
13545 {
13546  SCIP_INTERVAL bd;
13547  SCIP_INTERVAL ob;
13548  SCIP_INTERVAL prod;
13549  SCIP_INTERVAL loose;
13550  SCIP_Real obj;
13551  SCIP_Real lb;
13552  SCIP_Real ub;
13553 
13554  assert(lp != NULL);
13555  assert(lp->nloosevars > 0);
13556  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13557  assert(SCIPvarGetProbindex(var) >= 0);
13558 
13559  obj = SCIPvarGetObj(var);
13560 
13561  SCIPintervalSet(&loose, lp->looseobjval);
13562 
13563  /* update loose objective value corresponding to the deletion of variable */
13564  if( obj > 0.0 )
13565  {
13566  lb = SCIPvarGetLbLocal(var);
13567  if( SCIPsetIsInfinity(set, -lb) )
13568  lp->looseobjvalinf--;
13569  else
13570  {
13571  SCIPintervalSet(&bd, lb);
13572  SCIPintervalSet(&ob, obj);
13573  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13574  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13575  }
13576  }
13577  else if( SCIPsetIsNegative(set, obj) )
13578  {
13579  ub = SCIPvarGetUbLocal(var);
13580  if( SCIPsetIsInfinity(set, ub) )
13581  lp->looseobjvalinf--;
13582  else
13583  {
13584  SCIPintervalSet(&bd, ub);
13585  SCIPintervalSet(&ob, obj);
13586  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13587  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13588  }
13589  }
13590  lp->nloosevars--;
13591 
13592  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13593  if( lp->nloosevars == 0 )
13594  {
13595  assert(lp->looseobjvalinf == 0);
13596  lp->looseobjval = 0.0;
13597  }
13598  else
13599  lp->looseobjval = SCIPintervalGetInf(loose);
13600 
13601  return SCIP_OKAY;
13602 }
13603 
13604 /** informs LP, that given formerly loose problem variable is now a column variable */
13606  SCIP_LP* lp, /**< current LP data */
13607  SCIP_SET* set, /**< global SCIP settings */
13608  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13609  )
13610 {
13611  assert(set != NULL);
13612 
13613  if( set->misc_exactsolve )
13614  {
13615  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13616  }
13617  else
13618  {
13619  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13620  }
13621 
13622  return SCIP_OKAY;
13623 }
13624 
13625 /** informs LP, that given formerly column problem variable is now again a loose variable */
13626 static
13628  SCIP_LP* lp, /**< current LP data */
13629  SCIP_SET* set, /**< global SCIP settings */
13630  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13631  )
13632 {
13633  SCIP_Real obj;
13634  SCIP_Real lb;
13635  SCIP_Real ub;
13636 
13637  assert(lp != NULL);
13638  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13639  assert(SCIPvarGetProbindex(var) >= 0);
13640  assert(lp->looseobjvalinf >= 0);
13641 
13642  obj = SCIPvarGetObj(var);
13643 
13644  /* update loose objective value corresponding to the addition of variable */
13645  if( SCIPsetIsPositive(set, obj) )
13646  {
13647  lb = SCIPvarGetLbLocal(var);
13648  if( SCIPsetIsInfinity(set, -lb) )
13649  lp->looseobjvalinf++;
13650  else
13651  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
13652  }
13653  else if( SCIPsetIsNegative(set, obj) )
13654  {
13655  ub = SCIPvarGetUbLocal(var);
13656  if( SCIPsetIsInfinity(set, ub) )
13657  lp->looseobjvalinf++;
13658  else
13659  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
13660  }
13661  lp->nloosevars++;
13662 
13663  assert(lp->looseobjvalinf >= 0);
13664 
13665  return SCIP_OKAY;
13666 }
13667 
13668 /** informs LP, that given formerly column problem variable is now again a loose variable
13669  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13670  */
13671 static
13673  SCIP_LP* lp, /**< current LP data */
13674  SCIP_SET* set, /**< global SCIP settings */
13675  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13676  )
13677 {
13678  SCIP_INTERVAL bd;
13679  SCIP_INTERVAL ob;
13680  SCIP_INTERVAL prod;
13681  SCIP_INTERVAL loose;
13682  SCIP_Real obj;
13683  SCIP_Real lb;
13684  SCIP_Real ub;
13685 
13686  assert(lp != NULL);
13687  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
13688  assert(SCIPvarGetProbindex(var) >= 0);
13689 
13690  obj = SCIPvarGetObj(var);
13691 
13692  SCIPintervalSet(&loose, lp->looseobjval);
13693 
13694  /* update loose objective value corresponding to the deletion of variable */
13695  if( obj > 0.0 )
13696  {
13697  lb = SCIPvarGetLbLocal(var);
13698  if( SCIPsetIsInfinity(set, -lb) )
13699  lp->looseobjvalinf++;
13700  else
13701  {
13702  SCIPintervalSet(&bd, lb);
13703  SCIPintervalSet(&ob, obj);
13704  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13705  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
13706  }
13707  }
13708  else if( SCIPsetIsNegative(set, obj) )
13709  {
13710  ub = SCIPvarGetUbLocal(var);
13711  if( SCIPsetIsInfinity(set, ub) )
13712  lp->looseobjvalinf++;
13713  else
13714  {
13715  SCIPintervalSet(&bd, ub);
13716  SCIPintervalSet(&ob, obj);
13717  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13718  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
13719  }
13720  }
13721  lp->nloosevars++;
13722 
13723  lp->looseobjval = SCIPintervalGetInf(loose);
13724 
13725  return SCIP_OKAY;
13726 }
13727 
13728 /** informs LP, that given formerly column problem variable is now again a loose variable */
13730  SCIP_LP* lp, /**< current LP data */
13731  SCIP_SET* set, /**< global SCIP settings */
13732  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13733  )
13734 {
13735  assert(set != NULL);
13736 
13737  if( set->misc_exactsolve )
13738  {
13739  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
13740  }
13741  else
13742  {
13743  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
13744  }
13745 
13746  return SCIP_OKAY;
13747 }
13748 
13749 /** decrease the number of loose variables by one */
13751  SCIP_LP* lp /**< current LP data */
13752  )
13753 {
13754  assert(lp != NULL);
13755  assert(lp->nloosevars > 0);
13756 
13757  lp->nloosevars--;
13758 
13759  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13760  if( lp->nloosevars == 0 )
13761  {
13762  assert(lp->looseobjvalinf == 0);
13763  lp->looseobjval = 0.0;
13764  }
13765 }
13766 
13767 /** stores the LP solution in the columns and rows */
13769  SCIP_LP* lp, /**< current LP data */
13770  SCIP_SET* set, /**< global SCIP settings */
13771  SCIP_STAT* stat, /**< problem statistics */
13772  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
13773  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
13774  )
13775 {
13776  SCIP_COL** lpicols;
13777  SCIP_ROW** lpirows;
13778  SCIP_Real* primsol;
13779  SCIP_Real* dualsol;
13780  SCIP_Real* activity;
13781  SCIP_Real* redcost;
13782  SCIP_Real primalbound;
13783  SCIP_Real dualbound;
13784  SCIP_Bool stillprimalfeasible;
13785  SCIP_Bool stilldualfeasible;
13786  int* cstat;
13787  int* rstat;
13788  SCIP_Longint lpcount;
13789  int nlpicols;
13790  int nlpirows;
13791  int c;
13792  int r;
13793 
13794  assert(lp != NULL);
13795  assert(lp->flushed);
13796  assert(lp->solved);
13797  assert(set != NULL);
13798  assert(stat != NULL);
13799  assert(lp->validsollp <= stat->lpcount);
13800 
13801  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
13802  * corresponding flag immediately to FALSE to skip all checks
13803  */
13804  if( primalfeasible == NULL )
13805  stillprimalfeasible = FALSE;
13806  else
13807  {
13808  *primalfeasible = TRUE;
13809  stillprimalfeasible = TRUE;
13810  }
13811  if( dualfeasible == NULL )
13812  stilldualfeasible = FALSE;
13813  else
13814  {
13815  *dualfeasible = TRUE;
13816  stilldualfeasible = TRUE;
13817  }
13818 
13819  /* check if the values are already calculated */
13820  if( lp->validsollp == stat->lpcount )
13821  return SCIP_OKAY;
13822  lp->validsollp = stat->lpcount;
13823 
13824  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
13825  stat->lpcount, SCIPlpGetSolstat(lp));
13826 
13827  lpicols = lp->lpicols;
13828  lpirows = lp->lpirows;
13829  nlpicols = lp->nlpicols;
13830  nlpirows = lp->nlpirows;
13831  lpcount = stat->lpcount;
13832 
13833  /* get temporary memory */
13834  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
13835  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
13836  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
13837  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
13838  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
13839  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
13840 
13841  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
13842  if( lp->solisbasic )
13843  {
13844  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
13845  }
13846  else
13847  {
13848  BMSclearMemoryArray(cstat, nlpicols);
13849  BMSclearMemoryArray(rstat, nlpirows);
13850  }
13851 
13852  primalbound = 0.0;
13853  dualbound = 0.0;
13854 
13855  /* copy primal solution and reduced costs into columns */
13856  for( c = 0; c < nlpicols; ++c )
13857  {
13858  assert( 0 <= cstat[c] && cstat[c] < 4 );
13859  lpicols[c]->primsol = primsol[c];
13860  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
13861  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
13862  lpicols[c]->redcost = redcost[c];
13863  lpicols[c]->basisstatus = (unsigned int) cstat[c];
13864  lpicols[c]->validredcostlp = lpcount;
13865  if( stillprimalfeasible )
13866  {
13867  stillprimalfeasible =
13868  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
13869  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
13870  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
13871  }
13872  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13873  {
13874  double compslack;
13875 
13876  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13877  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
13878  * variables, which would magnify even the tiniest violation in the dual multiplier
13879  */
13880  if( stilldualfeasible )
13881  {
13882  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
13883  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13884  }
13885  if( stilldualfeasible )
13886  {
13887  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
13888  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13889  }
13890 
13891  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13892  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13893  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13894  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13895  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13896  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
13897  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
13898  dualfeasible != NULL ? stilldualfeasible : TRUE);
13899  }
13900  else
13901  {
13902  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
13903  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
13904  {
13905  lpicols[c]->redcost = 0.0;
13906  }
13907 
13908  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
13909  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
13910  * bounds, its reduced cost must be zero
13911  */
13912  if( stilldualfeasible
13913  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
13914  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
13915  if( stilldualfeasible
13916  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
13917  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
13918 
13919  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13920  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
13921  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
13922  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
13923  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13924  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
13925  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
13926  dualfeasible != NULL ? stilldualfeasible : TRUE);
13927  }
13928 
13929  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
13930  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
13931  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
13932  */
13933  if( stilldualfeasible )
13934  {
13935  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
13936  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
13937  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
13938  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
13939  }
13940  }
13941 
13942  /* copy dual solution and activities into rows */
13943  for( r = 0; r < nlpirows; ++r )
13944  {
13945  assert( 0 <= rstat[r] && rstat[r] < 4 );
13946  lpirows[r]->dualsol = dualsol[r];
13947  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
13948  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
13949  lpirows[r]->validactivitylp = lpcount;
13950  if( stillprimalfeasible )
13951  {
13952  stillprimalfeasible =
13953  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
13954  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
13955  }
13956  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
13957  {
13958  double compslack;
13959 
13960  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
13961  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
13962  * variables, which would magnify even the tiniest violation in the dual multiplier
13963  */
13964  if( stilldualfeasible )
13965  {
13966  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
13967  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
13968  }
13969  if( stilldualfeasible )
13970  {
13971  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
13972  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
13973  }
13974 
13975  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13976  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
13977  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
13978  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
13979  primalfeasible != NULL ? stillprimalfeasible : TRUE,
13980  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
13981  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
13982  dualfeasible != NULL ? stilldualfeasible : TRUE);
13983  }
13984  else
13985  {
13986  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
13987  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
13988  * strictly within left-hand and right-hand side, its dual multiplier must be zero
13989  */
13990  if( stilldualfeasible &&
13991  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
13992  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
13993  if( stilldualfeasible &&
13994  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
13995  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
13996 
13997  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
13998  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
13999  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14000  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14001  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14002  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14003  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14004  dualfeasible != NULL ? stilldualfeasible : TRUE);
14005  }
14006 
14007  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14008  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14009  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14010  */
14011  if( stilldualfeasible )
14012  {
14013  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14014  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14015  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14016  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14017  }
14018  }
14019 
14020  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14021  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14022  * infinity
14023  */
14024  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14025  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14026  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14027  {
14028  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14029  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14030  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14031  }
14032 
14033  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14034  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14035  */
14036  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14037  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14038  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14039  {
14040  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14041  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14042  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14043  }
14044 
14045  if( primalfeasible != NULL )
14046  *primalfeasible = stillprimalfeasible;
14047  if( dualfeasible != NULL )
14048  *dualfeasible = stilldualfeasible;
14049 
14050  /* free temporary memory */
14051  SCIPsetFreeBufferArray(set, &rstat);
14052  SCIPsetFreeBufferArray(set, &cstat);
14053  SCIPsetFreeBufferArray(set, &redcost);
14054  SCIPsetFreeBufferArray(set, &activity);
14055  SCIPsetFreeBufferArray(set, &dualsol);
14056  SCIPsetFreeBufferArray(set, &primsol);
14057 
14058  return SCIP_OKAY;
14059 }
14060 
14061 /** stores LP solution with infinite objective value in the columns and rows */
14063  SCIP_LP* lp, /**< current LP data */
14064  SCIP_SET* set, /**< global SCIP settings */
14065  SCIP_STAT* stat, /**< problem statistics */
14066  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14067  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14068  )
14069 {
14070  SCIP_COL** lpicols;
14071  SCIP_ROW** lpirows;
14072  SCIP_Real* primsol;
14073  SCIP_Real* activity;
14074  SCIP_Real* ray;
14075  SCIP_Real rayobjval;
14076  SCIP_Real rayscale;
14077  SCIP_Longint lpcount;
14078  int nlpicols;
14079  int nlpirows;
14080  int c;
14081  int r;
14082 
14083  assert(lp != NULL);
14084  assert(lp->flushed);
14085  assert(lp->solved);
14086  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14087  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14088  assert(set != NULL);
14089  assert(stat != NULL);
14090  assert(lp->validsollp <= stat->lpcount);
14091 
14092  if( primalfeasible != NULL )
14093  *primalfeasible = TRUE;
14094  if( rayfeasible != NULL )
14095  *rayfeasible = TRUE;
14096 
14097  /* check if the values are already calculated */
14098  if( lp->validsollp == stat->lpcount )
14099  return SCIP_OKAY;
14100 
14101  /* check if the LP solver is able to provide a primal unbounded ray */
14102  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14103  {
14104  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14105  return SCIP_LPERROR;
14106  }
14107 
14108  lp->validsollp = stat->lpcount;
14109 
14110  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14111 
14112  /* get temporary memory */
14113  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14114  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14115  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14116 
14117  /* get primal feasible point */
14118  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14119 
14120  /* get primal unbounded ray */
14121  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14122 
14123  lpicols = lp->lpicols;
14124  lpirows = lp->lpirows;
14125  nlpicols = lp->nlpicols;
14126  nlpirows = lp->nlpirows;
14127  lpcount = stat->lpcount;
14128 
14129  /* calculate the objective value decrease of the ray */
14130  rayobjval = 0.0;
14131  for( c = 0; c < nlpicols; ++c )
14132  {
14133  assert(lpicols[c] != NULL);
14134  assert(lpicols[c]->var != NULL);
14135 
14136  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14137  if( rayfeasible != NULL )
14138  *rayfeasible = *rayfeasible
14139  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -lpicols[c]->lb))
14140  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, lpicols[c]->ub));
14141 
14142  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14143  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14144  */
14145  if( primalfeasible != NULL )
14146  *primalfeasible = *primalfeasible
14147  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14148  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14149 
14150  if( !SCIPsetIsZero(set, ray[c]) )
14151  rayobjval += ray[c] * lpicols[c]->obj;
14152  }
14153 
14154  /* if the finite point is already infeasible, we do not have to add the ray */
14155  if( primalfeasible != NULL && !(*primalfeasible) )
14156  {
14157  rayscale = 0.0;
14158  }
14159  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14160  else if( rayfeasible != NULL && !(*rayfeasible) )
14161  {
14162  rayscale = 0.0;
14163  }
14164  /* due to numerical problems, the objective of the ray might be nonnegative,
14165  *
14166  * @todo How to check for negative objective value here?
14167  */
14168  else if( !SCIPsetIsNegative(set, rayobjval) )
14169  {
14170  if( rayfeasible != NULL )
14171  {
14172  *rayfeasible = FALSE;
14173  }
14174 
14175  rayscale = 0.0;
14176  }
14177  else
14178  {
14179  assert(rayobjval != 0.0);
14180 
14181  /* scale the ray, such that the resulting point has infinite objective value */
14182  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14183  assert(SCIPsetIsFeasPositive(set, rayscale));
14184 
14185  /* ensure that unbounded point does not violate the bounds of the variables */
14186  for( c = 0; c < nlpicols; ++c )
14187  {
14188  if( SCIPsetIsPositive(set, ray[c]) )
14189  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14190  else if( SCIPsetIsNegative(set, ray[c]) )
14191  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14192 
14193  assert(SCIPsetIsFeasPositive(set, rayscale));
14194  }
14195  }
14196 
14197  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14198 
14199  /* calculate the unbounded point: x' = x + rayscale * ray */
14200  for( c = 0; c < nlpicols; ++c )
14201  {
14202  if( SCIPsetIsZero(set, ray[c]) )
14203  lpicols[c]->primsol = primsol[c];
14204  else
14205  {
14206  SCIP_Real primsolval = primsol[c] + rayscale * ray[c];
14207  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14208  }
14209  lpicols[c]->redcost = SCIP_INVALID;
14210  lpicols[c]->validredcostlp = -1;
14211  }
14212 
14213  for( r = 0; r < nlpirows; ++r )
14214  {
14215  lpirows[r]->dualsol = SCIP_INVALID;
14216  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14217  lpirows[r]->validactivitylp = lpcount;
14218 
14219  /* check for feasibility of the rows */
14220  if( primalfeasible != NULL )
14221  *primalfeasible = *primalfeasible
14222  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14223  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14224  }
14225 
14226  /* free temporary memory */
14227  SCIPsetFreeBufferArray(set, &ray);
14228  SCIPsetFreeBufferArray(set, &activity);
14229  SCIPsetFreeBufferArray(set, &primsol);
14230 
14231  return SCIP_OKAY;
14232 }
14233 
14234 /** returns primal ray proving the unboundedness of the current LP */
14236  SCIP_LP* lp, /**< current LP data */
14237  SCIP_SET* set, /**< global SCIP settings */
14238  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14239  * so the size of this array should be at least number of active variables
14240  * (all entries have to be initialized to 0 before) */
14241  )
14242 {
14243  SCIP_COL** lpicols;
14244  SCIP_Real* lpiray;
14245  SCIP_VAR* var;
14246  int nlpicols;
14247  int c;
14248 
14249  assert(lp != NULL);
14250  assert(set != NULL);
14251  assert(ray != NULL);
14252  assert(lp->flushed);
14253  assert(lp->solved);
14254  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14255  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14256 
14257  /* check if the LP solver is able to provide a primal unbounded ray */
14258  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14259  {
14260  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14261  return SCIP_LPERROR;
14262  }
14263 
14264  /* get temporary memory */
14265  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14266 
14267  SCIPsetDebugMsg(set, "getting primal ray values\n");
14268 
14269  /* get primal unbounded ray */
14270  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14271 
14272  lpicols = lp->lpicols;
14273  nlpicols = lp->nlpicols;
14274 
14275  /* store the ray values of active problem variables */
14276  for( c = 0; c < nlpicols; c++ )
14277  {
14278  assert(lpicols[c] != NULL);
14279 
14280  var = lpicols[c]->var;
14281  assert(var != NULL);
14282  assert(SCIPvarGetProbindex(var) != -1);
14283  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14284  }
14285 
14286  SCIPsetFreeBufferArray(set, &lpiray);
14287 
14288  return SCIP_OKAY;
14289 }
14290 
14291 /** stores the dual Farkas multipliers for infeasibility proof in rows */
14293  SCIP_LP* lp, /**< current LP data */
14294  SCIP_SET* set, /**< global SCIP settings */
14295  SCIP_STAT* stat /**< problem statistics */
14296  )
14297 {
14298  SCIP_COL** lpicols;
14299  SCIP_ROW** lpirows;
14300  SCIP_Real* dualfarkas;
14301  int nlpicols;
14302  int nlpirows;
14303  int c;
14304  int r;
14305 
14306  assert(lp != NULL);
14307  assert(lp->flushed);
14308  assert(lp->solved);
14309  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14310  assert(set != NULL);
14311  assert(stat != NULL);
14312  assert(lp->validfarkaslp <= stat->lpcount);
14313 
14314  /* check if the values are already calculated */
14315  if( lp->validfarkaslp == stat->lpcount )
14316  return SCIP_OKAY;
14317  lp->validfarkaslp = stat->lpcount;
14318 
14319  /* get temporary memory */
14320  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14321 
14322  /* get dual Farkas infeasibility proof */
14323  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14324 
14325  lpicols = lp->lpicols;
14326  lpirows = lp->lpirows;
14327  nlpicols = lp->nlpicols;
14328  nlpirows = lp->nlpirows;
14329 
14330  /* store infeasibility proof in rows */
14331  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14332  for( r = 0; r < nlpirows; ++r )
14333  {
14334  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14335  lpirows[r]->dualfarkas = dualfarkas[r];
14336  lpirows[r]->dualsol = SCIP_INVALID;
14337  lpirows[r]->activity = 0.0;
14338  lpirows[r]->validactivitylp = -1L;
14339  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14340  }
14341 
14342  /* set columns as invalid */
14343  for( c = 0; c < nlpicols; ++c )
14344  {
14345  lpicols[c]->primsol = SCIP_INVALID;
14346  lpicols[c]->redcost = SCIP_INVALID;
14347  lpicols[c]->validredcostlp = -1L;
14348  lpicols[c]->validfarkaslp = -1L;
14349  }
14350 
14351  /* free temporary memory */
14352  SCIPsetFreeBufferArray(set, &dualfarkas);
14353 
14354  return SCIP_OKAY;
14355 }
14356 
14357 /** get number of iterations used in last LP solve */
14359  SCIP_LP* lp, /**< current LP data */
14360  int* iterations /**< pointer to store the iteration count */
14361  )
14362 {
14363  assert(lp != NULL);
14364 
14365  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14366 
14367  return SCIP_OKAY;
14368 }
14369 
14370 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14371  * resets age of non-zero columns and sharp rows
14372  */
14374  SCIP_LP* lp, /**< current LP data */
14375  SCIP_STAT* stat /**< problem statistics */
14376  )
14377 {
14378  SCIP_COL** lpicols;
14379  SCIP_ROW** lpirows;
14380  int nlpicols;
14381  int nlpirows;
14382  int c;
14383  int r;
14384 
14385  assert(lp != NULL);
14386  assert(lp->flushed);
14387  assert(lp->solved);
14388  assert(lp->nlpicols == lp->ncols);
14389  assert(lp->nlpirows == lp->nrows);
14390  assert(stat != NULL);
14391  assert(lp->validsollp == stat->lpcount);
14392 
14393  SCIPdebugMessage("updating LP ages\n");
14394 
14395  lpicols = lp->lpicols;
14396  lpirows = lp->lpirows;
14397  nlpicols = lp->nlpicols;
14398  nlpirows = lp->nlpirows;
14399 
14400  for( c = 0; c < nlpicols; ++c )
14401  {
14402  assert(lpicols[c] == lp->cols[c]);
14403  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14404  lpicols[c]->age++;
14405  else
14406  lpicols[c]->age = 0;
14407  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14408  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14409  }
14410 
14411  for( r = 0; r < nlpirows; ++r )
14412  {
14413  lpirows[r]->nlpsaftercreation++;
14414  assert(lpirows[r] == lp->rows[r]);
14415 
14416  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14417  {
14418  lpirows[r]->age++;
14419  }
14420  else
14421  {
14422  lpirows[r]->activeinlpcounter++;
14423  lpirows[r]->age = 0;
14424  }
14425  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14426  }
14427 
14428  return SCIP_OKAY;
14429 }
14430 
14431 /* deletes the marked columns from the LP and the LP interface */
14432 static
14434  SCIP_LP* lp, /**< current LP data */
14435  SCIP_SET* set, /**< global SCIP settings */
14436  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
14437  )
14438 {
14439  SCIP_COL* col;
14440  int ncols;
14441  int c;
14442 
14443  assert(lp != NULL);
14444  assert(lp->flushed);
14445  assert(lp->ncols == lp->nlpicols);
14446  assert(!lp->diving);
14447  assert(coldstat != NULL);
14448  assert(lp->nlazycols <= lp->ncols);
14449 
14450  ncols = lp->ncols;
14451 
14452  /* delete columns in LP solver */
14453  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
14454 
14455  /* update LP data respectively */
14456  for( c = 0; c < ncols; ++c )
14457  {
14458  col = lp->cols[c];
14459  assert(col != NULL);
14460  assert(col == lp->lpicols[c]);
14461  assert(coldstat[c] <= c);
14462  col->lppos = coldstat[c];
14463  if( coldstat[c] == -1 )
14464  {
14465  assert(col->removable);
14466 
14467  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
14468  * function vector norms
14469  */
14470  markColDeleted(col);
14471  colUpdateDelLP(col, set);
14472  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
14473  col->lpdepth = -1;
14474 
14475  lp->cols[c] = NULL;
14476  lp->lpicols[c] = NULL;
14477  lp->ncols--;
14478  lp->nremovablecols--;
14479  lp->nlpicols--;
14480  }
14481  else if( coldstat[c] < c )
14482  {
14483  assert(lp->cols[coldstat[c]] == NULL);
14484  assert(lp->lpicols[coldstat[c]] == NULL);
14485  lp->cols[coldstat[c]] = col;
14486  lp->lpicols[coldstat[c]] = col;
14487  lp->cols[coldstat[c]]->lppos = coldstat[c];
14488  lp->cols[coldstat[c]]->lpipos = coldstat[c];
14489  lp->cols[c] = NULL;
14490  lp->lpicols[c] = NULL;
14491  }
14492  }
14493 
14494  /* remove columns which are deleted from the lazy column array */
14495  c = 0;
14496  while( c < lp->nlazycols )
14497  {
14498  if( lp->lazycols[c]->lpipos < 0 )
14499  {
14500  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
14501  lp->nlazycols--;
14502  }
14503  else
14504  c++;
14505  }
14506 
14507  /* mark LP to be unsolved */
14508  if( lp->ncols < ncols )
14509  {
14510  assert(lp->ncols == lp->nlpicols);
14511  assert(lp->nchgcols == 0);
14512  assert(lp->flushed);
14513 
14514  lp->lpifirstchgcol = lp->nlpicols;
14515 
14516  /* mark the current solution invalid */
14517  lp->solved = FALSE;
14518  lp->primalfeasible = FALSE;
14519  lp->primalchecked = FALSE;
14520  lp->lpobjval = SCIP_INVALID;
14522  }
14523 
14524  checkLazyColArray(lp, set);
14525  checkLinks(lp);
14526 
14527  return SCIP_OKAY;
14528 }
14529 
14530 /* deletes the marked rows from the LP and the LP interface */
14531 static
14533  SCIP_LP* lp, /**< current LP data */
14534  BMS_BLKMEM* blkmem, /**< block memory buffers */
14535  SCIP_SET* set, /**< global SCIP settings */
14536  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14537  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14538  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
14539  )
14540 {
14541  SCIP_ROW* row;
14542  int nrows;
14543  int r;
14544 
14545  assert(lp != NULL);
14546  assert(lp->flushed);
14547  assert(lp->nrows == lp->nlpirows);
14548  assert(!lp->diving);
14549  assert(rowdstat != NULL);
14550 
14551  nrows = lp->nrows;
14552 
14553  /* delete rows in LP solver */
14554  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
14555 
14556  /* update LP data respectively */
14557  for( r = 0; r < nrows; ++r )
14558  {
14559  row = lp->rows[r];
14560  assert(row == lp->lpirows[r]);
14561  assert(rowdstat[r] <= r);
14562  assert(row != NULL);
14563  row->lppos = rowdstat[r];
14564  if( rowdstat[r] == -1 )
14565  {
14566  if( row->removable )
14567  lp->nremovablerows--;
14568 
14569  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
14570  markRowDeleted(row);
14571  rowUpdateDelLP(row);
14572  row->lpdepth = -1;
14573 
14574  /* check, if row deletion events are tracked
14575  * if so, issue ROWDELETEDLP event
14576  */
14577  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
14578  {
14579  SCIP_EVENT* event;
14580 
14581  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
14582  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
14583  }
14584 
14585  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
14586  SCIProwUnlock(lp->rows[r]);
14587  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
14588  assert(lp->lpirows[r] == NULL);
14589  assert(lp->rows[r] == NULL);
14590  lp->nrows--;
14591  lp->nlpirows--;
14592  }
14593  else if( rowdstat[r] < r )
14594  {
14595  assert(lp->rows[rowdstat[r]] == NULL);
14596  assert(lp->lpirows[rowdstat[r]] == NULL);
14597  lp->rows[rowdstat[r]] = row;
14598  lp->lpirows[rowdstat[r]] = row;
14599  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
14600  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
14601  lp->rows[r] = NULL;
14602  lp->lpirows[r] = NULL;
14603  }
14604  }
14605 
14606  /* mark LP to be unsolved */
14607  if( lp->nrows < nrows )
14608  {
14609  assert(lp->nrows == lp->nlpirows);
14610  assert(lp->nchgrows == 0);
14611  assert(lp->flushed);
14612 
14613  lp->lpifirstchgrow = lp->nlpirows;
14614 
14615  /* mark the current solution invalid */
14616  lp->solved = FALSE;
14617  lp->dualfeasible = FALSE;
14618  lp->dualchecked = FALSE;
14619  lp->lpobjval = SCIP_INVALID;
14621  }
14622 
14623  checkLinks(lp);
14624 
14625  return SCIP_OKAY;
14626 }
14627 
14628 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
14629 static
14631  SCIP_LP* lp, /**< current LP data */
14632  SCIP_SET* set, /**< global SCIP settings */
14633  SCIP_STAT* stat, /**< problem statistics */
14634  int firstcol /**< first column to check for clean up */
14635  )
14636 {
14637  SCIP_COL** cols;
14638 #ifndef NDEBUG
14639  SCIP_COL** lpicols;
14640 #endif
14641  int* coldstat;
14642  int ncols;
14643  int ndelcols;
14644  int c;
14645 
14646  assert(lp != NULL);
14647  assert(lp->flushed);
14648  assert(lp->ncols == lp->nlpicols);
14649  assert(lp->nremovablecols <= lp->ncols);
14650  assert(!lp->diving);
14651  assert(set != NULL);
14652  assert(stat != NULL);
14653 
14654  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
14655  return SCIP_OKAY;
14656 
14657  ncols = lp->ncols;
14658  cols = lp->cols;
14659 #ifndef NDEBUG
14660  lpicols = lp->lpicols;
14661 #endif
14662 
14663  /* get temporary memory */
14664  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14665 
14666  /* mark obsolete columns to be deleted */
14667  ndelcols = 0;
14668  BMSclearMemoryArray(coldstat, ncols);
14669  for( c = firstcol; c < ncols; ++c )
14670  {
14671  assert(cols[c] == lpicols[c]);
14672  assert(cols[c]->lppos == c);
14673  assert(cols[c]->lpipos == c);
14674  if( cols[c]->removable
14675  && 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 */
14676  && cols[c]->age > set->lp_colagelimit
14678  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14679  {
14680  assert(cols[c]->primsol == 0.0);
14681  coldstat[c] = 1;
14682  ndelcols++;
14683  cols[c]->obsoletenode = stat->nnodes;
14684  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
14685  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
14686  }
14687  }
14688 
14689  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
14690 
14691  /* delete the marked columns in the LP solver interface, update the LP respectively */
14692  if( ndelcols > 0 )
14693  {
14694  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14695  }
14696  assert(lp->ncols == ncols - ndelcols);
14697 
14698  /* release temporary memory */
14699  SCIPsetFreeBufferArray(set, &coldstat);
14700 
14701  return SCIP_OKAY;
14702 }
14703 
14704 /** removes all basic rows, that are too old, beginning with the given firstrow */
14705 static
14707  SCIP_LP* lp, /**< current LP data */
14708  BMS_BLKMEM* blkmem, /**< block memory buffers */
14709  SCIP_SET* set, /**< global SCIP settings */
14710  SCIP_STAT* stat, /**< problem statistics */
14711  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14712  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14713  int firstrow /**< first row to check for clean up */
14714  )
14715 {
14716  SCIP_ROW** rows;
14717 #ifndef NDEBUG
14718  SCIP_ROW** lpirows;
14719 #endif
14720  int* rowdstat;
14721  int nrows;
14722  int ndelrows;
14723  int r;
14724 
14725  assert(lp != NULL);
14726  assert(lp->flushed);
14727  assert(lp->nrows == lp->nlpirows);
14728  assert(lp->nremovablerows <= lp->nrows);
14729  assert(!lp->diving);
14730  assert(set != NULL);
14731  assert(stat != NULL);
14732 
14733  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
14734  return SCIP_OKAY;
14735 
14736  nrows = lp->nrows;
14737  rows = lp->rows;
14738 #ifndef NDEBUG
14739  lpirows = lp->lpirows;
14740 #endif
14741 
14742  /* get temporary memory */
14743  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14744 
14745  /* mark obsolete rows to be deleted */
14746  ndelrows = 0;
14747  BMSclearMemoryArray(rowdstat, nrows);
14748  for( r = firstrow; r < nrows; ++r )
14749  {
14750  assert(rows[r] == lpirows[r]);
14751  assert(rows[r]->lppos == r);
14752  assert(rows[r]->lpipos == r);
14753  if( rows[r]->removable
14754  && 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 */
14755  && rows[r]->age > set->lp_rowagelimit
14757  {
14758  rowdstat[r] = 1;
14759  ndelrows++;
14760  rows[r]->obsoletenode = stat->nnodes;
14761  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
14762  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
14763  }
14764  }
14765 
14766  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
14767 
14768  /* delete the marked rows in the LP solver interface, update the LP respectively */
14769  if( ndelrows > 0 )
14770  {
14771  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14772  }
14773  assert(lp->nrows == nrows - ndelrows);
14774 
14775  /* release temporary memory */
14776  SCIPsetFreeBufferArray(set, &rowdstat);
14777 
14778  return SCIP_OKAY;
14779 }
14780 
14781 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
14783  SCIP_LP* lp, /**< current LP data */
14784  BMS_BLKMEM* blkmem, /**< block memory buffers */
14785  SCIP_SET* set, /**< global SCIP settings */
14786  SCIP_STAT* stat, /**< problem statistics */
14787  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14788  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14789  )
14790 {
14791  assert(lp != NULL);
14792  assert(lp->solved);
14793  assert(!lp->diving);
14795  assert(set != NULL);
14796 
14797  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
14798  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
14799 
14800  if( lp->firstnewcol < lp->ncols )
14801  {
14802  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
14803  }
14804  if( lp->firstnewrow < lp->nrows )
14805  {
14806  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
14807  }
14808 
14809  return SCIP_OKAY;
14810 }
14811 
14812 /** removes all non-basic columns and basic rows in whole LP, that are too old */
14814  SCIP_LP* lp, /**< current LP data */
14815  BMS_BLKMEM* blkmem, /**< block memory buffers */
14816  SCIP_SET* set, /**< global SCIP settings */
14817  SCIP_STAT* stat, /**< problem statistics */
14818  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14819  SCIP_EVENTFILTER* eventfilter /**< global event filter */
14820  )
14821 {
14822  assert(lp != NULL);
14823  assert(lp->solved);
14824  assert(!lp->diving);
14826  assert(set != NULL);
14827 
14828  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
14829 
14830  if( 0 < lp->ncols )
14831  {
14832  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
14833  }
14834  if( 0 < lp->nrows )
14835  {
14836  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
14837  }
14838 
14839  return SCIP_OKAY;
14840 }
14841 
14842 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
14843 static
14845  SCIP_LP* lp, /**< current LP data */
14846  SCIP_SET* set, /**< global SCIP settings */
14847  SCIP_STAT* stat, /**< problem statistics */
14848  int firstcol /**< first column to check for clean up */
14849  )
14850 {
14851  SCIP_COL** cols;
14852  SCIP_COL** lpicols;
14853  int* coldstat;
14854  int ncols;
14855  int ndelcols;
14856  int c;
14857 
14858  assert(lp != NULL);
14859  assert(lp->flushed);
14860  assert(lp->ncols == lp->nlpicols);
14861  assert(!lp->diving);
14862  assert(stat != NULL);
14863  assert(lp->validsollp == stat->lpcount);
14864  assert(0 <= firstcol && firstcol < lp->ncols);
14865 
14866  if( lp->nremovablecols == 0 || !lp->solisbasic )
14867  return SCIP_OKAY;
14868 
14869  ncols = lp->ncols;
14870  cols = lp->cols;
14871  lpicols = lp->lpicols;
14872 
14873  /* get temporary memory */
14874  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
14875 
14876  /* mark unused columns to be deleted */
14877  ndelcols = 0;
14878  BMSclearMemoryArray(coldstat, ncols);
14879  for( c = firstcol; c < ncols; ++c )
14880  {
14881  assert(cols[c] == lpicols[c]);
14882  assert(cols[c]->lppos == c);
14883  assert(cols[c]->lpipos == c);
14884  if( lpicols[c]->removable
14885  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
14886  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
14887  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
14888  {
14889  coldstat[c] = 1;
14890  ndelcols++;
14891  }
14892  }
14893 
14894  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
14895 
14896  /* delete the marked columns in the LP solver interface, update the LP respectively */
14897  if( ndelcols > 0 )
14898  {
14899  SCIP_CALL( lpDelColset(lp, set, coldstat) );
14900  }
14901  assert(lp->ncols == ncols - ndelcols);
14902 
14903  /* release temporary memory */
14904  SCIPsetFreeBufferArray(set, &coldstat);
14905 
14906  return SCIP_OKAY;
14907 }
14908 
14909 /** removes all basic rows beginning with the given firstrow */
14910 static
14912  SCIP_LP* lp, /**< current LP data */
14913  BMS_BLKMEM* blkmem, /**< block memory buffers */
14914  SCIP_SET* set, /**< global SCIP settings */
14915  SCIP_STAT* stat, /**< problem statistics */
14916  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14917  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14918  int firstrow /**< first row to check for clean up */
14919  )
14920 {
14921 #ifndef NDEBUG
14922  SCIP_ROW** rows;
14923 #endif
14924  SCIP_ROW** lpirows;
14925  int* rowdstat;
14926  int nrows;
14927  int ndelrows;
14928  int r;
14929 
14930  assert(lp != NULL);
14931  assert(lp->flushed);
14932  assert(lp->ncols == lp->nlpicols);
14933  assert(lp->nrows == lp->nlpirows);
14934  assert(!lp->diving);
14935  assert(stat != NULL);
14936  assert(lp->validsollp == stat->lpcount);
14937  assert(0 <= firstrow && firstrow < lp->nrows);
14938 
14939  if( lp->nremovablerows == 0 || !lp->solisbasic )
14940  return SCIP_OKAY;
14941 
14942 #ifndef NDEBUG
14943  rows = lp->rows;
14944 #endif
14945  nrows = lp->nrows;
14946  lpirows = lp->lpirows;
14947 
14948  /* get temporary memory */
14949  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
14950 
14951  /* mark unused rows to be deleted */
14952  ndelrows = 0;
14953  BMSclearMemoryArray(rowdstat, nrows);
14954  for( r = firstrow; r < nrows; ++r )
14955  {
14956  assert(rows[r] == lpirows[r]);
14957  assert(rows[r]->lppos == r);
14958  assert(rows[r]->lpipos == r);
14959  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
14960  {
14961  rowdstat[r] = 1;
14962  ndelrows++;
14963  }
14964  }
14965 
14966  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
14967 
14968  /* delete the marked rows in the LP solver interface, update the LP respectively */
14969  if( ndelrows > 0 )
14970  {
14971  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
14972  }
14973  assert(lp->nrows == nrows - ndelrows);
14974 
14975  /* release temporary memory */
14976  SCIPsetFreeBufferArray(set, &rowdstat);
14977 
14978  return SCIP_OKAY;
14979 }
14980 
14981 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
14983  SCIP_LP* lp, /**< current LP data */
14984  BMS_BLKMEM* blkmem, /**< block memory buffers */
14985  SCIP_SET* set, /**< global SCIP settings */
14986  SCIP_STAT* stat, /**< problem statistics */
14987  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
14988  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
14989  SCIP_Bool root /**< are we at the root node? */
14990  )
14991 {
14992  SCIP_Bool cleanupcols;
14993  SCIP_Bool cleanuprows;
14994 
14995  assert(lp != NULL);
14996  assert(lp->solved);
14997  assert(!lp->diving);
14999  assert(set != NULL);
15000 
15001  /* check, if we want to clean up the columns and rows */
15002  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15003  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15004 
15005  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15006  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15007 
15008  if( cleanupcols && lp->firstnewcol < lp->ncols )
15009  {
15010  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15011  }
15012  if( cleanuprows && lp->firstnewrow < lp->nrows )
15013  {
15014  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15015  }
15016 
15017  return SCIP_OKAY;
15018 }
15019 
15020 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15022  SCIP_LP* lp, /**< current LP data */
15023  BMS_BLKMEM* blkmem, /**< block memory buffers */
15024  SCIP_SET* set, /**< global SCIP settings */
15025  SCIP_STAT* stat, /**< problem statistics */
15026  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15027  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15028  SCIP_Bool root /**< are we at the root node? */
15029  )
15030 {
15031  SCIP_Bool cleanupcols;
15032  SCIP_Bool cleanuprows;
15033 
15034  assert(lp != NULL);
15035  assert(lp->solved);
15036  assert(!lp->diving);
15038  assert(set != NULL);
15039 
15040  /* check, if we want to clean up the columns and rows */
15041  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15042  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15043 
15044  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15045  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15046 
15047  if( cleanupcols && 0 < lp->ncols )
15048  {
15049  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15050  }
15051  if( cleanuprows && 0 < lp->nrows )
15052  {
15053  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15054  }
15055 
15056  return SCIP_OKAY;
15057 }
15058 
15059 /** removes all redundant rows that were added at the current node */
15061  SCIP_LP* lp, /**< current LP data */
15062  BMS_BLKMEM* blkmem, /**< block memory buffers */
15063  SCIP_SET* set, /**< global SCIP settings */
15064  SCIP_STAT* stat, /**< problem statistics */
15065  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15066  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15067  )
15068 {
15069 #ifndef NDEBUG
15070  SCIP_ROW** rows;
15071 #endif
15072  SCIP_ROW** lpirows;
15073  int* rowdstat;
15074  int nrows;
15075  int ndelrows;
15076  int r;
15077 
15078  assert(lp != NULL);
15079  assert(lp->flushed);
15080  assert(lp->ncols == lp->nlpicols);
15081  assert(lp->nrows == lp->nlpirows);
15082  assert(!lp->diving);
15083  assert(stat != NULL);
15084  assert(lp->validsollp == stat->lpcount);
15085  assert(lp->firstnewrow <= lp->nrows);
15086 
15087  if( lp->firstnewrow == lp->nrows )
15088  return SCIP_OKAY;
15089 
15090 #ifndef NDEBUG
15091  rows = lp->rows;
15092 #endif
15093  nrows = lp->nrows;
15094  lpirows = lp->lpirows;
15095 
15096  /* get temporary memory */
15097  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15098 
15099  /* mark redundant rows to be deleted (only delete basic rows!) */
15100  ndelrows = 0;
15101  BMSclearMemoryArray(rowdstat, nrows);
15102  for( r = lp->firstnewrow; r < nrows; ++r )
15103  {
15104  assert(rows[r] == lpirows[r]);
15105  assert(rows[r]->lppos == r);
15106  assert(rows[r]->lpipos == r);
15107  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15108  && SCIProwIsRedundant(lpirows[r], set, stat) )
15109  {
15110  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15111  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15112  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15113  rowdstat[r] = 1;
15114  ndelrows++;
15115  }
15116  }
15117 
15118  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15119 
15120  /* delete the marked rows in the LP solver interface, update the LP respectively */
15121  if( ndelrows > 0 )
15122  {
15123  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15124  }
15125  assert(lp->nrows == nrows - ndelrows);
15126 
15127  /* release temporary memory */
15128  SCIPsetFreeBufferArray(set, &rowdstat);
15129 
15130  return SCIP_OKAY;
15131 }
15132 
15133 /** initiates LP diving */
15135  SCIP_LP* lp, /**< current LP data */
15136  BMS_BLKMEM* blkmem, /**< block memory */
15137  SCIP_SET* set, /**< global SCIP settings */
15138  SCIP_STAT* stat /**< problem statistics */
15139  )
15140 {
15141  int c;
15142  int r;
15143 
15144  assert(lp != NULL);
15145  assert(lp->flushed || !lp->solved);
15146  assert(!lp->diving);
15147  assert(!lp->probing);
15148  assert(lp->divelpistate == NULL);
15149  assert(lp->divelpwasprimfeas);
15150  assert(lp->divelpwasdualfeas);
15151  assert(lp->validsollp <= stat->lpcount);
15152  assert(blkmem != NULL);
15153  assert(set != NULL);
15154  assert(lp->ndivechgsides == 0);
15155 
15156  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15157  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15158 
15159 #ifndef NDEBUG
15160  for( c = 0; c < lp->ncols; ++c )
15161  {
15162  assert(lp->cols[c] != NULL);
15163  assert(lp->cols[c]->var != NULL);
15164  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15165  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15166  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15167  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15168  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15169  }
15170 #endif
15171 
15172  /* save current LPI state (basis information) */
15173  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15175  lp->divelpwasdualfeas = lp->dualfeasible;
15178 
15179  /* save current LP values dependent on the solution */
15180  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15181  assert(lp->storedsolvals != NULL);
15182  if( !set->lp_resolverestore && lp->solved )
15183  {
15184  SCIP_Bool store = TRUE;
15185 
15186  switch ( lp->lpsolstat )
15187  {
15189  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15190  assert(lp->validsollp == stat->lpcount);
15191  break;
15193  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15194  assert(lp->validsollp == stat->lpcount);
15195  break;
15199  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15200  assert(lp->validsollp == stat->lpcount);
15201  break;
15203  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat) );
15204  break;
15206  case SCIP_LPSOLSTAT_ERROR:
15207  default:
15208  store = FALSE;
15209  }
15210 
15211  if ( store )
15212  {
15213  for( c = 0; c < lp->ncols; ++c )
15214  {
15215  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15216  }
15217  for( r = 0; r < lp->nrows; ++r )
15218  {
15220  }
15221  }
15222  }
15223 
15224  /* store LPI iteration limit */
15226 
15227  /* store current number of rows */
15228  lp->ndivingrows = lp->nrows;
15229 
15230  /* switch to diving mode */
15231  lp->diving = TRUE;
15232 
15233  return SCIP_OKAY;
15234 }
15235 
15236 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15238  SCIP_LP* lp, /**< current LP data */
15239  BMS_BLKMEM* blkmem, /**< block memory */
15240  SCIP_SET* set, /**< global SCIP settings */
15241  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15242  SCIP_STAT* stat, /**< problem statistics */
15243  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15244  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15245  SCIP_PROB* prob, /**< problem data */
15246  SCIP_VAR** vars, /**< array with all active variables */
15247  int nvars /**< number of active variables */
15248  )
15249 {
15250  SCIP_VAR* var;
15251  int v;
15252 
15253  assert(lp != NULL);
15254  assert(lp->diving);
15255  assert(blkmem != NULL);
15256  assert(nvars == 0 || vars != NULL);
15257 
15258  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15259 
15260  /* reset all columns' objective values and bounds to its original values */
15261  for( v = 0; v < nvars; ++v )
15262  {
15263  var = vars[v];
15264  assert(var != NULL);
15266  {
15267  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15268  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15269  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15270  }
15271  }
15272 
15273  /* remove rows which were added in diving mode */
15274  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15275 
15276  /* undo changes to left hand sides and right hand sides */
15277  while( lp->ndivechgsides > 0 )
15278  {
15279  SCIP_Real oldside;
15280  SCIP_SIDETYPE sidetype;
15281  SCIP_ROW* row;
15282 
15283  lp->ndivechgsides--;
15284  oldside = lp->divechgsides[lp->ndivechgsides];
15285  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15286  row = lp->divechgrows[lp->ndivechgsides];
15287 
15288  if( sidetype == SCIP_SIDETYPE_LEFT )
15289  {
15290  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15291  }
15292  else
15293  {
15294  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15295  }
15296  }
15297 
15298  /* restore LPI iteration limit */
15300 
15301  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15302  * happens
15303  */
15304  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15306  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15307  lp->divelpwasprimfeas = TRUE;
15308  lp->divelpwasdualfeas = TRUE;
15309  lp->divelpwasprimchecked = TRUE;
15310  lp->divelpwasdualchecked = TRUE;
15311  assert(lp->divelpistate == NULL);
15312 
15313  /* switch to standard (non-diving) mode */
15314  lp->diving = FALSE;
15315  lp->divingobjchg = FALSE;
15316 
15317  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15318  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15319  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15320  * the parameter resolverestore to TRUE
15321  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15322  */
15323  assert(lp->storedsolvals != NULL);
15324  if( lp->storedsolvals->lpissolved
15325  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL) )
15326  {
15327  SCIP_Bool lperror;
15328 
15329  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15330  if( lperror )
15331  {
15332  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
15333  lp->resolvelperror = TRUE;
15334  }
15339  {
15340  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15341  "LP was not resolved to a sufficient status after diving\n");
15342  lp->resolvelperror = TRUE;
15343  }
15344  }
15345  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15346  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15347  * re-solve as above can lead to a different LP status
15348  */
15349  else
15350  {
15351  int c;
15352  int r;
15353 
15354  /* if there are lazy bounds, remove them from the LP */
15355  if( lp->nlazycols > 0 )
15356  {
15357  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15358  * first resolve LP?
15359  */
15360  SCIP_CALL( updateLazyBounds(lp, set) );
15361  assert(lp->diving == lp->divinglazyapplied);
15362 
15363  /* flush changes to the LP solver */
15364  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15365  }
15366 
15367  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15368  SCIPstatIncrement(stat, set, lpcount);
15369 
15370  /* restore LP solution values in lp data, columns and rows */
15371  if( lp->storedsolvals->lpissolved &&
15378  )
15379  {
15380  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15381 
15382  for( c = 0; c < lp->ncols; ++c )
15383  {
15384  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15385  }
15386  for( r = 0; r < lp->nrows; ++r )
15387  {
15388  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15389  }
15390  }
15391  else
15392  {
15393  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15394  }
15395  }
15396 
15397 #ifndef NDEBUG
15398  {
15399  int c;
15400  for( c = 0; c < lp->ncols; ++c )
15401  {
15402  assert(lp->cols[c] != NULL);
15403  assert(lp->cols[c]->var != NULL);
15404  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15405  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15406  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15407  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15408  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15409  }
15410  }
15411 #endif
15412 
15413  return SCIP_OKAY;
15414 }
15415 
15416 #define DIVESTACKGROWFACT 1.5
15417 
15418 /** records a current row side such that any change will be undone after diving */
15420  SCIP_LP* lp, /**< LP data object */
15421  SCIP_ROW* row, /**< row affected by the change */
15422  SCIP_SIDETYPE sidetype /**< side type */
15423  )
15424 {
15425  assert(lp != NULL);
15426  assert(row != NULL);
15427 
15428  if( lp->ndivechgsides == lp->divechgsidessize )
15429  {
15431  }
15432  assert(lp->ndivechgsides < lp->divechgsidessize);
15433 
15434  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
15435  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
15436  lp->divechgrows[lp->ndivechgsides] = row;
15437  lp->ndivechgsides++;
15438 
15439  return SCIP_OKAY;
15440 }
15441 
15442 /** informs the LP that probing mode was initiated */
15444  SCIP_LP* lp /**< current LP data */
15445  )
15446 {
15447  assert(lp != NULL);
15448  assert(!lp->probing);
15449  assert(!lp->strongbranching);
15450  assert(!lp->strongbranchprobing);
15451 
15452  lp->probing = TRUE;
15453 
15454  return SCIP_OKAY;
15455 }
15456 
15457 /** informs the LP that probing mode was finished */
15459  SCIP_LP* lp /**< current LP data */
15460  )
15461 {
15462  assert(lp != NULL);
15463  assert(lp->probing);
15464  assert(!lp->strongbranching);
15465  assert(!lp->strongbranchprobing);
15466 
15467  lp->probing = FALSE;
15468 
15469  return SCIP_OKAY;
15470 }
15471 
15472 /** informs the LP that the probing mode is now used for strongbranching */
15474  SCIP_LP* lp /**< current LP data */
15475  )
15476 {
15477  assert(lp != NULL);
15478  assert(lp->probing);
15479  assert(!lp->strongbranching);
15480  assert(!lp->strongbranchprobing);
15481 
15482  lp->strongbranchprobing = TRUE;
15483 }
15484 
15485 /** informs the LP that the probing mode is not used for strongbranching anymore */
15487  SCIP_LP* lp /**< current LP data */
15488  )
15489 {
15490  assert(lp != NULL);
15491  assert(lp->probing);
15492  assert(!lp->strongbranching);
15493  assert(lp->strongbranchprobing);
15494 
15495  lp->strongbranchprobing = FALSE;
15496 }
15497 
15498 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
15499  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
15500  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
15501  * we have only left hand sides):
15502  * min{cx | b <= Ax, lb <= x <= ub}
15503  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
15504  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
15505  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
15506  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
15507  */
15508 static
15510  SCIP_LP* lp, /**< current LP data */
15511  SCIP_SET* set, /**< global SCIP settings */
15512  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
15513  SCIP_Real* bound /**< result of interval arithmetic minimization */
15514  )
15515 {
15516  SCIP_INTERVAL* yinter;
15517  SCIP_INTERVAL b;
15518  SCIP_INTERVAL ytb;
15519  SCIP_INTERVAL prod;
15520  SCIP_INTERVAL diff;
15521  SCIP_INTERVAL x;
15522  SCIP_INTERVAL minprod;
15523  SCIP_INTERVAL a;
15524  SCIP_ROW* row;
15525  SCIP_COL* col;
15526  SCIP_Real y;
15527  SCIP_Real c;
15528  int i;
15529  int j;
15530 
15531  assert(lp != NULL);
15532  assert(lp->solved);
15533  assert(set != NULL);
15534  assert(bound != NULL);
15535 
15536  /* allocate buffer for storing y in interval arithmetic */
15537  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
15538 
15539  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
15540  SCIPintervalSet(&ytb, 0.0);
15541  for( j = 0; j < lp->nrows; ++j )
15542  {
15543  row = lp->rows[j];
15544  assert(row != NULL);
15545 
15546  y = (usefarkas ? row->dualfarkas : row->dualsol);
15547 
15548  if( SCIPsetIsFeasPositive(set, y) )
15549  {
15550  SCIPintervalSet(&yinter[j], y);
15551  SCIPintervalSet(&b, row->lhs - row->constant);
15552  }
15553  else if( SCIPsetIsFeasNegative(set, y) )
15554  {
15555  SCIPintervalSet(&yinter[j], y);
15556  SCIPintervalSet(&b, row->rhs - row->constant);
15557  }
15558  else
15559  {
15560  SCIPintervalSet(&yinter[j], 0.0);
15561  SCIPintervalSet(&b, 0.0);
15562  }
15563 
15564  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
15565  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
15566  }
15567 
15568  /* calculate min{(c^T - y^TA)x} */
15569  SCIPintervalSet(&minprod, 0.0);
15570  for( j = 0; j < lp->ncols; ++j )
15571  {
15572  col = lp->cols[j];
15573  assert(col != NULL);
15574  assert(col->nunlinked == 0);
15575 
15577 
15578  c = usefarkas ? 0.0 : col->obj;
15579  SCIPintervalSet(&diff, c);
15580 
15581  for( i = 0; i < col->nlprows; ++i )
15582  {
15583  assert(col->rows[i] != NULL);
15584  assert(col->rows[i]->lppos >= 0);
15585  assert(col->linkpos[i] >= 0);
15586  SCIPintervalSet(&a, col->vals[i]);
15587  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
15588  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
15589  }
15590 
15591 #ifndef NDEBUG
15592  for( i = col->nlprows; i < col->len; ++i )
15593  {
15594  assert(col->rows[i] != NULL);
15595  assert(col->rows[i]->lppos == -1);
15596  assert(col->rows[i]->dualsol == 0.0);
15597  assert(col->rows[i]->dualfarkas == 0.0);
15598  assert(col->linkpos[i] >= 0);
15599  }
15600 #endif
15601 
15602  SCIPintervalSetBounds(&x, col->lb, col->ub);
15603  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
15604  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
15605  }
15606 
15607  /* add y^Tb */
15608  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
15609 
15610  /* free buffer for storing y in interval arithmetic */
15611  SCIPsetFreeBufferArray(set, &yinter);
15612 
15613  *bound = SCIPintervalGetInf(minprod);
15614 
15615  return SCIP_OKAY;
15616 }
15617 
15618 /** gets proven lower (dual) bound of last LP solution */
15620  SCIP_LP* lp, /**< current LP data */
15621  SCIP_SET* set, /**< global SCIP settings */
15622  SCIP_Real* bound /**< pointer to store proven dual bound */
15623  )
15624 {
15625  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
15626 
15627  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
15628 
15629  return SCIP_OKAY;
15630 }
15631 
15632 /** gets proven dual bound of last LP solution */
15634  SCIP_LP* lp, /**< current LP data */
15635  SCIP_SET* set, /**< global SCIP settings */
15636  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
15637  )
15638 {
15639  SCIP_Real bound;
15640 
15641  assert(proved != NULL);
15642 
15643  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
15644 
15645  *proved = (bound > 0.0);
15646 
15647  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
15648 
15649  return SCIP_OKAY;
15650 }
15651 
15652 
15653 
15654 /** writes LP to a file */
15656  SCIP_LP* lp, /**< current LP data */
15657  const char* fname /**< file name */
15658  )
15659 {
15660  assert(lp != NULL);
15661  assert(lp->flushed);
15662  assert(fname != NULL);
15663 
15664  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
15665 
15666  return SCIP_OKAY;
15667 }
15668 
15669 /** writes MIP relaxation of the current B&B node to a file */
15671  SCIP_LP* lp, /**< current LP data */
15672  SCIP_SET* set, /**< global SCIP settings */
15673  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15674  const char* fname, /**< file name */
15675  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
15676  * troubles with reserved symbols? */
15677  SCIP_Bool origobj, /**< should the original objective function be used? */
15678  SCIP_OBJSENSE objsense, /**< objective sense */
15679  SCIP_Real objscale, /**< objective scaling factor */
15680  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
15681  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
15682  )
15683 {
15684  FILE* file;
15685  int i;
15686  int j;
15687  char rowname[SCIP_MAXSTRLEN];
15688  SCIP_Real coeff;
15689 
15690  assert(lp != NULL);
15691  assert(lp->flushed);
15692  assert(fname != NULL);
15693 
15694  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
15695  file = fopen(fname, "w");
15696  if( file == NULL )
15697  {
15698  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
15699  SCIPprintSysError(fname);
15700  return SCIP_FILECREATEERROR;
15701  }
15702 
15703  /* print comments */
15704  if( genericnames )
15705  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
15706  else
15707  {
15708  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
15709  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
15710  }
15711 
15712  if( origobj && objoffset != 0.0 )
15713  {
15714  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
15715  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
15716  }
15717 
15718  /* print objective function */
15719  /**@note the transformed problem in SCIP is always a minimization problem */
15720  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
15721  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
15722  else
15723  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
15724 
15725  /* print objective */
15726  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
15727  j = 0;
15728  for( i = 0; i < lp->ncols; ++i )
15729  {
15730  if( lp->cols[i]->obj != 0.0 )
15731  {
15732  coeff = lp->cols[i]->obj;
15733  if( origobj )
15734  {
15735  coeff *= (SCIP_Real) objsense;
15736  coeff *= objscale;
15737  }
15738 
15739  if( genericnames )
15740  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
15741  else
15742  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
15743 
15744  ++j;
15745  if( j % 10 == 0 )
15746  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15747  }
15748  }
15749  /* add artificial variable 'objoffset' to transfer objective offset */
15750  if( origobj && objoffset != 0.0 )
15751  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
15752 
15753  /* print constraint section */
15754  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
15755  for( i = 0; i < lp->nrows; i++ )
15756  {
15757  char type = 'i';
15758 
15759  /* skip removable rows if we want to write them as lazy constraints */
15760  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
15761  continue;
15762 
15763  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15764  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15765  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15766  * type 'i' means: lhs and rhs are both infinite */
15767  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15768  type = 'r';
15769  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15770  type = 'l';
15771  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15772  type = 'e';
15773  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15774  type = 'b';
15775 
15776  /* print name of row */
15777  if( genericnames )
15778  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15779  else
15780  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15781 
15782  WRITEROW:
15783  switch( type )
15784  {
15785  case 'r':
15786  case 'l':
15787  case 'e':
15788  if( strlen(rowname) > 0 )
15789  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15790  break;
15791  case 'i':
15792  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15793  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15794  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
15795  type = 'b';
15796  /*lint -fallthrough*/
15797  case 'b':
15798  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15799  break;
15800  case 'B':
15801  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15802  break;
15803  default:
15804  SCIPerrorMessage("Undefined row type!\n");
15805  return SCIP_ERROR;
15806  }
15807 
15808  /* print coefficients and variables */
15809  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15810  {
15811  if( genericnames )
15812  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15813  else
15814  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15815 
15816  if( (j+1) % 10 == 0 )
15817  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15818  }
15819 
15820  /* print right hand side */
15821  switch( type )
15822  {
15823  case 'b':
15824  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15825  type = 'B';
15826  goto WRITEROW;
15827  case 'l':
15828  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15829  break;
15830  case 'B':
15831  case 'r':
15832  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15833  break;
15834  case 'e':
15835  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15836  break;
15837  default:
15838  SCIPerrorMessage("Undefined row type!\n");
15839  return SCIP_ERROR;
15840  }
15841  }
15842 
15843  if ( lazyconss )
15844  {
15845  /* print lazy constraint section */
15846  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
15847  for( i = 0; i < lp->nrows; i++ )
15848  {
15849  char type = 'i';
15850 
15851  /* skip non-removable rows if we want to write lazy constraints */
15852  if ( ! SCIProwIsRemovable(lp->rows[i]) )
15853  continue;
15854 
15855  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
15856  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
15857  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
15858  * type 'i' means: lhs and rhs are both infinite */
15859  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15860  type = 'r';
15861  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15862  type = 'l';
15863  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
15864  type = 'e';
15865  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
15866  type = 'b';
15867 
15868  /* print name of row */
15869  if( genericnames )
15870  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
15871  else
15872  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
15873 
15874  WRITELAZYROW:
15875  switch( type )
15876  {
15877  case 'r':
15878  case 'l':
15879  case 'e':
15880  if( strlen(rowname) > 0 )
15881  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
15882  break;
15883  case 'i':
15884  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
15885  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
15886  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
15887  type = 'b';
15888  /*lint -fallthrough*/
15889  case 'b':
15890  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
15891  break;
15892  case 'B':
15893  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
15894  break;
15895  default:
15896  SCIPerrorMessage("Undefined row type!\n");
15897  return SCIP_ERROR;
15898  }
15899 
15900  /* print coefficients and variables */
15901  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
15902  {
15903  if( genericnames )
15904  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
15905  else
15906  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
15907 
15908  if( (j+1) % 10 == 0 )
15909  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
15910  }
15911 
15912  /* print right hand side */
15913  switch( type )
15914  {
15915  case 'b':
15916  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15917  type = 'B';
15918  goto WRITELAZYROW;
15919  case 'l':
15920  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15921  break;
15922  case 'B':
15923  case 'r':
15924  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
15925  break;
15926  case 'e':
15927  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
15928  break;
15929  default:
15930  SCIPerrorMessage("Undefined row type!\n");
15931  return SCIP_ERROR;
15932  }
15933  }
15934  }
15935 
15936  /* print variable bounds */
15937  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
15938  for( i = 0; i < lp->ncols; ++i )
15939  {
15940  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
15941  {
15942  /* print lower bound as far this one is not infinity */
15943  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
15944  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
15945 
15946  /* print variable name */
15947  if( genericnames )
15948  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
15949  else
15950  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
15951 
15952  /* print upper bound as far this one is not infinity */
15953  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
15954  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
15955  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
15956  }
15957  }
15958  if( origobj && objoffset != 0.0 )
15959  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
15960 
15961  /* print integer variables */
15962  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
15963  j = 0;
15964  for( i = 0; i < lp->ncols; ++i )
15965  {
15966  if( SCIPvarIsIntegral(lp->cols[i]->var) )
15967  {
15968  /* print variable name */
15969  if( genericnames )
15970  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
15971  else
15972  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
15973 
15974  j++;
15975  if( j % 10 == 0 )
15976  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
15977  }
15978  }
15979 
15980  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
15981  fclose(file);
15982 
15983  return SCIP_OKAY;
15984 }
15985 
15986 /*
15987  * simple functions implemented as defines
15988  */
15989 
15990 /* In debug mode, the following methods are implemented as function calls to ensure
15991  * type validity.
15992  * In optimized mode, the methods are implemented as defines to improve performance.
15993  * However, we want to have them in the library anyways, so we have to undef the defines.
15994  */
15995 
15996 #undef SCIPcolGetObj
15997 #undef SCIPcolGetLb
15998 #undef SCIPcolGetUb
15999 #undef SCIPcolGetBestBound
16000 #undef SCIPcolGetPrimsol
16001 #undef SCIPcolGetMinPrimsol
16002 #undef SCIPcolGetMaxPrimsol
16003 #undef SCIPcolGetBasisStatus
16004 #undef SCIPcolGetVar
16005 #undef SCIPcolGetIndex
16006 #undef SCIPcolIsIntegral
16007 #undef SCIPcolIsRemovable
16008 #undef SCIPcolGetLPPos
16009 #undef SCIPcolGetLPDepth
16010 #undef SCIPcolIsInLP
16011 #undef SCIPcolGetNNonz
16012 #undef SCIPcolGetNLPNonz
16013 #undef SCIPcolGetRows
16014 #undef SCIPcolGetVals
16015 #undef SCIPcolGetStrongbranchNode
16016 #undef SCIPcolGetNStrongbranchs
16017 #undef SCIPboundtypeOpposite
16018 #undef SCIProwGetNNonz
16019 #undef SCIProwGetNLPNonz
16020 #undef SCIProwGetCols
16021 #undef SCIProwGetVals
16022 #undef SCIProwGetConstant
16023 #undef SCIProwGetNorm
16024 #undef SCIProwGetSumNorm
16025 #undef SCIProwGetLhs
16026 #undef SCIProwGetRhs
16027 #undef SCIProwGetDualsol
16028 #undef SCIProwGetDualfarkas
16029 #undef SCIProwGetBasisStatus
16030 #undef SCIProwGetName
16031 #undef SCIProwGetIndex
16032 #undef SCIProwGetAge
16033 #undef SCIProwGetRank
16034 #undef SCIProwIsIntegral
16035 #undef SCIProwIsLocal
16036 #undef SCIProwIsModifiable
16037 #undef SCIProwIsRemovable
16038 #undef SCIProwGetOrigintype
16039 #undef SCIProwGetOriginCons
16040 #undef SCIProwGetOriginSepa
16041 #undef SCIProwIsInGlobalCutpool
16042 #undef SCIProwGetLPPos
16043 #undef SCIProwGetLPDepth
16044 #undef SCIProwIsInLP
16045 #undef SCIProwGetActiveLPCount
16046 #undef SCIProwGetNLPsAfterCreation
16047 #undef SCIProwChgRank
16048 #undef SCIPlpGetCols
16049 #undef SCIPlpGetNCols
16050 #undef SCIPlpGetRows
16051 #undef SCIPlpGetNRows
16052 #undef SCIPlpGetNewcols
16053 #undef SCIPlpGetNNewcols
16054 #undef SCIPlpGetNewrows
16055 #undef SCIPlpGetNNewrows
16056 #undef SCIPlpGetObjNorm
16057 #undef SCIPlpGetRootObjval
16058 #undef SCIPlpGetRootColumnObjval
16059 #undef SCIPlpGetRootLooseObjval
16060 #undef SCIPlpGetLPI
16061 #undef SCIPlpSetIsRelax
16062 #undef SCIPlpIsRelax
16063 #undef SCIPlpIsSolved
16064 #undef SCIPlpIsSolBasic
16065 #undef SCIPlpDiving
16066 #undef SCIPlpDivingObjChanged
16067 #undef SCIPlpMarkDivingObjChanged
16068 #undef SCIPlpUnmarkDivingObjChanged
16069 #undef SCIPlpDivingRowsChanged
16070 
16071 /** gets objective value of column */
16073  SCIP_COL* col /**< LP column */
16074  )
16075 {
16076  assert(col != NULL);
16077 
16078  return col->obj;
16079 }
16080 
16081 /** gets lower bound of column */
16083  SCIP_COL* col /**< LP column */
16084  )
16085 {
16086  assert(col != NULL);
16087 
16088  return col->lb;
16089 }
16090 
16091 /** gets upper bound of column */
16093  SCIP_COL* col /**< LP column */
16094  )
16095 {
16096  assert(col != NULL);
16097 
16098  return col->ub;
16099 }
16100 
16101 /** gets best bound of column with respect to the objective function */
16103  SCIP_COL* col /**< LP column */
16104  )
16105 {
16106  assert(col != NULL);
16107 
16108  if( col->obj >= 0.0 )
16109  return col->lb;
16110  else
16111  return col->ub;
16112 }
16113 
16114 /** gets the primal LP solution of a column */
16116  SCIP_COL* col /**< LP column */
16117  )
16118 {
16119  assert(col != NULL);
16120 
16121  if( col->lppos >= 0 )
16122  return col->primsol;
16123  else
16124  return 0.0;
16125 }
16126 
16127 /** gets the minimal LP solution value, this column ever assumed */
16129  SCIP_COL* col /**< LP column */
16130  )
16131 {
16132  assert(col != NULL);
16133 
16134  return col->minprimsol;
16135 }
16136 
16137 /** gets the maximal LP solution value, this column ever assumed */
16139  SCIP_COL* col /**< LP column */
16140  )
16141 {
16142  assert(col != NULL);
16143 
16144  return col->maxprimsol;
16145 }
16146 
16147 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16148  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16149  */
16151  SCIP_COL* col /**< LP column */
16152  )
16153 {
16154  assert(col != NULL);
16155  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16156 
16157  return (SCIP_BASESTAT)col->basisstatus;
16158 }
16159 
16160 /** gets variable this column represents */
16162  SCIP_COL* col /**< LP column */
16163  )
16164 {
16165  assert(col != NULL);
16166 
16167  return col->var;
16168 }
16169 
16170 /** gets unique index of col */
16172  SCIP_COL* col /**< LP col */
16173  )
16174 {
16175  assert(col != NULL);
16176 
16177  return col->index;
16178 }
16179 
16180 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16182  SCIP_COL* col /**< LP column */
16183  )
16184 {
16185  assert(col != NULL);
16186  assert(SCIPvarIsIntegral(col->var) == col->integral);
16187 
16188  return col->integral;
16189 }
16190 
16191 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16193  SCIP_COL* col /**< LP column */
16194  )
16195 {
16196  assert(col != NULL);
16197 
16198  return col->removable;
16199 }
16200 
16201 /** gets position of column in current LP, or -1 if it is not in LP */
16203  SCIP_COL* col /**< LP column */
16204  )
16205 {
16206  assert(col != NULL);
16207  assert((col->lppos == -1) == (col->lpdepth == -1));
16208 
16209  return col->lppos;
16210 }
16211 
16212 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16214  SCIP_COL* col /**< LP column */
16215  )
16216 {
16217  assert(col != NULL);
16218  assert((col->lppos == -1) == (col->lpdepth == -1));
16219 
16220  return col->lpdepth;
16221 }
16222 
16223 /** returns TRUE iff column is member of current LP */
16225  SCIP_COL* col /**< LP column */
16226  )
16227 {
16228  assert(col != NULL);
16229  assert((col->lppos == -1) == (col->lpdepth == -1));
16230 
16231  return (col->lppos >= 0);
16232 }
16233 
16234 /** get number of nonzero entries in column vector */
16236  SCIP_COL* col /**< LP column */
16237  )
16238 {
16239  assert(col != NULL);
16240 
16241  return col->len;
16242 }
16243 
16244 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16245  *
16246  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16247  * 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
16248  */
16250  SCIP_COL* col /**< LP column */
16251  )
16252 {
16253  assert(col != NULL);
16254  assert(col->nunlinked == 0);
16255 
16256  return col->nlprows;
16257 }
16258 
16259 /** gets array with rows of nonzero entries */
16261  SCIP_COL* col /**< LP column */
16262  )
16263 {
16264  assert(col != NULL);
16265 
16266  return col->rows;
16267 }
16268 
16269 /** gets array with coefficients of nonzero entries */
16271  SCIP_COL* col /**< LP column */
16272  )
16273 {
16274  assert(col != NULL);
16275 
16276  return col->vals;
16277 }
16278 
16279 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16280  * given column, or -1 if strong branching was never applied to the column in current run
16281  */
16283  SCIP_COL* col /**< LP column */
16284  )
16285 {
16286  assert(col != NULL);
16287 
16288  return col->sbnode;
16289 }
16290 
16291 /** gets number of times, strong branching was applied in current run on the given column */
16293  SCIP_COL* col /**< LP column */
16294  )
16295 {
16296  assert(col != NULL);
16297 
16298  return col->nsbcalls;
16299 }
16300 
16301 /** gets opposite bound type of given bound type */
16303  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16304  )
16305 {
16306  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16307 
16309 }
16310 
16311 /** get number of nonzero entries in row vector */
16313  SCIP_ROW* row /**< LP row */
16314  )
16315 {
16316  assert(row != NULL);
16317 
16318  return row->len;
16319 }
16320 
16321 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16322  *
16323  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16324  * 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
16325  */
16327  SCIP_ROW* row /**< LP row */
16328  )
16329 {
16330  assert(row != NULL);
16331  assert(row->nunlinked == 0);
16332 
16333  return row->nlpcols;
16334 }
16335 
16336 /** gets array with columns of nonzero entries */
16338  SCIP_ROW* row /**< LP row */
16339  )
16340 {
16341  assert(row != NULL);
16342 
16343  return row->cols;
16344 }
16345 
16346 /** gets array with coefficients of nonzero entries */
16348  SCIP_ROW* row /**< LP row */
16349  )
16350 {
16351  assert(row != NULL);
16352 
16353  return row->vals;
16354 }
16355 
16356 /** gets constant shift of row */
16358  SCIP_ROW* row /**< LP row */
16359  )
16360 {
16361  assert(row != NULL);
16362 
16363  return row->constant;
16364 }
16365 
16366 /** gets Euclidean norm of row vector */
16368  SCIP_ROW* row /**< LP row */
16369  )
16370 {
16371  assert(row != NULL);
16372 
16373  checkRowSqrnorm(row);
16374 
16375  return sqrt(row->sqrnorm);
16376 }
16377 
16378 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16380  SCIP_ROW* row /**< LP row */
16381  )
16382 {
16383  assert(row != NULL);
16384 
16385  checkRowSumnorm(row);
16386 
16387  return row->sumnorm;
16388 }
16389 
16390 /** returns the left hand side of the row */
16392  SCIP_ROW* row /**< LP row */
16393  )
16394 {
16395  assert(row != NULL);
16396 
16397  return row->lhs;
16398 }
16399 
16400 /** returns the right hand side of the row */
16402  SCIP_ROW* row /**< LP row */
16403  )
16404 {
16405  assert(row != NULL);
16406 
16407  return row->rhs;
16408 }
16409 
16410 /** gets the dual LP solution of a row */
16412  SCIP_ROW* row /**< LP row */
16413  )
16414 {
16415  assert(row != NULL);
16416 
16417  if( row->lppos >= 0 )
16418  return row->dualsol;
16419  else
16420  return 0.0;
16421 }
16422 
16423 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16425  SCIP_ROW* row /**< LP row */
16426  )
16427 {
16428  assert(row != NULL);
16429 
16430  if( row->lppos >= 0 )
16431  return row->dualfarkas;
16432  else
16433  return 0.0;
16434 }
16435 
16436 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16437  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
16438  */
16440  SCIP_ROW* row /**< LP row */
16441  )
16442 {
16443  assert(row != NULL);
16444  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
16445 
16446  return (SCIP_BASESTAT)row->basisstatus;
16447 }
16448 
16449 /** returns the name of the row */
16450 const char* SCIProwGetName(
16451  SCIP_ROW* row /**< LP row */
16452  )
16453 {
16454  assert(row != NULL);
16455 
16456  return row->name;
16457 }
16458 
16459 /** gets unique index of row */
16461  SCIP_ROW* row /**< LP row */
16462  )
16463 {
16464  assert(row != NULL);
16465 
16466  return row->index;
16467 }
16468 
16469 /** gets age of row */
16471  SCIP_ROW* row /**< LP row */
16472  )
16473 {
16474  assert(row != NULL);
16475 
16476  return row->age;
16477 }
16478 
16479 /** gets rank of row */
16481  SCIP_ROW* row /**< LP row */
16482  )
16483 {
16484  assert(row != NULL);
16485 
16486  return row->rank;
16487 }
16488 
16489 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
16491  SCIP_ROW* row /**< LP row */
16492  )
16493 {
16494  assert(row != NULL);
16495 
16496  return row->integral;
16497 }
16498 
16499 /** returns TRUE iff row is only valid locally */
16501  SCIP_ROW* row /**< LP row */
16502  )
16503 {
16504  assert(row != NULL);
16505 
16506  return row->local;
16507 }
16508 
16509 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
16511  SCIP_ROW* row /**< LP row */
16512  )
16513 {
16514  assert(row != NULL);
16515 
16516  return row->modifiable;
16517 }
16518 
16519 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
16521  SCIP_ROW* row /**< LP row */
16522  )
16523 {
16524  assert(row != NULL);
16525 
16526  return row->removable;
16527 }
16528 
16529 /** returns type of origin that created the row */
16531  SCIP_ROW* row /**< LP row */
16532  )
16533 {
16534  assert( row != NULL );
16535 
16536  return (SCIP_ROWORIGINTYPE) row->origintype;
16537 }
16538 
16539 /** returns origin constraint handler that created the row (NULL if not available) */
16541  SCIP_ROW* row /**< LP row */
16542  )
16543 {
16544  assert( row != NULL );
16545 
16547  {
16548  assert( row->origin != NULL );
16549  return (SCIP_CONSHDLR*) row->origin;
16550  }
16551  return NULL;
16552 }
16553 
16554 /** returns origin separator that created the row (NULL if not available) */
16556  SCIP_ROW* row /**< LP row */
16557  )
16558 {
16559  assert( row != NULL );
16560 
16562  {
16563  assert( row->origin != NULL );
16564  return (SCIP_SEPA*) row->origin;
16565  }
16566  return NULL;
16567 }
16568 
16569 /** returns TRUE iff row is member of the global cut pool */
16571  SCIP_ROW* row /**< LP row */
16572  )
16573 {
16574  assert(row != NULL);
16575 
16576  return row->inglobalcutpool;
16577 }
16578 
16579 /** gets position of row in current LP, or -1 if it is not in LP */
16581  SCIP_ROW* row /**< LP row */
16582  )
16583 {
16584  assert(row != NULL);
16585  assert((row->lppos == -1) == (row->lpdepth == -1));
16586 
16587  return row->lppos;
16588 }
16589 
16590 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
16592  SCIP_ROW* row /**< LP row */
16593  )
16594 {
16595  assert(row != NULL);
16596  assert((row->lppos == -1) == (row->lpdepth == -1));
16597 
16598  return row->lpdepth;
16599 }
16600 
16601 /** returns TRUE iff row is member of current LP */
16603  SCIP_ROW* row /**< LP row */
16604  )
16605 {
16606  assert(row != NULL);
16607  assert((row->lppos == -1) == (row->lpdepth == -1));
16608 
16609  return (row->lppos >= 0);
16610 }
16611 
16612 /** changes the rank of LP row */
16614  SCIP_ROW* row, /**< LP row */
16615  int rank /**< new value for rank */
16616  )
16617 {
16618  assert(row != NULL);
16619 
16620  row->rank = rank;
16621 }
16622 
16623 /** returns the number of times that this row has been sharp in an optimal LP solution */
16625  SCIP_ROW* row /**< row */
16626  )
16627 {
16628  assert(row != NULL);
16629 
16630  return row->activeinlpcounter;
16631 }
16632 
16633 /** returns the number of LPs since this row has been created */
16635  SCIP_ROW* row /**< row */
16636  )
16637 {
16638  assert(row != NULL);
16639 
16640  return row->nlpsaftercreation;
16641 }
16642 
16643 /** gets array with columns of the LP */
16645  SCIP_LP* lp /**< current LP data */
16646  )
16647 {
16648  assert(lp != NULL);
16649 
16650  return lp->cols;
16651 }
16652 
16653 /** gets current number of columns in LP */
16655  SCIP_LP* lp /**< current LP data */
16656  )
16657 {
16658  assert(lp != NULL);
16659 
16660  return lp->ncols;
16661 }
16662 
16663 /** gets array with rows of the LP */
16665  SCIP_LP* lp /**< current LP data */
16666  )
16667 {
16668  assert(lp != NULL);
16669 
16670  return lp->rows;
16671 }
16672 
16673 /** gets current number of rows in LP */
16675  SCIP_LP* lp /**< current LP data */
16676  )
16677 {
16678  assert(lp != NULL);
16679 
16680  return lp->nrows;
16681 }
16682 
16683 /** gets array with newly added columns after the last mark */
16685  SCIP_LP* lp /**< current LP data */
16686  )
16687 {
16688  assert(lp != NULL);
16689  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16690 
16691  return &(lp->cols[lp->firstnewcol]);
16692 }
16693 
16694 /** gets number of newly added columns after the last mark */
16696  SCIP_LP* lp /**< current LP data */
16697  )
16698 {
16699  assert(lp != NULL);
16700  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
16701 
16702  return lp->ncols - lp->firstnewcol;
16703 }
16704 
16705 /** gets array with newly added rows after the last mark */
16707  SCIP_LP* lp /**< current LP data */
16708  )
16709 {
16710  assert(lp != NULL);
16711  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16712 
16713  return &(lp->rows[lp->firstnewrow]);
16714 }
16715 
16716 /** gets number of newly added rows after the last mark */
16718  SCIP_LP* lp /**< current LP data */
16719  )
16720 {
16721  assert(lp != NULL);
16722  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
16723 
16724  return lp->nrows - lp->firstnewrow;
16725 }
16726 
16727 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
16729  SCIP_SET* set, /**< global SCIP settings */
16730  SCIP_LP* lp /**< LP data */
16731  )
16732 {
16733  if( lp->objsqrnormunreliable )
16734  {
16735  SCIP_COL** cols;
16736  int c;
16737 
16738  cols = lp->cols;
16739  assert(cols != NULL || lp->ncols == 0);
16740 
16741  lp->objsqrnorm = 0.0;
16742 
16743  for( c = lp->ncols - 1; c >= 0; --c )
16744  {
16745  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
16746  }
16747  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
16748 
16749  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
16750  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
16751 
16753  }
16754  return;
16755 }
16756 
16757 /** gets Euclidean norm of objective function vector of column variables, only use this method if
16758  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
16760  SCIP_LP* lp /**< LP data */
16761  )
16762 {
16763  assert(lp != NULL);
16764  assert(!lp->objsqrnormunreliable);
16765  assert(lp->objsqrnorm >= 0.0);
16766 
16767  return SQRT(lp->objsqrnorm);
16768 }
16769 
16770 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16772  SCIP_LP* lp, /**< LP data */
16773  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
16774  )
16775 {
16776  assert(lp != NULL);
16777 
16778  lp->rootlpisrelax = isrelax;
16779 }
16780 
16781 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
16783  SCIP_LP* lp /**< LP data */
16784  )
16785 {
16786  assert(lp != NULL);
16787 
16788  return lp->rootlpisrelax;
16789 }
16790 
16791 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
16793  SCIP_LP* lp /**< LP data */
16794  )
16795 {
16796  assert(lp != NULL);
16797 
16798  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
16799 }
16800 
16801 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
16802  * returns SCIP_INVALID if the root node LP was not (yet) solved
16803  */
16805  SCIP_LP* lp /**< LP data */
16806  )
16807 {
16808  assert(lp != NULL);
16809 
16810  return lp->rootlpobjval;
16811 }
16812 
16813 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
16814  * returns SCIP_INVALID if the root node LP was not (yet) solved
16815  */
16817  SCIP_LP* lp /**< LP data */
16818  )
16819 {
16820  assert(lp != NULL);
16821 
16822  return lp->rootlooseobjval;
16823 }
16824 
16825 /** gets the LP solver interface */
16827  SCIP_LP* lp /**< current LP data */
16828  )
16829 {
16830  assert(lp != NULL);
16831 
16832  return lp->lpi;
16833 }
16834 
16835 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
16837  SCIP_LP* lp, /**< LP data */
16838  SCIP_Bool relax /**< is the current lp a relaxation? */
16839  )
16840 {
16841  assert(lp != NULL);
16842 
16843  lp->isrelax = relax;
16844 }
16845 
16846 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
16847  * solution value a valid local lower bound?
16848  */
16850  SCIP_LP* lp /**< LP data */
16851  )
16852 {
16853  assert(lp != NULL);
16854 
16855  return lp->isrelax;
16856 }
16857 
16858 /** returns whether the current LP is flushed and solved */
16860  SCIP_LP* lp /**< current LP data */
16861  )
16862 {
16863  assert(lp != NULL);
16864 
16865  return lp->flushed && lp->solved;
16866 }
16867 
16868 /** return whether the current LP solution passed the primal feasibility check */
16870  SCIP_LP* lp /**< current LP data */
16871  )
16872 {
16873  assert(lp != NULL);
16874 
16875  return (lp->primalchecked && lp->primalfeasible);
16876 }
16877 
16878 /** return whether the current LP solution passed the dual feasibility check */
16880  SCIP_LP* lp /**< current LP data */
16881  )
16882 {
16883  assert(lp != NULL);
16884 
16885  return (lp->dualchecked && lp->dualfeasible);
16886 }
16887 
16888 /** returns whether the current LP solution is a basic solution */
16890  SCIP_LP* lp /**< current LP data */
16891  )
16892 {
16893  assert(lp != NULL);
16894 
16895  return lp->solisbasic;
16896 }
16897 
16898 /** returns whether the LP is in diving mode */
16900  SCIP_LP* lp /**< current LP data */
16901  )
16902 {
16903  assert(lp != NULL);
16904 
16905  return lp->diving;
16906 }
16907 
16908 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
16910  SCIP_LP* lp /**< current LP data */
16911  )
16912 {
16913  assert(lp != NULL);
16914 
16915  return lp->divingobjchg;
16916 }
16917 
16918 /** marks the diving LP to have a changed objective function */
16920  SCIP_LP* lp /**< current LP data */
16921  )
16922 {
16923  assert(lp != NULL);
16924  assert(lp->diving || lp->probing);
16925 
16926  lp->divingobjchg = TRUE;
16927 }
16928 
16929 /** marks the diving LP to not have a changed objective function anymore */
16931  SCIP_LP* lp /**< current LP data */
16932  )
16933 {
16934  assert(lp != NULL);
16935  assert(lp->diving || lp->probing);
16936 
16937  lp->divingobjchg = FALSE;
16938 }
16939 
16940 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
16942  SCIP_LP* lp /**< current LP data */
16943  )
16944 {
16945  assert(lp != NULL);
16946  assert(lp->diving || lp->ndivechgsides == 0);
16947 
16948  return (lp->ndivechgsides > 0);
16949 }
16950 
16951 /** compute relative interior point
16952  *
16953  * We use the approach of@par
16954  * R. Freund, R. Roundy, M. J. Todd@par
16955  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
16956  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
16957  *
16958  * to compute a relative interior point for the current LP.
16959  *
16960  * Assume the original LP looks as follows:
16961  * \f[
16962  * \begin{array}{rrl}
16963  * \min & c^T x &\\
16964  * & A x & \geq a\\
16965  * & B x & \leq b\\
16966  * & D x & = d.
16967  * \end{array}
16968  * \f]
16969  * Note that bounds should be included in the system.
16970  *
16971  * To find an interior point the following LP does the job:
16972  * \f[
16973  * \begin{array}{rrl}
16974  * \max & 1^T y &\\
16975  * & A x - y - \alpha a & \geq 0\\
16976  * & B x + y - \alpha b & \leq 0\\
16977  * & D x - \alpha d & = 0\\
16978  * & 0 \leq y & \leq 1\\
16979  * & \alpha & \geq 1.
16980  * \end{array}
16981  * \f]
16982  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
16983  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
16984  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
16985  */
16987  SCIP_SET* set, /**< global SCIP settings */
16988  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16989  SCIP_LP* lp, /**< LP data */
16990  SCIP_PROB* prob, /**< problem data */
16991  SCIP_Bool relaxrows, /**< should the rows be relaxed */
16992  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
16993  SCIP_Real timelimit, /**< time limit for LP solver */
16994  int iterlimit, /**< iteration limit for LP solver */
16995  SCIP_Real* point, /**< array to store relative interior point on exit */
16996  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
16997  )
16998 {
16999  SCIP_LPI* lpi;
17000  SCIP_Real* obj;
17001  SCIP_Real* lb;
17002  SCIP_Real* ub;
17003  SCIP_Real* primal;
17004  SCIP_Real* colvals;
17005  SCIP_Real zero;
17006  SCIP_Real minusinf;
17007  SCIP_Real plusinf;
17008  SCIP_Real objval;
17009  SCIP_Real alpha;
17010  SCIP_RETCODE retcode;
17011  int* colinds;
17012  int nnewcols;
17013 #ifndef NDEBUG
17014  int nslacks;
17015 #endif
17016  int beg;
17017  int cnt;
17018  int i;
17019  int j;
17020 
17021  assert(set != NULL);
17022  assert(lp != NULL);
17023  assert(point != NULL);
17024  assert(success != NULL);
17025 
17026  *success = FALSE;
17027 
17028  /* check time and iteration limits */
17029  if ( timelimit <= 0.0 || iterlimit <= 0 )
17030  return SCIP_OKAY;
17031 
17032  /* exit if there are no columns */
17033  assert(lp->nrows >= 0);
17034  assert(lp->ncols >= 0);
17035  if( lp->ncols == 0 )
17036  return SCIP_OKAY;
17037 
17038  /* disable objective cutoff if we have none */
17039  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
17040  inclobjcutoff = FALSE;
17041 
17042  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
17043 
17044  /* if there are no rows, we return the zero point */
17045  if( lp->nrows == 0 && !inclobjcutoff )
17046  {
17047  /* create zero point */
17048  BMSclearMemoryArray(point, lp->ncols);
17049  *success = TRUE;
17050 
17051  return SCIP_OKAY;
17052  }
17053 
17054  /* create auxiliary LP */
17055  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
17056 
17058  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17059  {
17060  SCIP_CALL( retcode );
17061  }
17062 
17064  if( retcode != SCIP_OKAY && retcode != SCIP_PARAMETERUNKNOWN )
17065  {
17066  SCIP_CALL( retcode );
17067  }
17068 
17069  /* get storage */
17070  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17071  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17072  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17073  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17074 
17075  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17076  for( j = 0; j < lp->ncols; ++j )
17077  {
17078  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17079  obj[j] = 0.0;
17080  lb[j] = -SCIPlpiInfinity(lpi);
17081  ub[j] = SCIPlpiInfinity(lpi);
17082  /* note: we could also use the original bounds - free variables seem to be faster. */
17083  }
17084 
17085  /* add artificial alpha variable */
17086  nnewcols = lp->ncols;
17087  obj[nnewcols] = 0.0;
17088  lb[nnewcols] = 1.0;
17089  ub[nnewcols] = SCIPlpiInfinity(lpi);
17090  ++nnewcols;
17091 
17092  /* create slacks for rows */
17093  for( i = 0; i < lp->nrows; ++i )
17094  {
17095  SCIP_ROW* row;
17096 
17097  row = lp->rows[i];
17098  assert( row != NULL );
17099 
17100  if( SCIProwIsModifiable(row) )
17101  continue;
17102 
17103  /* make sure row is sorted */
17104  rowSortLP(row);
17105  assert( row->lpcolssorted );
17106 
17107  /* check whether we have an equation */
17108  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17109  {
17110  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17111  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17112  }
17113  else if( relaxrows )
17114  {
17115  /* otherwise add slacks for each side if necessary */
17116  if( !SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17117  {
17118  obj[nnewcols] = 1.0;
17119  lb[nnewcols] = 0.0;
17120  ub[nnewcols] = 1.0;
17121  ++nnewcols;
17122  }
17123  if( !SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17124  {
17125  obj[nnewcols] = 1.0;
17126  lb[nnewcols] = 0.0;
17127  ub[nnewcols] = 1.0;
17128  ++nnewcols;
17129  }
17130  }
17131  }
17132 
17133  /* create slacks for objective cutoff row */
17134  if( inclobjcutoff && relaxrows )
17135  {
17136  /* add slacks for right hand side */
17137  obj[nnewcols] = 1.0;
17138  lb[nnewcols] = 0.0;
17139  ub[nnewcols] = 1.0;
17140  ++nnewcols;
17141  }
17142 
17143  /* create slacks for bounds */
17144  for( j = 0; j < lp->ncols; ++j )
17145  {
17146  SCIP_COL* col;
17147 
17148  col = lp->cols[j];
17149  assert( col != NULL );
17150 
17151  /* no slacks for fixed variables */
17152  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17153  continue;
17154 
17155  /* add slacks for each bound if necessary */
17156  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17157  {
17158  obj[nnewcols] = 1.0;
17159  lb[nnewcols] = 0.0;
17160  ub[nnewcols] = 1.0;
17161  ++nnewcols;
17162  }
17163  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17164  {
17165  obj[nnewcols] = 1.0;
17166  lb[nnewcols] = 0.0;
17167  ub[nnewcols] = 1.0;
17168  ++nnewcols;
17169  }
17170  }
17171 #ifndef NDEBUG
17172  nslacks = nnewcols - lp->ncols - 1;
17173  assert( nslacks >= 0 );
17174  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17175 #endif
17176 
17177  /* add columns */
17178  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17179 
17180  /* free storage */
17181  SCIPsetFreeBufferArray(set, &obj);
17182  SCIPsetFreeBufferArray(set, &ub);
17183  SCIPsetFreeBufferArray(set, &lb);
17184 
17185  /* prepare storage for rows */
17186  SCIP_CALL( SCIPsetAllocBufferArray(set, &colinds, lp->ncols+2) );
17187  SCIP_CALL( SCIPsetAllocBufferArray(set, &colvals, lp->ncols+2) );
17188 
17189  /* create rows arising from original rows */
17190  cnt = 0;
17191  beg = 0;
17192  zero = 0.0;
17193  minusinf = -SCIPlpiInfinity(lpi);
17194  plusinf = SCIPlpiInfinity(lpi);
17195  for( i = 0; i < lp->nrows; ++i )
17196  {
17197  SCIP_ROW* row;
17198  SCIP_COL** rowcols;
17199  SCIP_Real* rowvals;
17200  SCIP_Real lhs;
17201  SCIP_Real rhs;
17202  int nnonz;
17203 
17204  row = lp->rows[i];
17205  assert( row != NULL );
17206 
17207  if( SCIProwIsModifiable(row) )
17208  continue;
17209  assert( row->lpcolssorted );
17210 
17211  /* get row data */
17212  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17213  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17214  nnonz = row->nlpcols;
17215  assert( nnonz <= lp->ncols );
17216  rowcols = row->cols;
17217  rowvals = row->vals;
17218 
17219  /* set up indices */
17220  for( j = 0; j < nnonz; ++j )
17221  {
17222  assert( rowcols[j] != NULL );
17223  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17224  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17225  colinds[j] = rowcols[j]->lppos;
17226  colvals[j] = rowvals[j];
17227  }
17228 
17229  /* if we have an equation */
17230  if( SCIPsetIsEQ(set, lhs, rhs) )
17231  {
17232  /* add artificial variable */
17233  colinds[nnonz] = lp->ncols;
17234  colvals[nnonz] = -rhs;
17235 
17236  /* add row */
17237  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &zero, NULL, nnonz+1, &beg, colinds, colvals) );
17238  }
17239  else
17240  {
17241  SCIP_Real abslhs = REALABS(lhs);
17242  SCIP_Real absrhs = REALABS(rhs);
17243 
17244  /* treat lhs */
17245  if( !SCIPsetIsInfinity(set, abslhs) )
17246  {
17247  assert(!SCIPsetIsEQ(set, lhs, rhs));
17248 
17249  /* add artificial variable */
17250  colinds[nnonz] = lp->ncols;
17251  colvals[nnonz] = -lhs;
17252 
17253  if( relaxrows )
17254  {
17255  /* add slack variable */
17256  colinds[nnonz+1] = lp->ncols + 1 + cnt; /*lint !e679*/
17257  colvals[nnonz+1] = -MAX(1.0, lhs); /*lint !e679*/
17258  ++cnt;
17259  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, nnonz+2, &beg, colinds, colvals) );
17260  }
17261  else
17262  {
17263  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, nnonz+1, &beg, colinds, colvals) );
17264  }
17265  }
17266 
17267  /* treat rhs */
17268  if( !SCIPsetIsInfinity(set, absrhs) )
17269  {
17270  assert(!SCIPsetIsEQ(set, lhs, rhs));
17271 
17272  /* add artificial variable */
17273  colinds[nnonz] = lp->ncols;
17274  colvals[nnonz] = -rhs;
17275 
17276  if( relaxrows )
17277  {
17278  /* add slack variable */
17279  colinds[nnonz+1] = lp->ncols + 1 + cnt; /*lint !e679*/
17280  colvals[nnonz+1] = MAX(1.0, absrhs); /*lint !e679*/
17281  ++cnt;
17282  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz+2, &beg, colinds, colvals) );
17283  }
17284  else
17285  {
17286  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz+1, &beg, colinds, colvals) );
17287  }
17288  }
17289  }
17290  }
17291 
17292  /* create row arising from objective cutoff */
17293  if( inclobjcutoff )
17294  {
17295  SCIP_Real rhs;
17296  int nnonz;
17297 
17298  /* get row data */
17299  assert(lp->looseobjvalinf == 0);
17300  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17301 
17302  /* set up indices and coefficients */
17303  nnonz = 0;
17304  for( j = 0; j < lp->ncols; ++j )
17305  {
17306  assert( lp->cols[j] != NULL );
17307  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17308  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17309  if( lp->cols[j]->obj == 0.0 )
17310  continue;
17311  colinds[nnonz] = lp->cols[j]->lppos;
17312  colvals[nnonz] = lp->cols[j]->obj;
17313  ++nnonz;
17314  }
17315 
17316  /* treat rhs */
17317  /* add artificial variable */
17318  colinds[nnonz] = lp->ncols;
17319  colvals[nnonz] = -rhs;
17320  ++nnonz;
17321 
17322  if( relaxrows )
17323  {
17324  SCIP_Real absrhs = REALABS(rhs);
17325 
17326  /* add slack variable */
17327  colinds[nnonz] = lp->ncols + 1 + cnt;
17328  colvals[nnonz] = MAX(1.0, absrhs);
17329  ++cnt;
17330  ++nnonz;
17331  }
17332  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, nnonz, &beg, colinds, colvals) );
17333  }
17334 
17335  /* create rows arising from bounds */
17336  for( j = 0; j < lp->ncols; ++j )
17337  {
17338  SCIP_COL* col;
17339  SCIP_Real abscollb;
17340  SCIP_Real abscolub;
17341 
17342  col = lp->cols[j];
17343  assert( col != NULL );
17344  assert( col->lppos == j );
17345 
17346  /* set up index of column */
17347  colinds[0] = j;
17348  colvals[0] = 1.0;
17349 
17350  /* fixed variable */
17351  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17352  {
17353  /* add artificial variable */
17354  colinds[1] = lp->ncols;
17355  colvals[1] = -col->lb;
17356 
17357  /* add row */
17358  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &zero, NULL, 2, &beg, colinds, colvals) );
17359 
17360  continue;
17361  }
17362 
17363  abscollb = REALABS(col->lb);
17364  abscolub = REALABS(col->ub);
17365 
17366  /* lower bound */
17367  if( !SCIPsetIsInfinity(set, abscollb) )
17368  {
17369  /* add artificial variable */
17370  colinds[1] = lp->ncols;
17371  colvals[1] = -col->lb;
17372 
17373  /* add slack variable */
17374  colinds[2] = lp->ncols + 1 + cnt;
17375  colvals[2] = -MAX(1.0, abscollb);
17376  ++cnt;
17377  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &zero, &plusinf, NULL, 3, &beg, colinds, colvals) );
17378  }
17379 
17380  /* upper bound */
17381  if( !SCIPsetIsInfinity(set, abscolub) )
17382  {
17383  /* add artificial variable */
17384  colinds[1] = lp->ncols;
17385  colvals[1] = -col->ub;
17386 
17387  /* add slack variable */
17388  colinds[2] = lp->ncols + 1 + cnt;
17389  colvals[2] = MAX(1.0, abscolub);
17390  ++cnt;
17391  SCIP_CALL( SCIPlpiAddRows(lpi, 1, &minusinf, &zero, NULL, 3, &beg, colinds, colvals) );
17392  }
17393  }
17394  assert( cnt == nslacks );
17395 
17396  SCIPsetFreeBufferArray(set, &colvals);
17397  SCIPsetFreeBufferArray(set, &colinds);
17398 
17399 #ifdef SCIP_OUTPUT
17400  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
17401 #endif
17402 
17403 #ifndef NDEBUG
17404  {
17405  int ncols;
17406  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
17407  assert( ncols == nnewcols );
17408  }
17409 #endif
17410 
17411  /* set time limit */
17412  if( SCIPsetIsInfinity(set, timelimit) )
17413  timelimit = SCIPlpiInfinity(lpi);
17414  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
17415 
17416  /* check, if parameter is unknown */
17417  if ( retcode == SCIP_PARAMETERUNKNOWN )
17418  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
17419 
17420  /* set iteration limit */
17421  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
17422 
17423  /* check, if parameter is unknown */
17424  if ( retcode == SCIP_PARAMETERUNKNOWN )
17425  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
17426 
17427  /* solve and store point */
17428  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
17429  retcode = SCIPlpiSolveDual(lpi); /* dual is usually faster */
17430 
17431  /* detect possible error in LP solver */
17432  if ( retcode != SCIP_OKAY )
17433  {
17434  SCIP_CALL( SCIPlpiFree(&lpi) );
17435  return SCIP_OKAY;
17436  }
17437 
17438 #ifndef NDEBUG
17439  if ( SCIPlpiIsIterlimExc(lpi) )
17440  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
17441  if ( SCIPlpiIsTimelimExc(lpi) )
17442  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
17443 #endif
17444 
17445  if( SCIPlpiIsOptimal(lpi) )
17446  {
17447  /* get primal solution */
17448  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
17449  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
17450  alpha = primal[lp->ncols];
17451  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
17452 
17453  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
17454 
17455  /* construct relative interior point */
17456  for( j = 0; j < lp->ncols; ++j )
17457  point[j] = primal[j]/alpha;
17458 
17459 #ifdef SCIP_DEBUG
17460  /* check whether the point is a relative interior point */
17461  cnt = 0;
17462  if( relaxrows )
17463  {
17464  for( i = 0; i < lp->nrows; ++i )
17465  {
17466  SCIP_ROW* row;
17467  SCIP_COL** rowcols;
17468  SCIP_Real* rowvals;
17469  SCIP_Real lhs;
17470  SCIP_Real rhs;
17471  SCIP_Real sum;
17472  int nnonz;
17473 
17474  row = lp->rows[i];
17475  assert( row != NULL );
17476 
17477  /* get row data */
17478  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17479  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17480  nnonz = row->nlpcols;
17481  assert( nnonz <= lp->ncols );
17482  rowcols = row->cols;
17483  rowvals = row->vals;
17484 
17485  sum = 0.0;
17486  for( j = 0; j < nnonz; ++j )
17487  sum += rowvals[j] * primal[rowcols[j]->lppos];
17488  sum /= alpha;
17489 
17490  /* if we have an equation */
17491  if( SCIPsetIsEQ(set, lhs, rhs) )
17492  {
17493  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
17494  }
17495  else
17496  {
17497  /* treat lhs */
17498  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
17499  {
17500  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
17501  ++cnt;
17502  }
17503  /* treat rhs */
17504  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
17505  {
17506  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17507  ++cnt;
17508  }
17509  }
17510  }
17511  if( inclobjcutoff )
17512  {
17513  SCIP_Real sum;
17514 #ifndef NDEBUG
17515  SCIP_Real rhs;
17516 
17517  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17518 #endif
17519  sum = 0.0;
17520  for( j = 0; j < lp->ncols; ++j )
17521  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
17522  sum /= alpha;
17523 
17524  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
17525  ++cnt;
17526  }
17527  }
17528  /* check bounds */
17529  for( j = 0; j < lp->ncols; ++j )
17530  {
17531  SCIP_COL* col;
17532 #ifndef NDEBUG
17533  SCIP_Real val;
17534 #endif
17535 
17536  col = lp->cols[j];
17537  assert( col != NULL );
17538 #ifndef NDEBUG
17539  val = primal[col->lppos] / alpha;
17540 #endif
17541  /* if the variable is not fixed */
17542  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
17543  {
17544  /* treat lb */
17545  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
17546  {
17547  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
17548  ++cnt;
17549  }
17550  /* treat rhs */
17551  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
17552  {
17553  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
17554  ++cnt;
17555  }
17556  }
17557  }
17558 #endif
17559 
17560  /* free */
17561  SCIPsetFreeBufferArray(set, &primal);
17562 
17563  *success = TRUE;
17564  }
17565  SCIP_CALL( SCIPlpiFree(&lpi) );
17566 
17567  return SCIP_OKAY;
17568 }
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:6632
SCIP_Longint nprimallps
Definition: struct_stat.h:173
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:16520
SCIP_Bool solisbasic
Definition: struct_lp.h:350
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:1693
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:61
SCIP_Bool lpissolved
Definition: struct_lp.h:116
int nunlinked
Definition: struct_lp.h:228
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4607
int firstnewrow
Definition: struct_lp.h:315
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:15619
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6338
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:12615
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:4563
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:71
SCIP_Longint nsbdivinglps
Definition: struct_stat.h:187
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:5517
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5820
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2494
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2783
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6521
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:426
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2683
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:13144
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8673
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:9858
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:16941
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2758
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7110
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5575
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2507
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:16717
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6025
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2884
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:6753
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:4786
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1726
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13448
SCIP_STATUS status
Definition: struct_stat.h:165
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:16899
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3441
SCIP_Real farkascoef
Definition: struct_lp.h:141
unsigned int ubchanged
Definition: struct_lp.h:175
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3261
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1821
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:107
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9403
int nummaxval
Definition: struct_lp.h:235
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:16836
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2740
SCIP_Longint validactivitylp
Definition: struct_lp.h:223
int lpifirstchgrow
Definition: struct_lp.h:301
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2346
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3513
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:16470
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1358
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:16555
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:93
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:188
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6505
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:78
int * cols_index
Definition: struct_lp.h:219
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15486
int nremovablecols
Definition: struct_lp.h:310
char * name
Definition: struct_var.h:228
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:14844
SCIP_Bool primalfeasible
Definition: struct_lp.h:346
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:16986
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:3033
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:842
int nchgrows
Definition: struct_lp.h:305
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:8416
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9570
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3146
char * name
Definition: struct_lp.h:217
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:17317
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6104
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:3382
int nlpicols
Definition: struct_lp.h:297
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5915
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:14813
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6252
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:16771
SCIP_Longint nlps
Definition: struct_stat.h:171
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:2112
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17169
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6458
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:332
#define SCIP_MAXSTRLEN
Definition: def.h:225
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7750
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3349
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16150
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6002
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3612
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:16728
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:68
internal methods for clocks and timing issues
unsigned int origintype
Definition: struct_lp.h:254
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13021
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16270
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3108
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16282
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5640
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:105
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16312
SCIP_Real objsumnorm
Definition: struct_lp.h:280
SCIP_Longint ndivinglps
Definition: struct_stat.h:185
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: event.c:1851
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17225
SCIP_ROW ** chgrows
Definition: struct_lp.h:285
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5169
SCIP_COL ** chgcols
Definition: struct_lp.h:284
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:5415
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:14433
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14358
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11560
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16450
int rank
Definition: struct_lp.h:238
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2257
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:990
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16735
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5379
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1225
int rowssize
Definition: struct_lp.h:312
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8638
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2639
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3567
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7642
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:16624
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12694
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13339
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1496
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13627
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:11092
unsigned int nonlprowssorted
Definition: struct_lp.h:172
int nclockskipsleft
Definition: struct_stat.h:252
SCIP_COL ** cols
Definition: struct_lp.h:286
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9797
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1261
int nlpirows
Definition: struct_lp.h:300
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3181
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:649
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:97
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:131
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:16326
#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:3148
static const int nscalars
Definition: lp.c:5574
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:8996
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1534
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:38
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13311
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16391
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
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1851
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:15655
#define EPSEQ(x, y, eps)
Definition: def.h:170
#define EPSISINT(x, eps)
Definition: def.h:182
int pseudoobjvalinf
Definition: struct_lp.h:319
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:16889
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:13380
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6058
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:16181
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3488
int divinglpiitlim
Definition: struct_lp.h:323
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16092
SCIP_Bool solved
Definition: struct_lp.h:345
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:9618
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Longint nrootlps
Definition: struct_stat.h:172
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:16439
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16072
SCIP_Bool dualchecked
Definition: struct_lp.h:349
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2539
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5629
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:15633
#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:7973
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool lpifromscratch
Definition: struct_lp.h:363
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:549
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1099
unsigned int basisstatus
Definition: struct_lp.h:239
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2720
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6553
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9731
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:16804
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15473
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1834
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:424
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2534
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:5306
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16862
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3466
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:338
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:15416
unsigned int delaysort
Definition: struct_lp.h:242
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5091
unsigned int basisstatus
Definition: struct_lp.h:170
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:16213
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Real lpidualfeastol
Definition: struct_lp.h:276
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:14782
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1588
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5726
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3010
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:8794
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:325
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:82
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6709
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:15237
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:5811
int index
Definition: struct_lp.h:158
SCIP_Real relpseudoobjval
Definition: struct_lp.h:270
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2859
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:11960
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:147
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11878
SCIP_Real pseudoobjval
Definition: struct_lp.h:268
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:16664
SCIP_Bool diving
Definition: struct_lp.h:358
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7664
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:13062
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12723
SCIP_Real rootlooseobjval
Definition: struct_lp.h:272
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:3433
int firstnewcol
Definition: struct_lp.h:311
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:15021
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3337
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:9872
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:4957
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:14373
unsigned int integral
Definition: struct_lp.h:247
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:9838
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:5651
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:16530
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:2945
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1023
#define SCIP_LONGINT_MAX
Definition: def.h:131
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:147
int lpifirstchgcol
Definition: struct_lp.h:298
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1841
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:104
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:15458
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2506
#define checkRow(row)
Definition: lp.c:652
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5871
int maxdepth
Definition: struct_stat.h:213
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:8768
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:76
int looseobjvalinf
Definition: struct_lp.h:316
SCIP_Real obj
Definition: struct_var.h:202
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:339
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2577
unsigned int rhschanged
Definition: struct_lp.h:245
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:5358
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1294
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:16411
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:282
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:11001
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12527
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4595
internal methods for LP management
int lazycolssize
Definition: struct_lp.h:308
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13540
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_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:16782
int colssize
Definition: struct_lp.h:306
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:333
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:15419
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:369
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:378
SCIP_Bool lpipresolving
Definition: struct_lp.h:364
int nremovablerows
Definition: struct_lp.h:314
SCIP_Bool primalchecked
Definition: struct_lp.h:347
SCIP_Real lpiuobjlim
Definition: struct_lp.h:274
SCIP_Bool strongbranching
Definition: struct_lp.h:355
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1286
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
#define checkLinks(lp)
Definition: lp.c:1581
int lpithreads
Definition: struct_lp.h:326
int ndivechgsides
Definition: struct_lp.h:321
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:16654
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:11851
int * linkpos
Definition: struct_lp.h:221
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2623
#define FEASTOLTIGHTFAC
Definition: lp.c:11144
#define SCIP_DEFAULT_EPSILON
Definition: def.h:151
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:11147
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5611
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:16602
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:6387
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2302
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:8077
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:3516
int nloosevars
Definition: struct_lp.h:317
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:1934
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:16792
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3716
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4686
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17179
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5989
int divechgsidessize
Definition: struct_lp.h:322
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5557
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:14982
int * linkpos
Definition: struct_lp.h:157
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:351
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5784
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:39
int lpiitlim
Definition: struct_lp.h:324
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:9755
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:7578
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1276
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:277
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:3316
int glbpseudoobjvalinf
Definition: struct_lp.h:318
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:16695
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13407
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16379
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:420
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2428
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13672
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:15134
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16115
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6537
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:15443
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5496
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:5846
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2414
SCIP_ROW ** divechgrows
Definition: struct_lp.h:292
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:374
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:7924
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: event.c:1758
SCIP_RETCODE SCIPlpWriteMip(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *fname, SCIP_Bool genericnames, SCIP_Bool origobj, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_Bool lazyconss)
Definition: lp.c:15670
SCIP_Bool installing
Definition: struct_lp.h:354
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:379
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:16869
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16302
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:4746
SCIP_Real SCIPsetLpfeastol(SCIP_SET *set)
Definition: set.c:5441
#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:3122
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:13750
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:16879
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:169
SCIP_Bool lpilpinfo
Definition: struct_lp.h:365
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:16260
SCIP_Real pseudoactivity
Definition: struct_lp.h:207
SCIP_PRICING lpipricing
Definition: struct_lp.h:330
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9148
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 SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1557
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9331
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:16644
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16500
SCIP_Bool adjustlpval
Definition: struct_lp.h:362
SCIP_Real minval
Definition: struct_lp.h:203
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:3951
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIPInterval sqrt(const SCIPInterval &x)
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3331
SCIP_ROW ** lpirows
Definition: struct_lp.h:283
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2190
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:180
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2448
static SCIP_RETCODE lpCleanupRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition: lp.c:14911
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8368
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5560
SCIP_Longint validfarkaslp
Definition: struct_lp.h:295
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:9645
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9488
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5462
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16082
#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:16555
int lpiscaling
Definition: struct_lp.h:329
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:1992
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3715
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:16490
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:855
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6166
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1028
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1842
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14062
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:5978
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2653
SCIP_Real cutoffbound
Definition: struct_lp.h:273
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6280
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:9207
internal miscellaneous methods
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:16540
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:9951
SCIP_Bool isrelax
Definition: struct_lp.h:352
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:16759
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
#define REALABS(x)
Definition: def.h:169
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:293
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2646
SCIP_Bool looseobjvalid
Definition: struct_lp.h:336
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:432
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:14292
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:316
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2521
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6003
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:17307
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6356
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:16674
int lpirandomseed
Definition: struct_lp.h:328
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:16919
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:342
SCIP_Bool resolvelperror
Definition: struct_lp.h:361
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:16401
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8121
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2395
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11083
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5539
#define lpCutoffDisabled(set)
Definition: lp.c:2599
int lpicolssize
Definition: struct_lp.h:296
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:16826
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12543
SCIP_LPI * lpi
Definition: struct_lp.h:281
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5129
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2385
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:16510
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1776
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:887
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:265
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5959
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16337
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6653
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:180
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:291
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2249
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4049
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:148
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:8746
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_clp.cpp:2671
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8598
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5182
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:11591
SCIP_Longint nduallps
Definition: struct_stat.h:175
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6296
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16171
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:423
internal methods for problem variables
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7715
#define SCIP_UNKNOWN
Definition: def.h:166
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9514
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5662
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16347
int nchgcols
Definition: struct_lp.h:303
int len
Definition: struct_lp.h:160
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:16816
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9469
#define SCIP_Bool
Definition: def.h:61
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12626
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5411
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:181
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:412
int numminval
Definition: struct_lp.h:236
int lpipos
Definition: struct_lp.h:231
int size
Definition: struct_lp.h:225
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3510
unsigned int modifiable
Definition: struct_lp.h:249
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:778
void SCIPprintSysError(const char *message)
Definition: misc.c:9276
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:14532
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:9073
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2715
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16102
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5879
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:95
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3768
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:909
int chgrowssize
Definition: struct_lp.h:304
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:16706
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:17556
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3658
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:359
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9548
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_clp.cpp:3428
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:425
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16909
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3626
#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:343
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17027
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2211
#define DIVESTACKINITSIZE
Definition: lp.c:8811
#define SCIPsetDebugMsg
Definition: set.h:1870
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:373
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:4079
int minidx
Definition: struct_lp.h:233
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:16192
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2133
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2204
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:377
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2817
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17017
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:5260
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1653
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:8814
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9531
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:747
unsigned int lpcolssorted
Definition: struct_lp.h:240
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:360
SCIP_Longint validsollp
Definition: struct_lp.h:294
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3151
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9500
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16424
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16883
static void colSortLP(SCIP_COL *col)
Definition: lp.c:926
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13228
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:793
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6610
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:3794
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6669
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_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2347
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15060
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5937
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5748
SCIP_ROW ** rows
Definition: struct_lp.h:288
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:3671
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1172
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:289
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:9814
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:2891
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:7602
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3246
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3276
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:11940
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:16480
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:12848
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:146
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16128
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3412
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9117
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:4327
#define SCIP_REAL_MAX
Definition: def.h:146
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5208
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6247
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6437
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:12980
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:10864
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7469
#define checkRowObjprod(row)
Definition: lp.c:727
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12582
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:15509
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:7908
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:12750
unsigned int removable
Definition: struct_lp.h:250
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:244
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2570
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:149
SCIP_COL ** lazycols
Definition: struct_lp.h:287
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:457
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:952
static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1423
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:267
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16357
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:14630
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12602
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16235
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6594
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2607
int age
Definition: struct_lp.h:168
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3221
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:6416
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:357
SCIP_Real rellooseobjval
Definition: struct_lp.h:263
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16161
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8712
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:9882
static const SCIP_Real scalars[]
Definition: lp.c:5573
int lpipos
Definition: struct_lp.h:164
int chgcolssize
Definition: struct_lp.h:302
int lpitiming
Definition: struct_lp.h:327
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:290
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:16613
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8470
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1590
SCIP_Real rootlpobjval
Definition: struct_lp.h:271
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:480
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1718
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:135
unsigned int coefchanged
Definition: struct_lp.h:246
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:140
SCIP_Longint nbarrierlps
Definition: struct_stat.h:178
SCIP_Bool flushed
Definition: struct_lp.h:344
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8269
SCIP_CLOCK * primallptime
Definition: struct_stat.h:144
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13257
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5882
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:105
int lpdepth
Definition: struct_lp.h:165
unsigned int inglobalcutpool
Definition: struct_lp.h:251
int nrows
Definition: struct_lp.h:313
#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:14706
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:152
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13493
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:170
public methods for message output
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4627
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:376
#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:6084
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5593
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:16292
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16674
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:16580
int ndivingrows
Definition: struct_lp.h:320
SCIP_Real lpobjval
Definition: struct_lp.h:260
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:4168
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:145
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:16859
int size
Definition: struct_lp.h:159
#define MIN(x, y)
Definition: memory.c:75
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7545
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6036
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:3240
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:5431
static SCIP_RETCODE lpSetUobjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real uobjlim)
Definition: lp.c:2603
#define SCIPsetDebugMsgPrint
Definition: set.h:1871
int lpirowssize
Definition: struct_lp.h:299
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4030
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2302
#define BMSallocMemory(ptr)
Definition: memory.h:78
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13729
#define SCIP_INVALID
Definition: def.h:165
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:86
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5528
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2236
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:16849
SCIP_CLOCK * duallptime
Definition: struct_stat.h:145
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:130
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17281
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6236
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:9928
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:2968
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2772
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3073
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:16591
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14235
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2909
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:5577
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:716
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:335
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5981
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:9596
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7623
int SCIPsetInitializeRandomSeed(SCIP_SET *set, int initialseedvalue)
Definition: set.c:6697
int nlazycols
Definition: struct_lp.h:309
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:16460
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:348
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6489
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4004
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6054
unsigned int nlocks
Definition: struct_lp.h:253
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2809
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2365
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17235
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:410
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6258
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3304
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3845
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:907
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:89
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9621
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13605
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:275
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:12790
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:396
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4133
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13469
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:3092
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:16684
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16138
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:5239
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
unsigned int validminmaxidx
Definition: struct_lp.h:243
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3821
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:13768
#define SCIP_ALLOC(x)
Definition: def.h:327
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12571
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6225
#define SCIPABORT()
Definition: def.h:288
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2834
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:193
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:331
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:2193
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:16249
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2467
unsigned int nonlpcolssorted
Definition: struct_lp.h:241
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16202
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16746
SCIP_Bool flushaddedcols
Definition: struct_lp.h:340
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:10266
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:16634
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:337
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7945
int ncols
Definition: struct_lp.h:307
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2559
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4064
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:16367
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:10092
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:16930
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:416
SCIP_Real objsqrnorm
Definition: struct_lp.h:279
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:3531
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16224
unsigned int local
Definition: struct_lp.h:248
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3021
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5097
SCIP_Bool probing
Definition: struct_lp.h:356
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:341
SCIP_Real looseobjval
Definition: struct_lp.h:261
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:237
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7533
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1801
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6047
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:11762
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9278
SCIP_Real flushedlhs
Definition: struct_lp.h:197
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:5470
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:5223
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:3395
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:3899
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:278
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3058
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:16570
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:726