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-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file lp.c
26  * @ingroup OTHER_CFILES
27  * @brief LP management methods and data structures
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Marc Pfetsch
31  * @author Kati Wolter
32  * @author Gerald Gamrath
33  *
34  * In LP management, we have to differ between the current LP and the SCIP_LP
35  * stored in the LP solver. All LP methods affect the current LP only.
36  * Before solving the current LP with the LP solver or setting an LP state,
37  * the LP solvers data has to be updated to the current LP with a call to
38  * lpFlush().
39  */
40 
41 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
42 
43 
44 #include "lpi/lpi.h"
45 #include "scip/clock.h"
46 #include "scip/cons.h"
47 #include "scip/event.h"
48 #include "scip/intervalarith.h"
49 #include "scip/lp.h"
50 #include "scip/misc.h"
51 #include "scip/prob.h"
52 #include "scip/pub_lp.h"
53 #include "scip/pub_message.h"
54 #include "scip/pub_misc.h"
55 #include "scip/pub_misc_sort.h"
56 #include "scip/pub_var.h"
57 #include "scip/set.h"
58 #include "scip/sol.h"
59 #include "scip/solve.h"
60 #include "scip/stat.h"
61 #include "scip/struct_event.h"
62 #include "scip/struct_lp.h"
63 #include "scip/struct_prob.h"
64 #include "scip/struct_set.h"
65 #include "scip/struct_stat.h"
66 #include "scip/struct_var.h"
67 #include "scip/var.h"
68 #include <string.h>
69 
70 
71 /* activate this to use the row activities as given by the LPI instead of recalculating
72  * using the LP solver activity is potentially faster, but may not be consistent with the SCIP_ROW calculations
73  * see also #2594 for more details on possible trouble
74  */
75 /* #define SCIP_USE_LPSOLVER_ACTIVITY */
76 
77 /*
78  * debug messages
79  */
80 
81 #ifdef SCIP_DEBUG
82 /** method is to print in row in case SCIP_DEBUG is defined */
83 static
84 void debugRowPrint(
85  SCIP_SET* set, /**< global SCIP settings */
86  SCIP_ROW* row /**< LP row */
87  )
88 {
89  int i;
90 
91  assert(row != NULL);
92 
93  /* print row name */
94  if( row->name != NULL && row->name[0] != '\0' )
95  {
96  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
97  }
98 
99  /* print left hand side */
100  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
101 
102  /* print coefficients */
103  if( row->len == 0 )
104  {
105  SCIPsetDebugMsgPrint(set, "0 ");
106  }
107  for( i = 0; i < row->len; ++i )
108  {
109  assert(row->cols[i] != NULL);
110  assert(row->cols[i]->var != NULL);
111  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
112  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
113  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
114  }
115 
116  /* print constant */
118  {
119  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
120  }
121 
122  /* print right hand side */
123  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
124 }
125 #else
126 #define debugRowPrint(x,y) /**/
127 #endif
128 
129 #ifdef SCIP_DEBUG
130 /** method to output column if SCIP_DEBUG is define */
131 static
132 void debugColPrint(
133  SCIP_SET* set, /**< global SCIP settings */
134  SCIP_COL* col /**< LP column */
135  )
136 {
137  int r;
138 
139  assert(col != NULL);
140  assert(col->var != NULL);
141 
142  /* print bounds */
143  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
144 
145  /* print coefficients */
146  if( col->len == 0 )
147  {
148  SCIPsetDebugMsgPrint(set, "<empty>");
149  }
150  for( r = 0; r < col->len; ++r )
151  {
152  assert(col->rows[r] != NULL);
153  assert(col->rows[r]->name != NULL);
154  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
155  }
156  SCIPsetDebugMsgPrint(set, "\n");
157 }
158 #else
159 #define debugColPrint(x,y) /**/
160 #endif
161 
162 /*
163  * memory growing methods for dynamically allocated arrays
164  */
165 
166 /** ensures, that chgcols array can store at least num entries */
167 static
169  SCIP_LP* lp, /**< current LP data */
170  SCIP_SET* set, /**< global SCIP settings */
171  int num /**< minimum number of entries to store */
172  )
173 {
174  assert(lp->nchgcols <= lp->chgcolssize);
175 
176  if( num > lp->chgcolssize )
177  {
178  int newsize;
179 
180  newsize = SCIPsetCalcMemGrowSize(set, num);
181  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
182  lp->chgcolssize = newsize;
183  }
184  assert(num <= lp->chgcolssize);
185 
186  return SCIP_OKAY;
187 }
188 
189 /** ensures, that chgrows array can store at least num entries */
190 static
192  SCIP_LP* lp, /**< current LP data */
193  SCIP_SET* set, /**< global SCIP settings */
194  int num /**< minimum number of entries to store */
195  )
196 {
197  assert(lp->nchgrows <= lp->chgrowssize);
198 
199  if( num > lp->chgrowssize )
200  {
201  int newsize;
202 
203  newsize = SCIPsetCalcMemGrowSize(set, num);
204  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
205  lp->chgrowssize = newsize;
206  }
207  assert(num <= lp->chgrowssize);
208 
209  return SCIP_OKAY;
210 }
211 
212 /** ensures, that lpicols array can store at least num entries */
213 static
215  SCIP_LP* lp, /**< current LP data */
216  SCIP_SET* set, /**< global SCIP settings */
217  int num /**< minimum number of entries to store */
218  )
219 {
220  assert(lp->nlpicols <= lp->lpicolssize);
221 
222  if( num > lp->lpicolssize )
223  {
224  int newsize;
225 
226  newsize = SCIPsetCalcMemGrowSize(set, num);
227  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
228  lp->lpicolssize = newsize;
229  }
230  assert(num <= lp->lpicolssize);
231 
232  return SCIP_OKAY;
233 }
234 
235 /** ensures, that lpirows array can store at least num entries */
236 static
238  SCIP_LP* lp, /**< current LP data */
239  SCIP_SET* set, /**< global SCIP settings */
240  int num /**< minimum number of entries to store */
241  )
242 {
243  assert(lp->nlpirows <= lp->lpirowssize);
244 
245  if( num > lp->lpirowssize )
246  {
247  int newsize;
248 
249  newsize = SCIPsetCalcMemGrowSize(set, num);
250  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
251  lp->lpirowssize = newsize;
252  }
253  assert(num <= lp->lpirowssize);
254 
255  return SCIP_OKAY;
256 }
257 
258 /** ensures, that cols array can store at least num entries */
259 static
261  SCIP_LP* lp, /**< current LP data */
262  SCIP_SET* set, /**< global SCIP settings */
263  int num /**< minimum number of entries to store */
264  )
265 {
266  assert(lp->ncols <= lp->colssize);
267 
268  if( num > lp->colssize )
269  {
270  int newsize;
271 
272  newsize = SCIPsetCalcMemGrowSize(set, num);
273  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
274  lp->colssize = newsize;
275  }
276  assert(num <= lp->colssize);
277 
278  return SCIP_OKAY;
279 }
280 
281 /** ensures, that soldirection array can store at least num entries */
282 static
284  SCIP_LP* lp, /**< current LP data */
285  int num /**< minimum number of entries to store */
286  )
287 {
288  if( num > lp->soldirectionsize )
289  {
292 
293  lp->soldirectionsize = num;
294  }
295 
296  assert(num <= lp->soldirectionsize);
297 
298  return SCIP_OKAY;
299 }
300 
301 /** ensures, that lazy cols array can store at least num entries */
302 static
304  SCIP_LP* lp, /**< current LP data */
305  SCIP_SET* set, /**< global SCIP settings */
306  int num /**< minimum number of entries to store */
307  )
308 {
309  assert(lp->nlazycols <= lp->lazycolssize);
310 
311  if( num > lp->lazycolssize )
312  {
313  int newsize;
314 
315  newsize = SCIPsetCalcMemGrowSize(set, num);
316  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
317  lp->lazycolssize = newsize;
318  }
319  assert(num <= lp->lazycolssize);
320 
321  return SCIP_OKAY;
322 }
323 
324 /** ensures, that rows array can store at least num entries */
325 static
327  SCIP_LP* lp, /**< current LP data */
328  SCIP_SET* set, /**< global SCIP settings */
329  int num /**< minimum number of entries to store */
330  )
331 {
332  assert(lp->nrows <= lp->rowssize);
333 
334  if( num > lp->rowssize )
335  {
336  int newsize;
337 
338  newsize = SCIPsetCalcMemGrowSize(set, num);
339  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
340  lp->rowssize = newsize;
341  }
342  assert(num <= lp->rowssize);
343 
344  return SCIP_OKAY;
345 }
346 
347 /** ensures, that row array of column can store at least num entries */
348 static
350  SCIP_COL* col, /**< LP column */
351  BMS_BLKMEM* blkmem, /**< block memory */
352  SCIP_SET* set, /**< global SCIP settings */
353  int num /**< minimum number of entries to store */
354  )
355 {
356  assert(col != NULL);
357  assert(col->len <= col->size);
358 
359  if( num > col->size )
360  {
361  int newsize;
362 
363  newsize = SCIPsetCalcMemGrowSize(set, num);
364  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
365  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
366  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
367  col->size = newsize;
368  }
369  assert(num <= col->size);
370 
371  return SCIP_OKAY;
372 }
373 
374 /** save current LP values dependent on the solution */
375 static
377  SCIP_LP* lp, /**< LP data */
378  SCIP_STAT* stat, /**< problem statistics */
379  BMS_BLKMEM* blkmem /**< block memory */
380  )
381 {
382  SCIP_LPSOLVALS* storedsolvals;
383 
384  assert(lp != NULL);
385  assert(stat != NULL);
386  assert(blkmem != NULL);
387 
388  /* allocate memory for storage */
389  if( lp->storedsolvals == NULL )
390  {
392  }
393  storedsolvals = lp->storedsolvals;
394 
395  /* store values */
396  storedsolvals->lpsolstat = lp->lpsolstat;
397  storedsolvals->lpobjval = lp->lpobjval;
398  storedsolvals->primalfeasible = lp->primalfeasible;
399  storedsolvals->primalchecked = lp->primalchecked;
400  storedsolvals->dualfeasible = lp->dualfeasible;
401  storedsolvals->dualchecked = lp->dualchecked;
402  storedsolvals->solisbasic = lp->solisbasic;
403  storedsolvals->lpissolved = lp->solved;
404 
405  return SCIP_OKAY;
406 }
407 
408 /** restore LP solution values in column */
409 static
411  SCIP_LP* lp, /**< LP data */
412  BMS_BLKMEM* blkmem, /**< block memory */
413  SCIP_Longint validlp /**< number of lp for which restored values are valid */
414  )
415 {
416  SCIP_LPSOLVALS* storedsolvals;
417 
418  assert(lp != NULL);
419  assert(blkmem != NULL);
420 
421  /* if stored values are available, restore them */
422  storedsolvals = lp->storedsolvals;
423  if( storedsolvals != NULL )
424  {
425  lp->solved = storedsolvals->lpissolved;
426  lp->validsollp = validlp;
427 
428  lp->lpsolstat = storedsolvals->lpsolstat;
429  lp->lpobjval = storedsolvals->lpobjval;
430  lp->primalfeasible = storedsolvals->primalfeasible;
431  lp->primalchecked = storedsolvals->primalchecked;
432  lp->dualfeasible = storedsolvals->dualfeasible;
433  lp->dualchecked = storedsolvals->dualchecked;
434  lp->solisbasic = storedsolvals->solisbasic;
435 
436  /* solution values are stored only for LPs solved to optimality or unboundedness */
437  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
443  lp->validsollp == -1);
444  }
445  /* no values available, mark LP as unsolved */
446  else
447  {
448  lp->solved = FALSE;
449  lp->validsollp = -1;
450 
452  lp->lpobjval = SCIP_INVALID;
453  lp->primalfeasible = FALSE;
454  lp->primalchecked = FALSE;
455  lp->dualfeasible = FALSE;
456  lp->dualchecked = FALSE;
457  lp->solisbasic = FALSE;
458  lp->validfarkaslp = -1;
459  }
460 
461  lp->validdegeneracylp = -1;
462 
463  /* intentionally keep storage space allocated */
464 
465  return SCIP_OKAY;
466 }
467 
468 /** save current LP solution values stored in each column */
469 static
471  SCIP_COL* col, /**< LP column */
472  BMS_BLKMEM* blkmem /**< block memory */
473  )
474 {
475  SCIP_COLSOLVALS* storedsolvals;
476 
477  assert(col != NULL);
478  assert(blkmem != NULL);
479 
480  /* allocate memory for storage */
481  if( col->storedsolvals == NULL )
482  {
483  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
484  }
485  storedsolvals = col->storedsolvals;
486 
487  /* store values */
488  storedsolvals->primsol = col->primsol;
489  storedsolvals->redcost = col->redcost;
490  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
491 
492  return SCIP_OKAY;
493 }
494 
495 /** restore LP solution values in column */
496 static
498  SCIP_COL* col, /**< LP column */
499  BMS_BLKMEM* blkmem, /**< block memory */
500  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
501  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
502  )
503 {
504  SCIP_COLSOLVALS* storedsolvals;
505 
506  assert(col != NULL);
507  assert(blkmem != NULL);
508 
509  /* if stored values are available, restore them */
510  storedsolvals = col->storedsolvals;
511  if( storedsolvals != NULL )
512  {
513  col->primsol = storedsolvals->primsol;
514  col->redcost = storedsolvals->redcost;
515  col->validredcostlp = validlp;
516  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
517 
518  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
519  col->validfarkaslp = -1;
520  }
521  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
522  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
523  */
524  else
525  {
526  col->primsol = 0.0;
527  col->validredcostlp = -1;
528  col->validfarkaslp = -1;
529  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
530  }
531 
532  /* free memory */
533  if( freebuffer )
534  {
535  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
536  assert(col->storedsolvals == NULL);
537  }
538 
539  return SCIP_OKAY;
540 }
541 
542 /** save current LP solution values stored in each column */
543 static
545  SCIP_ROW* row, /**< LP row */
546  BMS_BLKMEM* blkmem, /**< block memory */
547  SCIP_Bool infeasible /**< is the solution infeasible? */
548  )
549 {
550  SCIP_ROWSOLVALS* storedsolvals;
551 
552  assert(row != NULL);
553  assert(blkmem != NULL);
554 
555  /* allocate memory for storage */
556  if( row->storedsolvals == NULL )
557  {
558  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
559  }
560  storedsolvals = row->storedsolvals;
561 
562  /* store values */
563  if ( infeasible )
564  {
565  storedsolvals->dualsol = row->dualfarkas;
566  storedsolvals->activity = SCIP_INVALID;
567  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
568  }
569  else
570  {
571  storedsolvals->dualsol = row->dualsol;
572  storedsolvals->activity = row->activity;
573  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
574  }
575 
576  return SCIP_OKAY;
577 }
578 
579 /** restore LP solution values in row */
580 static
582  SCIP_ROW* row, /**< LP column */
583  BMS_BLKMEM* blkmem, /**< block memory */
584  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
585  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
586  SCIP_Bool infeasible /**< is the solution infeasible? */
587  )
588 {
589  SCIP_ROWSOLVALS* storedsolvals;
590 
591  assert(row != NULL);
592  assert(blkmem != NULL);
593 
594  /* if stored values are available, restore them */
595  storedsolvals = row->storedsolvals;
596  if( storedsolvals != NULL )
597  {
598  if ( infeasible )
599  row->dualfarkas = storedsolvals->dualsol;
600  else
601  row->dualsol = storedsolvals->dualsol;
602  row->activity = storedsolvals->activity;
603  row->validactivitylp = validlp;
604  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
605  }
606  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
607  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
608  */
609  else
610  {
611  row->dualsol = 0.0;
612  row->dualfarkas = 0.0;
613  row->activity = SCIP_INVALID;
614  row->validactivitylp = -1;
615  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
616  }
617 
618  /* free memory */
619  if( freebuffer )
620  {
621  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
622  assert(row->storedsolvals == NULL);
623  }
624 
625  return SCIP_OKAY;
626 }
627 
628 /** ensures, that column array of row can store at least num entries */
630  SCIP_ROW* row, /**< LP row */
631  BMS_BLKMEM* blkmem, /**< block memory */
632  SCIP_SET* set, /**< global SCIP settings */
633  int num /**< minimum number of entries to store */
634  )
635 {
636  assert(row != NULL);
637  assert(row->len <= row->size);
638 
639  if( num > row->size )
640  {
641  int newsize;
642 
643  newsize = SCIPsetCalcMemGrowSize(set, num);
644  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
645  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
646  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
647  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
648  row->size = newsize;
649  }
650  assert(num <= row->size);
651 
652  return SCIP_OKAY;
653 }
654 
655 
656 #ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
657 static SCIP_Bool msgdisp_checkrow = FALSE;
658 
659 static
660 void checkRow(
661  SCIP_ROW* row
662  )
663 {
664  int i;
665 
666  if( !msgdisp_checkrow )
667  {
668  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
669  msgdisp_checkrow = TRUE;
670  }
671 
672  /* validate sorting of LP part of row */
673  if( row->lpcolssorted && row->nlpcols > 0)
674  {
675  assert(row->cols_index[0] == row->cols[0]->index);
676  for( i = 1; i < row->nlpcols; ++i )
677  {
678  assert(row->cols_index[i] == row->cols[i]->index);
679  assert(row->cols_index[i] >= row->cols_index[i-1]);
680  }
681  }
682 
683  /* validate sorting of non-LP part of row */
684  if( row->nonlpcolssorted && row->len > row->nlpcols )
685  {
686  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
687  for( i = row->nlpcols + 1; i < row->len; ++i )
688  {
689  assert(row->cols_index[i] == row->cols[i]->index);
690  assert(row->cols_index[i] >= row->cols_index[i-1]);
691  }
692  }
693 }
694 #else
695 #define checkRow(row) /**/
696 #endif
697 
698 #ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
699 static
700 void checkRowSqrnorm(
701  SCIP_ROW* row
702  )
703 {
704  SCIP_COL** cols;
705  SCIP_Real sqrnorm;
706  int c;
707 
708  cols = row->cols;
709  assert(cols != NULL || row->len == 0);
710 
711  sqrnorm = 0.0;
712 
713  for( c = row->len - 1; c >= 0; --c )
714  {
715  if( cols[c]->lppos >= 0 )
716  sqrnorm += SQR(row->vals[c]);
717  }
718 
719  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
720 }
721 
722 static
723 void checkRowSumnorm(
724  SCIP_ROW* row
725  )
726 {
727  SCIP_COL** cols;
728  SCIP_Real sumnorm;
729  int c;
730 
731  cols = row->cols;
732  assert(cols != NULL || row->len == 0);
733 
734  sumnorm = 0.0;
735 
736  for( c = row->len - 1; c >= 0; --c )
737  {
738  if( cols[c]->lppos >= 0 )
739  sumnorm += REALABS(row->vals[c]);
740  }
741 
742  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
743 }
744 
745 static
746 void checkRowObjprod(
747  SCIP_ROW* row
748  )
749 {
750  SCIP_COL** cols;
751  SCIP_Real objprod;
752  int c;
753 
754  cols = row->cols;
755  assert(cols != NULL || row->len == 0);
756 
757  objprod = 0.0;
758 
759  for( c = row->len - 1; c >= 0; --c )
760  {
761  if( cols[c]->lppos >= 0 )
762  objprod += row->vals[c] * cols[c]->unchangedobj;
763  }
764 
765  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
766 }
767 #else
768 #define checkRowSqrnorm(row) /**/
769 #define checkRowSumnorm(row) /**/
770 #define checkRowObjprod(row) /**/
771 #endif
772 
773 /*
774  * Local methods for pseudo and loose objective values
775  */
776 
777 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
778 static
780  SCIP_LP* lp, /**< current LP data */
781  SCIP_SET* set, /**< global SCIP settings */
782  SCIP_PROB* prob /**< problem data */
783  )
784 {
785  SCIP_VAR** vars;
786  SCIP_Real obj;
787  int nvars;
788  int v;
789 
790  assert(lp != NULL);
791  assert(set != NULL);
792  assert(prob != NULL);
793  assert(!lp->looseobjvalid);
794 
795  vars = prob->vars;
796  nvars = prob->nvars;
797  lp->looseobjval = 0.0;
798 
799  /* iterate over all variables in the problem */
800  for( v = 0; v < nvars; ++v )
801  {
802  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
803  {
804  obj = SCIPvarGetObj(vars[v]);
805 
806  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
807  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
808  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
809  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
810  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
811  }
812  }
813 
814  /* the recomputed value is reliable */
815  lp->rellooseobjval = lp->looseobjval;
816  lp->looseobjvalid = TRUE;
817 }
818 
819 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
820 static
822  SCIP_LP* lp, /**< current LP data */
823  SCIP_SET* set, /**< global SCIP settings */
824  SCIP_PROB* prob /**< problem data */
825  )
826 {
827  SCIP_VAR** vars;
828  int nvars;
829  int v;
830 
831  assert(lp != NULL);
832  assert(set != NULL);
833  assert(prob != NULL);
834  assert(!lp->pseudoobjvalid);
835 
836  vars = prob->vars;
837  nvars = prob->nvars;
838  lp->pseudoobjval = 0.0;
839 
840  /* iterate over all variables in the problem */
841  for( v = 0; v < nvars; ++v )
842  {
843  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
844  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
845  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
846  {
847  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
848  }
849  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
850  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
851  {
852  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
853  }
854  }
855 
856  /* the recomputed value is reliable */
857  lp->relpseudoobjval = lp->pseudoobjval;
858  lp->pseudoobjvalid = TRUE;
859 }
860 
861 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
862 static
864  SCIP_LP* lp, /**< current LP data */
865  SCIP_SET* set, /**< global SCIP settings */
866  SCIP_PROB* prob /**< problem data */
867  )
868 {
869  SCIP_VAR** vars;
870  int nvars;
871  int v;
872 
873  assert(lp != NULL);
874  assert(set != NULL);
875  assert(prob != NULL);
876  assert(!lp->glbpseudoobjvalid);
877 
878  vars = prob->vars;
879  nvars = prob->nvars;
880  lp->glbpseudoobjval = 0.0;
881 
882  /* iterate over all variables in the problem */
883  for( v = 0; v < nvars; ++v )
884  {
885  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
886  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
887  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
888  {
889  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
890  }
891  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
892  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
893  {
894  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
895  }
896  }
897 
898  /* the recomputed value is reliable */
900  lp->glbpseudoobjvalid = TRUE;
901 }
902 
903 /** gets finite part of objective value of current LP that results from LOOSE variables only */
904 static
906  SCIP_LP* lp, /**< current LP data */
907  SCIP_SET* set, /**< global SCIP settings */
908  SCIP_PROB* prob /**< problem data */
909  )
910 {
911  assert(lp != NULL);
912  assert(set != NULL);
913  assert(prob != NULL);
914  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
915  assert(lp->flushed);
916  assert(lp->looseobjvalinf == 0);
917 
918  /* recalculate the loose objective value, if needed */
919  if( !lp->looseobjvalid )
920  recomputeLooseObjectiveValue(lp, set, prob);
921 
922  return lp->looseobjval;
923 }
924 
925 /** gets finite part of pseudo objective value of current LP */
926 static
928  SCIP_LP* lp, /**< current LP data */
929  SCIP_SET* set, /**< global SCIP settings */
930  SCIP_PROB* prob /**< problem data */
931  )
932 {
933  assert(lp != NULL);
934  assert(set != NULL);
935  assert(prob != NULL);
936 
937  /* recalculate the pseudo objective value, if needed */
938  if( !lp->pseudoobjvalid )
939  recomputePseudoObjectiveValue(lp, set, prob);
940 
941  return lp->pseudoobjval;
942 }
943 
944 /*
945  * Sorting and searching rows and columns
946  */
947 
948 
949 /** comparison method for sorting rows by non-decreasing index */
951 {
952  assert(elem1 != NULL);
953  assert(elem2 != NULL);
954 
955  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
956  return -1;
957  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
958  return +1;
959  else
960  {
961  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
962  return 0;
963  }
964 }
965 
966 
967 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
968 static
970  SCIP_COL* col /**< column to be sorted */
971  )
972 {
973  int i;
974 
975  assert(col != NULL);
976 
977  /* check, if column is already sorted in the LP part */
978  if( col->lprowssorted )
979  return;
980 
981  /* sort coefficients */
982  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
983 
984  /* update links */
985  for( i = 0; i < col->nlprows; ++i )
986  {
987  if( col->linkpos[i] >= 0 )
988  {
989  assert(col->rows[i]->cols[col->linkpos[i]] == col);
990  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
991  col->rows[i]->linkpos[col->linkpos[i]] = i;
992  }
993  }
994 
995  col->lprowssorted = TRUE;
996 }
997 
998 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
999  * ones
1000  */
1001 static
1003  SCIP_COL* col /**< column to be sorted */
1004  )
1005 {
1006  int i;
1007 
1008  assert(col != NULL);
1009 
1010  /* check, if column is already sorted in the non-LP part */
1011  if( col->nonlprowssorted )
1012  return;
1013 
1014  /* sort coefficients */
1015  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
1016 
1017  /* update links */
1018  for( i = col->nlprows; i < col->len; ++i )
1019  {
1020  if( col->linkpos[i] >= 0 )
1021  {
1022  assert(col->rows[i]->cols[col->linkpos[i]] == col);
1023  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1024  col->rows[i]->linkpos[col->linkpos[i]] = i;
1025  }
1026  }
1027 
1028  col->nonlprowssorted = TRUE;
1029 }
1030 
1031 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1032 static
1034  SCIP_ROW* row /**< row to be sorted */
1035  )
1036 {
1037  int i;
1038 
1039  assert(row != NULL);
1040 
1041  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1042  if( row->lpcolssorted || row->delaysort )
1043  return;
1044 
1045  /* sort coefficients */
1046  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1047 
1048  /* update links */
1049  for( i = 0; i < row->nlpcols; ++i )
1050  {
1051  if( row->linkpos[i] >= 0 )
1052  {
1053  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1054  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1055  row->cols[i]->linkpos[row->linkpos[i]] = i;
1056  }
1057  }
1058 
1059  row->lpcolssorted = TRUE;
1060 }
1061 
1062 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1063  * higher ones
1064  */
1065 static
1067  SCIP_ROW* row /**< row to be sorted */
1068  )
1069 {
1070  int i;
1071 
1072  assert(row != NULL);
1073 
1074  checkRow(row);
1075 
1076  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1077  if( row->nonlpcolssorted || row->delaysort )
1078  return;
1079 
1080  /* sort coefficients */
1081  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1082 
1083  /* update links */
1084  for( i = row->nlpcols; i < row->len; ++i )
1085  {
1086  if( row->linkpos[i] >= 0 )
1087  {
1088  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1089  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1090  row->cols[i]->linkpos[row->linkpos[i]] = i;
1091  }
1092  }
1093 
1094  checkRow(row);
1095 
1096  row->nonlpcolssorted = TRUE;
1097 }
1098 
1099 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1100 static
1102  SCIP_COL* col, /**< column to be searched in */
1103  const SCIP_ROW* row, /**< coefficient to be searched for */
1104  int minpos, /**< first position of search range */
1105  int maxpos /**< last position of search range */
1106  )
1107 {
1108  int pos;
1109  int idx;
1110  int searchidx;
1111 
1112  assert(col != NULL);
1113  assert(row != NULL);
1114 
1115  /* binary search */
1116  searchidx = row->index;
1117  while(minpos <= maxpos)
1118  {
1119  pos = (minpos + maxpos)/2;
1120  assert(0 <= pos && pos < col->len);
1121  assert(col->rows[pos] != NULL);
1122  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1123  idx = col->rows[pos]->index;
1124  if( searchidx == idx )
1125  return pos;
1126  else if( searchidx < idx )
1127  maxpos = pos-1;
1128  else
1129  minpos = pos+1;
1130  }
1131 
1132  return -1;
1133 }
1134 
1135 /** searches coefficient in column, returns position in col vector or -1 if not found */
1136 static
1138  SCIP_COL* col, /**< column to be searched in */
1139  const SCIP_ROW* row /**< coefficient to be searched for */
1140  )
1141 {
1142  int pos;
1143 
1144  assert(col != NULL);
1145  assert(row != NULL);
1146 
1147  pos = -1;
1148 
1149  /* search in the linked LP rows */
1150  if( row->lppos >= 0 )
1151  {
1152  /* column has to be sorted, such that binary search works */
1153  colSortLP(col);
1154  assert(col->lprowssorted);
1155 
1156  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1157  if( pos >= 0 )
1158  return pos;
1159  }
1160 
1161  /* search in the non-LP/unlinked rows */
1162  if( row->lppos == -1 || col->nunlinked > 0 )
1163  {
1164  /* column has to be sorted, such that binary search works */
1165  colSortNonLP(col);
1166  assert(col->nonlprowssorted);
1167 
1168  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1169  }
1170 
1171  return pos;
1172 }
1173 
1174 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1175 static
1177  SCIP_ROW* row, /**< row to be searched in */
1178  const SCIP_COL* col, /**< coefficient to be searched for */
1179  int minpos, /**< first position of search range */
1180  int maxpos /**< last position of search range */
1181  )
1182 {
1183  int pos;
1184  int idx;
1185  int searchidx;
1186 
1187  assert(row != NULL);
1188  assert(col != NULL);
1189 
1190  /* binary search */
1191  searchidx = col->index;
1192  while(minpos <= maxpos)
1193  {
1194  pos = (minpos + maxpos)/2;
1195  assert(0 <= pos && pos < row->len);
1196  assert(row->cols[pos] != NULL);
1197  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1198  assert(row->cols_index[pos] == row->cols[pos]->index);
1199  idx = row->cols_index[pos];
1200  if( searchidx == idx )
1201  return pos;
1202  else if( searchidx < idx )
1203  maxpos = pos-1;
1204  else
1205  minpos = pos+1;
1206  }
1207 
1208  return -1;
1209 }
1210 
1211 /** searches coefficient in row, returns position in row vector or -1 if not found;
1212  * if the sorting of the row is delayed, returns -1
1213  */
1214 static
1216  SCIP_ROW* row, /**< row to be searched in */
1217  const SCIP_COL* col /**< coefficient to be searched for */
1218  )
1219 {
1220  int pos;
1221 
1222  assert(row != NULL);
1223  assert(col != NULL);
1224 
1225  if( row->delaysort )
1226  return -1;
1227 
1228  pos = -1;
1229 
1230  /* search in the linked LP columns */
1231  if( col->lppos >= 0 )
1232  {
1233  /* row has to be sorted, such that binary search works */
1234  rowSortLP(row);
1235  assert(row->lpcolssorted);
1236 
1237  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1238  }
1239 
1240  /* search in the non-LP/unlinked columns */
1241  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1242  {
1243  /* row has to be sorted, such that binary search works */
1244  rowSortNonLP(row);
1245  assert(row->nonlpcolssorted);
1246 
1247  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1248  }
1249 
1250 #ifndef NDEBUG
1251  /* validate result */
1252  assert(-1 <= pos && pos < row->len);
1253  if( pos >= 0 )
1254  assert(row->cols[pos] == col);
1255  else
1256  {
1257  int i;
1258  for( i = 0; i < row->len; ++i )
1259  assert(row->cols[i] != col);
1260  }
1261 #endif
1262 
1263  return pos;
1264 }
1265 
1266 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1267 static
1269  SCIP_COL* col, /**< LP column */
1270  int oldpos, /**< old position of coefficient */
1271  int newpos /**< new position of coefficient */
1272  )
1273 {
1274  assert(col != NULL);
1275  assert(0 <= oldpos && oldpos < col->len);
1276  assert(0 <= newpos && newpos < col->len);
1277  assert(col->rows[oldpos] != NULL);
1278 
1279  if( oldpos == newpos )
1280  return;
1281 
1282  col->rows[newpos] = col->rows[oldpos];
1283  col->vals[newpos] = col->vals[oldpos];
1284  col->linkpos[newpos] = col->linkpos[oldpos];
1285 
1286  /* update link position in row */
1287  if( col->linkpos[newpos] >= 0 )
1288  {
1289  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1290  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1291 
1292  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1293  }
1294 
1295  /* update sorted flags */
1296  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1297  col->lprowssorted = FALSE;
1298  else
1299  col->nonlprowssorted = FALSE;
1300 }
1301 
1302 /** swaps two coefficients in a column, and updates all corresponding data structures */
1303 static
1305  SCIP_COL* col, /**< LP column */
1306  int pos1, /**< position of first coefficient */
1307  int pos2 /**< position of second coefficient */
1308  )
1309 {
1310  SCIP_ROW* tmprow;
1311  SCIP_Real tmpval;
1312  int tmplinkpos;
1313 
1314  assert(col != NULL);
1315  assert(0 <= pos1 && pos1 < col->len);
1316  assert(0 <= pos2 && pos2 < col->len);
1317  assert(col->rows[pos1] != NULL);
1318 
1319  if( pos1 == pos2 )
1320  return;
1321 
1322  /* swap coefficients */
1323  tmprow = col->rows[pos2];
1324  tmpval = col->vals[pos2];
1325  tmplinkpos = col->linkpos[pos2];
1326 
1327  col->rows[pos2] = col->rows[pos1];
1328  col->vals[pos2] = col->vals[pos1];
1329  col->linkpos[pos2] = col->linkpos[pos1];
1330 
1331  col->rows[pos1] = tmprow;
1332  col->vals[pos1] = tmpval;
1333  col->linkpos[pos1] = tmplinkpos;
1334 
1335  /* update link position in rows */
1336  if( col->linkpos[pos1] >= 0 )
1337  {
1338  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1339  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1340 
1341  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1342  }
1343  if( col->linkpos[pos2] >= 0 )
1344  {
1345  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1346  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1347 
1348  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1349  }
1350 
1351  /* update sorted flags */
1352  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1353  col->lprowssorted = FALSE;
1354  else
1355  col->nonlprowssorted = FALSE;
1356  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1357  col->lprowssorted = FALSE;
1358  else
1359  col->nonlprowssorted = FALSE;
1360 }
1361 
1362 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1363 static
1365  SCIP_ROW* row, /**< LP row */
1366  int oldpos, /**< old position of coefficient */
1367  int newpos /**< new position of coefficient */
1368  )
1369 {
1370  assert(row != NULL);
1371  assert(0 <= oldpos && oldpos < row->len);
1372  assert(0 <= newpos && newpos < row->len);
1373  assert(row->cols[oldpos] != NULL);
1374 
1375  if( oldpos == newpos )
1376  return;
1377 
1378  row->cols[newpos] = row->cols[oldpos];
1379  row->cols_index[newpos] = row->cols_index[oldpos];
1380  row->vals[newpos] = row->vals[oldpos];
1381  row->linkpos[newpos] = row->linkpos[oldpos];
1382 
1383  /* update link position in column */
1384  if( row->linkpos[newpos] >= 0 )
1385  {
1386  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1387  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1388 
1389  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1390  }
1391 
1392  /* update sorted flags */
1393  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1394  row->lpcolssorted = FALSE;
1395  else
1396  row->nonlpcolssorted = FALSE;
1397 }
1398 
1399 /** swaps two coefficients in a row, and updates all corresponding data structures */
1400 static
1402  SCIP_ROW* row, /**< LP row */
1403  int pos1, /**< position of first coefficient */
1404  int pos2 /**< position of second coefficient */
1405  )
1406 {
1407  SCIP_COL* tmpcol;
1408  SCIP_Real tmpval;
1409  int tmpindex;
1410  int tmplinkpos;
1411 
1412  assert(row != NULL);
1413  assert(0 <= pos1 && pos1 < row->len);
1414  assert(0 <= pos2 && pos2 < row->len);
1415  assert(row->cols[pos1] != NULL);
1416  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1417 
1418  if( pos1 == pos2 )
1419  return;
1420 
1421  /* swap coefficients */
1422  tmpcol = row->cols[pos2];
1423  tmpindex = row->cols_index[pos2];
1424  tmpval = row->vals[pos2];
1425  tmplinkpos = row->linkpos[pos2];
1426 
1427  row->cols[pos2] = row->cols[pos1];
1428  row->cols_index[pos2] = row->cols_index[pos1];
1429  row->vals[pos2] = row->vals[pos1];
1430  row->linkpos[pos2] = row->linkpos[pos1];
1431 
1432  row->cols[pos1] = tmpcol;
1433  row->cols_index[pos1] = tmpindex;
1434  row->vals[pos1] = tmpval;
1435  row->linkpos[pos1] = tmplinkpos;
1436 
1437  /* update link position in columns */
1438  if( row->linkpos[pos1] >= 0 )
1439  {
1440  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1441  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1442 
1443  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1444  }
1445  if( row->linkpos[pos2] >= 0 )
1446  {
1447  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1448  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1449 
1450  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1451  }
1452 
1453  /* update sorted flags */
1454  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1455  row->lpcolssorted = FALSE;
1456  else
1457  row->nonlpcolssorted = FALSE;
1458  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1459  row->lpcolssorted = FALSE;
1460  else
1461  row->nonlpcolssorted = FALSE;
1462 }
1463 
1464 /** issues a ROWCOEFCHANGED event on the given row */
1465 static
1467  SCIP_ROW* row, /**< row which coefficient has changed */
1468  BMS_BLKMEM* blkmem, /**< block memory */
1469  SCIP_SET* set, /**< global SCIP settings */
1470  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1471  SCIP_COL* col, /**< the column which coefficient has changed */
1472  SCIP_Real oldval, /**< old value of the coefficient */
1473  SCIP_Real newval /**< new value of the coefficient */
1474  )
1475 {
1476  assert(row != NULL);
1477  assert(row->eventfilter != NULL);
1478  assert(col != NULL);
1479 
1480  /* check, if the row is being tracked for coefficient changes
1481  * if so, issue ROWCOEFCHANGED event
1482  */
1483  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1484  {
1485  SCIP_EVENT* event;
1486 
1487  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1488  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1489  }
1490 
1491  return SCIP_OKAY;
1492 }
1493 
1494 /** issues a ROWCONSTCHANGED event on the given row */
1495 static
1497  SCIP_ROW* row, /**< row which coefficient has changed */
1498  BMS_BLKMEM* blkmem, /**< block memory */
1499  SCIP_SET* set, /**< global SCIP settings */
1500  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1501  SCIP_Real oldval, /**< old value of the constant */
1502  SCIP_Real newval /**< new value of the constant */
1503  )
1504 {
1505  assert(row != NULL);
1506  assert(row->eventfilter != NULL);
1507 
1508  /* check, if the row is being tracked for coefficient changes
1509  * if so, issue ROWCONSTCHANGED event
1510  */
1511  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED)) )
1512  {
1513  SCIP_EVENT* event;
1514 
1515  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1516  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1517  }
1518 
1519  return SCIP_OKAY;
1520 }
1521 
1522 /** issues a ROWSIDECHANGED event on the given row */
1523 static
1525  SCIP_ROW* row, /**< row which coefficient has changed */
1526  BMS_BLKMEM* blkmem, /**< block memory */
1527  SCIP_SET* set, /**< global SCIP settings */
1528  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1529  SCIP_SIDETYPE side, /**< the side that has changed */
1530  SCIP_Real oldval, /**< old value of side */
1531  SCIP_Real newval /**< new value of side */
1532  )
1533 {
1534  assert(row != NULL);
1535  assert(row->eventfilter != NULL);
1536 
1537  /* check, if the row is being tracked for coefficient changes
1538  * if so, issue ROWSIDECHANGED event
1539  */
1540  if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
1541  {
1542  SCIP_EVENT* event;
1543 
1544  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1545  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1546  }
1547 
1548  return SCIP_OKAY;
1549 }
1550 
1551 #ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1552 
1553 #ifdef NDEBUG
1554 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1555 #else
1556 #define ASSERT(x) assert(x)
1557 #endif
1558 
1559 static SCIP_Bool msgdisp_checklinks = FALSE;
1560 
1561 
1562 static
1563 void checkLinks(
1564  SCIP_LP* lp /**< current LP data */
1565  )
1566 {
1567  SCIP_COL* col;
1568  SCIP_ROW* row;
1569  int i;
1570  int j;
1571 
1572  ASSERT(lp != NULL);
1573 
1574  if( !msgdisp_checklinks )
1575  {
1576  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1577  msgdisp_checklinks = TRUE;
1578  }
1579 
1580  for( i = 0; i < lp->ncols; ++i )
1581  {
1582  col = lp->cols[i];
1583  ASSERT(col != NULL);
1584  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1585  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1586  ASSERT(col->nlprows <= col->len);
1587  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1588 
1589  for( j = 0; j < col->len; ++j )
1590  {
1591  row = col->rows[j];
1592  ASSERT(row != NULL);
1593  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1594  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1595  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1596  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1597  }
1598  }
1599 
1600  for( i = 0; i < lp->nrows; ++i )
1601  {
1602  row = lp->rows[i];
1603  ASSERT(row != NULL);
1604  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1605  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1606  ASSERT(row->nlpcols <= row->len);
1607  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1608 
1609  for( j = 0; j < row->len; ++j )
1610  {
1611  col = row->cols[j];
1612  ASSERT(col != NULL);
1613  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1614  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1615  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1616  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1617  }
1618  }
1619 }
1620 
1621 #undef ASSERT
1622 
1623 #else
1624 #define checkLinks(lp) /**/
1625 #endif
1626 
1627 /*
1628  * Changing announcements
1629  */
1630 
1631 /** announces, that the given coefficient in the constraint matrix changed */
1632 static
1634  SCIP_ROW* row, /**< LP row */
1635  SCIP_COL* col, /**< LP col */
1636  SCIP_LP* lp /**< current LP data */
1637  )
1638 {
1639  assert(row != NULL);
1640  assert(col != NULL);
1641  assert(lp != NULL);
1642 
1643  if( row->lpipos >= 0 && col->lpipos >= 0 )
1644  {
1645  assert(row->lpipos < lp->nlpirows);
1646  assert(col->lpipos < lp->nlpicols);
1647 
1648  /* we have to remember the change only in the row or in the column,
1649  * because the readdition of one vector would change the other automatically.
1650  */
1651  if( row->lpipos >= lp->lpifirstchgrow )
1652  row->coefchanged = TRUE;
1653  else if( col->lpipos >= lp->lpifirstchgcol )
1654  col->coefchanged = TRUE;
1655  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1656  {
1657  row->coefchanged = TRUE;
1658  lp->lpifirstchgrow = row->lpipos;
1659  }
1660  else
1661  {
1662  col->coefchanged = TRUE;
1663  lp->lpifirstchgcol = col->lpipos;
1664  }
1665 
1666  /* mark the current LP unflushed */
1667  lp->flushed = FALSE;
1668  }
1669 
1671  row->minactivity = SCIP_INVALID;
1672  row->maxactivity = SCIP_INVALID;
1673  row->validpsactivitydomchg = -1;
1674  row->validactivitybdsdomchg = -1;
1675 }
1676 
1677 
1678 
1679 /*
1680  * local column changing methods
1681  */
1682 
1683 /* forward declaration for colAddCoef() */
1684 static
1686  SCIP_ROW* row, /**< LP row */
1687  BMS_BLKMEM* blkmem, /**< block memory */
1688  SCIP_SET* set, /**< global SCIP settings */
1689  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1690  SCIP_LP* lp, /**< current LP data */
1691  SCIP_COL* col, /**< LP column */
1692  SCIP_Real val, /**< value of coefficient */
1693  int linkpos /**< position of row in the column's row array, or -1 */
1694  );
1695 
1696 /** adds a previously non existing coefficient to an LP column */
1697 static
1699  SCIP_COL* col, /**< LP column */
1700  BMS_BLKMEM* blkmem, /**< block memory */
1701  SCIP_SET* set, /**< global SCIP settings */
1702  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1703  SCIP_LP* lp, /**< current LP data */
1704  SCIP_ROW* row, /**< LP row */
1705  SCIP_Real val, /**< value of coefficient */
1706  int linkpos /**< position of column in the row's col array, or -1 */
1707  )
1708 {
1709  int pos;
1710 
1711  assert(blkmem != NULL);
1712  assert(col != NULL);
1713  assert(col->nlprows <= col->len);
1714  assert(col->var != NULL);
1715  assert(row != NULL);
1716  assert(!SCIPsetIsZero(set, val));
1717  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1718 
1719  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1720  assert(col->rows != NULL);
1721  assert(col->vals != NULL);
1722  assert(col->linkpos != NULL);
1723 
1724  pos = col->len;
1725  col->len++;
1726 
1727  /* 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
1728  * part of the column's arrays
1729  */
1730  if( row->lppos >= 0 && linkpos >= 0 )
1731  {
1732  /* move the first non-LP/not linked row to the end */
1733  if( col->nlprows < pos )
1734  {
1735  colMoveCoef(col, col->nlprows, pos);
1736  pos = col->nlprows;
1737  }
1738  col->nlprows++;
1739  }
1740 
1741  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1742  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1743 
1744  /* insert the row at the correct position and update the links */
1745  col->rows[pos] = row;
1746  col->vals[pos] = val;
1747  col->linkpos[pos] = linkpos;
1748  if( linkpos == -1 )
1749  {
1750  col->nunlinked++;
1751 
1752  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1753  * of the row is not complete
1754  */
1755  if( col->lppos >= 0 )
1756  {
1757  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1758  * has to be updated
1759  */
1760  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1761  if( row->lppos >= 0 )
1762  pos = col->nlprows-1;
1763  linkpos = col->linkpos[pos];
1764 
1765  assert(0 <= linkpos && linkpos < row->len);
1766  assert(row->cols[linkpos] == col);
1767  assert(col->rows[pos] == row);
1768  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1769  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1770  }
1771  }
1772  else
1773  {
1774  assert(row->linkpos[linkpos] == -1);
1775  assert(row->nunlinked > 0);
1776  row->linkpos[linkpos] = pos;
1777  row->nunlinked--;
1778 
1779  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1780  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1781  */
1782  if( col->lppos >= 0 )
1783  {
1784  row->nlpcols++;
1785  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1786 
1787  /* if no swap was necessary, mark nonlpcols to be unsorted */
1788  if( linkpos == row->nlpcols-1 )
1789  row->lpcolssorted = FALSE;
1790  }
1791  }
1792 
1793  /* update the sorted flags */
1794  if( row->lppos >= 0 && linkpos >= 0 )
1795  {
1796  assert(col->nlprows >= 1);
1797  assert(col->rows[col->nlprows-1] == row);
1798  if( col->nlprows > 1 )
1799  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1800  }
1801  else
1802  {
1803  assert(col->len - col->nlprows >= 1);
1804  assert(col->rows[col->len-1] == row);
1805  if( col->len - col->nlprows > 1 )
1806  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1807  }
1808 
1809  coefChanged(row, col, lp);
1810 
1811  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1812  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1813 
1814  return SCIP_OKAY;
1815 }
1816 
1817 /** deletes coefficient at given position from column */
1818 static
1820  SCIP_COL* col, /**< column to be changed */
1821  SCIP_SET* set, /**< global SCIP settings */
1822  SCIP_LP* lp, /**< current LP data */
1823  int pos /**< position in column vector to delete */
1824  )
1825 {
1826  SCIP_ROW* row;
1827 
1828  assert(col != NULL);
1829  assert(col->var != NULL);
1830  assert(set != 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  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1835 
1836  row = col->rows[pos];
1837  assert((row->lppos >= 0) == (pos < col->nlprows));
1838 
1839  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1840  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1841 
1842  if( col->linkpos[pos] == -1 )
1843  col->nunlinked--;
1844 
1845  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1846  if( pos < col->nlprows )
1847  {
1848  colMoveCoef(col, col->nlprows-1, pos);
1849  col->nlprows--;
1850  pos = col->nlprows;
1851  }
1852 
1853  /* move last coefficient to position of empty slot */
1854  colMoveCoef(col, col->len-1, pos);
1855  col->len--;
1856 
1857  coefChanged(row, col, lp);
1858 
1859  return SCIP_OKAY;
1860 }
1861 
1862 /** changes a coefficient at given position of an LP column */
1863 static
1865  SCIP_COL* col, /**< LP column */
1866  SCIP_SET* set, /**< global SCIP settings */
1867  SCIP_LP* lp, /**< current LP data */
1868  int pos, /**< position in column vector to change */
1869  SCIP_Real val /**< value of coefficient */
1870  )
1871 {
1872  assert(col != NULL);
1873  assert(col->var != NULL);
1874  assert(0 <= pos && pos < col->len);
1875  assert(col->rows[pos] != NULL);
1876  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1877 
1878  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1879  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1880 
1881  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1882  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1883 
1884  if( SCIPsetIsZero(set, val) )
1885  {
1886  /* delete existing coefficient */
1887  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1888  }
1889  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1890  {
1891  /* change existing coefficient */
1892  col->vals[pos] = val;
1893  coefChanged(col->rows[pos], col, lp);
1894  }
1895 
1896  return SCIP_OKAY;
1897 }
1898 
1899 
1900 
1901 
1902 /*
1903  * local row changing methods
1904  */
1905 
1906 /** update row norms after addition of coefficient */
1907 static
1909  SCIP_ROW* row, /**< LP row */
1910  SCIP_SET* set, /**< global SCIP settings */
1911  SCIP_COL* col, /**< column of added coefficient */
1912  SCIP_Real val, /**< value of added coefficient */
1913  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1914  )
1915 {
1916  SCIP_Real absval;
1917 
1918  assert(row != NULL);
1919  assert(row->nummaxval >= 0);
1920  assert(row->numminval >= 0);
1921  assert(set != NULL);
1922  assert(col != NULL);
1923 
1924  absval = REALABS(val);
1925  assert(!SCIPsetIsZero(set, absval));
1926 
1927  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1928  if( col->lppos >= 0 )
1929  {
1930  /* update squared Euclidean norm and sum norm */
1931  row->sqrnorm += SQR(absval);
1932  row->sumnorm += absval;
1933 
1934  /* update objective function scalar product */
1935  row->objprod += val * col->unchangedobj;
1936  }
1937 
1938  if( updateidxvals )
1939  {
1940  /* update min/maxidx */
1941  row->minidx = MIN(row->minidx, col->index);
1942  row->maxidx = MAX(row->maxidx, col->index);
1943 
1944  /* update maximal and minimal non-zero value */
1945  if( row->nummaxval > 0 )
1946  {
1947  if( SCIPsetIsGT(set, absval, row->maxval) )
1948  {
1949  row->maxval = absval;
1950  row->nummaxval = 1;
1951  }
1952  else if( SCIPsetIsGE(set, absval, row->maxval) )
1953  {
1954  /* make sure the maxval is always exactly the same */
1955  row->maxval = MAX(absval, row->maxval);
1956  row->nummaxval++;
1957  }
1958  }
1959  if( row->numminval > 0 )
1960  {
1961  if( SCIPsetIsLT(set, absval, row->minval) )
1962  {
1963  row->minval = absval;
1964  row->numminval = 1;
1965  }
1966  else if( SCIPsetIsLE(set, absval, row->minval) )
1967  {
1968  /* make sure the minval is always exactly the same */
1969  row->minval = MIN(absval, row->minval);
1970  row->numminval++;
1971  }
1972  }
1973  }
1974  else
1975  {
1976  assert(row->minidx <= col->index);
1977  assert(row->maxidx >= col->index);
1978  assert(row->numminval <= 0 || absval >= row->minval);
1979  assert(row->nummaxval <= 0 || absval <= row->maxval);
1980  }
1981 }
1982 
1983 /** update row norms after deletion of coefficient */
1984 static
1986  SCIP_ROW* row, /**< LP row */
1987  SCIP_SET* set, /**< global SCIP settings */
1988  SCIP_COL* col, /**< column of deleted coefficient */
1989  SCIP_Real val, /**< value of deleted coefficient */
1990  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1991  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1992  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1993  )
1994 {
1995  SCIP_Real absval;
1996 
1997  assert(row != NULL);
1998  assert(row->nummaxval >= 0);
1999  assert(row->numminval >= 0);
2000  assert(set != NULL);
2001  assert(col != NULL);
2002 
2003  absval = REALABS(val);
2004  assert(!SCIPsetIsZero(set, absval));
2005  assert(row->nummaxval == 0 || row->maxval >= absval);
2006  assert(row->numminval == 0 || row->minval <= absval);
2007 
2008  /* update min/maxidx validity */
2009  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
2010  row->validminmaxidx = FALSE;
2011 
2012  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
2013  if( forcenormupdate || col->lppos >= 0 )
2014  {
2015  /* update squared Euclidean norm and sum norm */
2016  row->sqrnorm -= SQR(absval);
2017  row->sqrnorm = MAX(row->sqrnorm, 0.0);
2018  row->sumnorm -= absval;
2019  row->sumnorm = MAX(row->sumnorm, 0.0);
2020 
2021  /* update objective function scalar product */
2022  row->objprod -= val * col->unchangedobj;
2023  }
2024 
2025  if( updateval )
2026  {
2027  /* update maximal and minimal non-zero value */
2028  if( row->nummaxval > 0 )
2029  {
2030  if( SCIPsetIsGE(set, absval, row->maxval) )
2031  row->nummaxval--;
2032  }
2033  if( row->numminval > 0 )
2034  {
2035  if( SCIPsetIsLE(set, absval, row->minval) )
2036  row->numminval--;
2037  }
2038  }
2039 }
2040 
2041 /** adds a previously non existing coefficient to an LP row */
2042 static
2044  SCIP_ROW* row, /**< LP row */
2045  BMS_BLKMEM* blkmem, /**< block memory */
2046  SCIP_SET* set, /**< global SCIP settings */
2047  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2048  SCIP_LP* lp, /**< current LP data */
2049  SCIP_COL* col, /**< LP column */
2050  SCIP_Real val, /**< value of coefficient */
2051  int linkpos /**< position of row in the column's row array, or -1 */
2052  )
2053 {
2054  int pos;
2055 
2056  assert(row != NULL);
2057  assert(row->nlpcols <= row->len);
2058  assert(blkmem != NULL);
2059  assert(col != NULL);
2060  assert(col->var != NULL);
2061  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2062  assert(!SCIPsetIsZero(set, val));
2063  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2064 
2065  if( row->nlocks > 0 )
2066  {
2067  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2068  return SCIP_INVALIDDATA;
2069  }
2070 
2071  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2072  assert(row->cols != NULL);
2073  assert(row->vals != NULL);
2074 
2075  pos = row->len;
2076  row->len++;
2077 
2078  /* 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
2079  * part of the row's arrays
2080  */
2081  if( col->lppos >= 0 && linkpos >= 0 )
2082  {
2083  /* move the first non-LP/not linked column to the end */
2084  if( row->nlpcols < pos )
2085  {
2086  rowMoveCoef(row, row->nlpcols, pos);
2087  pos = row->nlpcols;
2088  }
2089  row->nlpcols++;
2090  }
2091 
2092  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2093  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2094 
2095  /* insert the column at the correct position and update the links */
2096  row->cols[pos] = col;
2097  row->cols_index[pos] = col->index;
2098  row->vals[pos] = val;
2099  row->linkpos[pos] = linkpos;
2100  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2101  if( linkpos == -1 )
2102  {
2103  row->nunlinked++;
2104 
2105  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2106  * of the column is not complete
2107  */
2108  if( row->lppos >= 0 )
2109  {
2110  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2111  * has to be updated
2112  */
2113  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2114  if( col->lppos >= 0 )
2115  pos = row->nlpcols-1;
2116  linkpos = row->linkpos[pos];
2117 
2118  assert(0 <= linkpos && linkpos < col->len);
2119  assert(col->rows[linkpos] == row);
2120  assert(row->cols[pos] == col);
2121  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2122  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2123  }
2124  }
2125  else
2126  {
2127  assert(col->linkpos[linkpos] == -1);
2128  assert(col->nunlinked > 0);
2129  col->linkpos[linkpos] = pos;
2130  col->nunlinked--;
2131 
2132  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2133  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2134  */
2135  if( row->lppos >= 0 )
2136  {
2137  col->nlprows++;
2138  colSwapCoefs(col, linkpos, col->nlprows-1);
2139 
2140  /* if no swap was necessary, mark lprows to be unsorted */
2141  if( linkpos == col->nlprows-1 )
2142  col->lprowssorted = FALSE;
2143  }
2144  }
2145 
2146  /* update the sorted flags */
2147  if( col->lppos >= 0 && linkpos >= 0 )
2148  {
2149  assert(row->nlpcols >= 1);
2150  assert(row->cols[row->nlpcols-1] == col);
2151  if( row->nlpcols > 1 )
2152  {
2153  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2154  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2155  }
2156  }
2157  else
2158  {
2159  assert(row->len - row->nlpcols >= 1);
2160  assert(row->cols[row->len-1] == col);
2161  if( row->len - row->nlpcols > 1 )
2162  {
2163  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2164  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2165  }
2166  }
2167 
2168  /* update row norm */
2169  rowAddNorms(row, set, col, val, TRUE);
2170 
2171  coefChanged(row, col, lp);
2172 
2173  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2174  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2175 
2176  /* issue row coefficient changed event */
2177  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2178 
2179  return SCIP_OKAY;
2180 }
2181 
2182 /** deletes coefficient at given position from row */
2183 static
2185  SCIP_ROW* row, /**< row to be changed */
2186  BMS_BLKMEM* blkmem, /**< block memory */
2187  SCIP_SET* set, /**< global SCIP settings */
2188  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2189  SCIP_LP* lp, /**< current LP data */
2190  int pos /**< position in row vector to delete */
2191  )
2192 {
2193  SCIP_COL* col;
2194  SCIP_Real val;
2195 
2196  assert(row != NULL);
2197  assert(set != NULL);
2198  assert(0 <= pos && pos < row->len);
2199  assert(row->cols[pos] != NULL);
2200  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2201 
2202  col = row->cols[pos];
2203  val = row->vals[pos];
2204  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2205 
2206  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2207  val, SCIPvarGetName(col->var), pos, row->name);*/
2208 
2209  if( row->nlocks > 0 )
2210  {
2211  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2212  return SCIP_INVALIDDATA;
2213  }
2214 
2215  if( row->linkpos[pos] == -1 )
2216  row->nunlinked--;
2217 
2218  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2219  if( pos < row->nlpcols )
2220  {
2221  rowMoveCoef(row, row->nlpcols-1, pos);
2222  assert(!row->lpcolssorted);
2223  row->nlpcols--;
2224  pos = row->nlpcols;
2225  }
2226 
2227  /* move last coefficient to position of empty slot */
2228  rowMoveCoef(row, row->len-1, pos);
2229  row->len--;
2230 
2231  /* update norms */
2232  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2233 
2234  coefChanged(row, col, lp);
2235 
2236  /* issue row coefficient changed event */
2237  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2238 
2239  return SCIP_OKAY;
2240 }
2241 
2242 /** changes a coefficient at given position of an LP row */
2243 static
2245  SCIP_ROW* row, /**< LP row */
2246  BMS_BLKMEM* blkmem, /**< block memory */
2247  SCIP_SET* set, /**< global SCIP settings */
2248  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2249  SCIP_LP* lp, /**< current LP data */
2250  int pos, /**< position in row vector to change */
2251  SCIP_Real val /**< value of coefficient */
2252  )
2253 {
2254  SCIP_COL* col;
2255 
2256  assert(row != NULL);
2257  assert(0 <= pos && pos < row->len);
2258 
2259  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2260  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2261 
2262  if( row->nlocks > 0 )
2263  {
2264  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2265  return SCIP_INVALIDDATA;
2266  }
2267 
2268  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2269  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2270  col = row->cols[pos];
2271  assert(row->cols[pos] != NULL);
2272 
2273  if( SCIPsetIsZero(set, val) )
2274  {
2275  /* delete existing coefficient */
2276  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2277  }
2278  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2279  {
2280  SCIP_Real oldval;
2281 
2282  oldval = row->vals[pos];
2283 
2284  /* change existing coefficient */
2285  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2286  row->vals[pos] = val;
2287  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2288  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2289  coefChanged(row, col, lp);
2290 
2291  /* issue row coefficient changed event */
2292  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2293  }
2294 
2295  return SCIP_OKAY;
2296 }
2297 
2298 /** notifies LP row, that its sides were changed */
2299 static
2301  SCIP_ROW* row, /**< LP row */
2302  SCIP_SET* set, /**< global SCIP settings */
2303  SCIP_LP* lp, /**< current LP data */
2304  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2305  )
2306 {
2307  assert(row != NULL);
2308  assert(lp != NULL);
2309 
2310  if( row->lpipos >= 0 )
2311  {
2312  /* insert row in the chgrows list (if not already there) */
2313  if( !row->lhschanged && !row->rhschanged )
2314  {
2315  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2316  lp->chgrows[lp->nchgrows] = row;
2317  lp->nchgrows++;
2318  }
2319 
2320  /* mark side change in the row */
2321  switch( sidetype )
2322  {
2323  case SCIP_SIDETYPE_LEFT:
2324  row->lhschanged = TRUE;
2325  break;
2326  case SCIP_SIDETYPE_RIGHT:
2327  row->rhschanged = TRUE;
2328  break;
2329  default:
2330  SCIPerrorMessage("unknown row side type\n");
2331  SCIPABORT();
2332  return SCIP_INVALIDDATA; /*lint !e527*/
2333  }
2334 
2335  /* mark the current LP unflushed */
2336  lp->flushed = FALSE;
2337 
2338  assert(lp->nchgrows > 0);
2339  }
2340 
2341  return SCIP_OKAY;
2342 }
2343 
2344 
2345 
2346 
2347 /*
2348  * double linked coefficient matrix methods
2349  */
2350 
2351 /** insert column coefficients in corresponding rows */
2352 static
2354  SCIP_COL* col, /**< column data */
2355  BMS_BLKMEM* blkmem, /**< block memory */
2356  SCIP_SET* set, /**< global SCIP settings */
2357  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2358  SCIP_LP* lp /**< current LP data */
2359  )
2360 {
2361  int i;
2362 
2363  assert(col != NULL);
2364  assert(col->var != NULL);
2365  assert(blkmem != NULL);
2366  assert(set != NULL);
2367  assert(lp != NULL);
2368 
2369  if( col->nunlinked > 0 )
2370  {
2371  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2372 
2373  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2374  for( i = col->nlprows; i < col->len; ++i )
2375  {
2376  assert(!SCIPsetIsZero(set, col->vals[i]));
2377  if( col->linkpos[i] == -1 )
2378  {
2379  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2380  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2381  }
2382  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2383  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2384  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2385  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2386  }
2387  }
2388  assert(col->nunlinked == 0);
2389 
2390  checkLinks(lp);
2391 
2392  return SCIP_OKAY;
2393 }
2394 
2395 /** removes column coefficients from corresponding rows */
2396 static
2398  SCIP_COL* col, /**< column data */
2399  BMS_BLKMEM* blkmem, /**< block memory */
2400  SCIP_SET* set, /**< global SCIP settings */
2401  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2402  SCIP_LP* lp /**< current LP data */
2403  )
2404 {
2405  int i;
2406 
2407  assert(col != NULL);
2408  assert(col->var != NULL);
2409  assert(blkmem != NULL);
2410  assert(set != NULL);
2411  assert(lp != NULL);
2412 
2413  if( col->nunlinked < col->len )
2414  {
2415  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2416  for( i = 0; i < col->len; ++i )
2417  {
2418  if( col->linkpos[i] >= 0 )
2419  {
2420  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2421  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2422  col->linkpos[i] = -1;
2423  col->nunlinked++;
2424  }
2425  }
2426  }
2427  assert(col->nunlinked == col->len);
2428 
2429  checkLinks(lp);
2430 
2431  return SCIP_OKAY;
2432 }
2433 
2434 /** insert row coefficients in corresponding columns */
2435 static
2437  SCIP_ROW* row, /**< row data */
2438  BMS_BLKMEM* blkmem, /**< block memory */
2439  SCIP_SET* set, /**< global SCIP settings */
2440  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2441  SCIP_LP* lp /**< current LP data */
2442  )
2443 {
2444  int i;
2445 
2446  assert(row != NULL);
2447  assert(blkmem != NULL);
2448  assert(set != NULL);
2449  assert(lp != NULL);
2450 
2451  if( row->nunlinked > 0 )
2452  {
2453  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2454 
2455  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2456  for( i = row->nlpcols; i < row->len; ++i )
2457  {
2458  assert(!SCIPsetIsZero(set, row->vals[i]));
2459  if( row->linkpos[i] == -1 )
2460  {
2461  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2462  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2463  }
2464  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2465  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2466  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2467  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2468  }
2469  }
2470  assert(row->nunlinked == 0);
2471 
2472  checkLinks(lp);
2473 
2474  return SCIP_OKAY;
2475 }
2476 
2477 /** removes row coefficients from corresponding columns */
2478 static
2480  SCIP_ROW* row, /**< row data */
2481  SCIP_SET* set, /**< global SCIP settings */
2482  SCIP_LP* lp /**< current LP data */
2483  )
2484 {
2485  int i;
2486 
2487  assert(row != NULL);
2488  assert(set != NULL);
2489  assert(lp != NULL);
2490 
2491  if( row->nunlinked < row->len )
2492  {
2493  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2494  for( i = 0; i < row->len; ++i )
2495  {
2496  if( row->linkpos[i] >= 0 )
2497  {
2498  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2499  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2500  row->nunlinked++;
2501  }
2502  }
2503  }
2504  assert(row->nunlinked == row->len);
2505 
2506  return SCIP_OKAY;
2507 }
2508 
2509 
2510 
2511 
2512 /*
2513  * local LP parameter methods
2514  */
2515 
2516 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2517 static
2519  SCIP_LP* lp, /**< current LP data */
2520  SCIP_LPPARAM lpparam, /**< LP parameter */
2521  int value, /**< value to set parameter to */
2522  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2523  )
2524 {
2525  SCIP_RETCODE retcode;
2526 
2527  assert(lp != NULL);
2528  assert(success != NULL);
2529 
2530  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2531 
2532  /* check, if parameter is unknown */
2533  if( retcode == SCIP_PARAMETERUNKNOWN )
2534  {
2535  *success = FALSE;
2536  return SCIP_OKAY;
2537  }
2538  *success = TRUE;
2539 
2540  return retcode;
2541 }
2542 
2543 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2544 static
2546  SCIP_LP* lp, /**< current LP data */
2547  SCIP_LPPARAM lpparam, /**< LP parameter */
2548  SCIP_Bool value, /**< value to set parameter to */
2549  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2550  )
2551 {
2552  return lpSetIntpar(lp, lpparam, (int)value, success);
2553 }
2554 
2555 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2556 static
2558  SCIP_LP* lp, /**< current LP data */
2559  SCIP_LPPARAM lpparam, /**< LP parameter */
2560  SCIP_Real value, /**< value to set parameter to */
2561  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2562  )
2563 {
2564  SCIP_RETCODE retcode;
2565 
2566  assert(lp != NULL);
2567  assert(success != NULL);
2568 
2569  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2570 
2571  /* check, if parameter is unknown */
2572  if( retcode == SCIP_PARAMETERUNKNOWN )
2573  {
2574  *success = FALSE;
2575  return SCIP_OKAY;
2576  }
2577  *success = TRUE;
2578 
2579  return retcode;
2580 }
2581 
2582 #ifndef NDEBUG
2583 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2584 static
2586  SCIP_LP* lp, /**< current LP data */
2587  SCIP_LPPARAM lpparam, /**< LP parameter */
2588  int value /**< value parameter should have */
2589  )
2590 {
2591  SCIP_RETCODE retcode;
2592  int lpivalue;
2593 
2594  assert(lp != NULL);
2595 
2596  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2597 
2598  /* ignore unknown parameter error */
2599  if( retcode == SCIP_PARAMETERUNKNOWN )
2600  return SCIP_OKAY;
2601 
2602  /* check value */
2603  assert(lpivalue == value);
2604 
2605  return retcode;
2606 }
2607 
2608 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2609 static
2611  SCIP_LP* lp, /**< current LP data */
2612  SCIP_LPPARAM lpparam, /**< LP parameter */
2613  SCIP_Bool value /**< value parameter should have */
2614  )
2615 {
2616  return lpCheckIntpar(lp, lpparam, (int)value);
2617 }
2618 
2619 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2620 static
2622  SCIP_LP* lp, /**< current LP data */
2623  SCIP_LPPARAM lpparam, /**< LP parameter */
2624  SCIP_Real value /**< value parameter should have */
2625  )
2626 {
2627  SCIP_RETCODE retcode;
2628  SCIP_Real lpivalue;
2629 
2630  assert(lp != NULL);
2631 
2632  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2633 
2634  /* ignore unknown parameter error */
2635  if( retcode == SCIP_PARAMETERUNKNOWN )
2636  return SCIP_OKAY;
2637 
2638  /* check value */
2639  assert(lpivalue == value); /*lint !e777*/
2640 
2641  return retcode;
2642 }
2643 #else
2644 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2645 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2646 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2647 #endif
2648 
2649 /** should the objective limit of the LP solver be disabled */
2650 #define lpCutoffDisabled(set,prob) (set->lp_disablecutoff == 1 || ((set->nactivepricers > 0 || !SCIPprobAllColsInLP(prob, set, lp)) && set->lp_disablecutoff == 2))
2651 
2652 /** sets the objective limit of the LP solver
2653  *
2654  * Note that we are always minimizing.
2655  */
2656 static
2658  SCIP_LP* lp, /**< current LP data */
2659  SCIP_SET* set, /**< global SCIP settings */
2660  SCIP_PROB* prob, /**< problem data */
2661  SCIP_Real objlim, /**< new objective limit */
2662  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2663  )
2664 {
2665  assert(lp != NULL);
2666  assert(set != NULL);
2667  assert(success != NULL);
2668 
2669  *success = FALSE;
2670 
2671  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2672  * solver's objective limit handling, so we make sure that the objective limit is inactive (infinity). */
2673  if( lpCutoffDisabled(set, prob) || set->misc_exactsolve )
2674  objlim = SCIPlpiInfinity(lp->lpi);
2675 
2676  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2677  if( SCIPsetIsInfinity(set, objlim) )
2678  objlim = SCIPlpiInfinity(lp->lpi);
2679 
2681 
2682  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2683  {
2684  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2685  if( *success )
2686  {
2687  SCIP_Real actualobjlim;
2688 
2689  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2690  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2691  if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2692  {
2693  /* mark the current solution invalid */
2694  lp->solved = FALSE;
2695  lp->primalfeasible = FALSE;
2696  lp->primalchecked = FALSE;
2697  lp->lpobjval = SCIP_INVALID;
2699  }
2700  lp->lpiobjlim = actualobjlim;
2701  }
2702  }
2703 
2704  return SCIP_OKAY;
2705 }
2706 
2707 /** sets the feasibility tolerance of the LP solver */
2708 static
2710  SCIP_LP* lp, /**< current LP data */
2711  SCIP_Real feastol, /**< new feasibility tolerance */
2712  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2713  )
2714 {
2715  assert(lp != NULL);
2716  assert(feastol >= 0.0);
2717  assert(success != NULL);
2718 
2720 
2721  if( feastol != lp->lpifeastol ) /*lint !e777*/
2722  {
2723  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2724  if( *success )
2725  {
2726  SCIP_Real actualfeastol;
2727 
2728  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2729  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2730  if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2731  {
2732  /* mark the current solution invalid */
2733  lp->solved = FALSE;
2734  lp->primalfeasible = FALSE;
2735  lp->primalchecked = FALSE;
2736  lp->lpobjval = SCIP_INVALID;
2738  }
2739  else
2740  *success = FALSE;
2741  lp->lpifeastol = actualfeastol;
2742  }
2743  }
2744  else
2745  *success = FALSE;
2746 
2747  return SCIP_OKAY;
2748 }
2749 
2750 /** sets the reduced costs feasibility tolerance of the LP solver */
2751 static
2753  SCIP_LP* lp, /**< current LP data */
2754  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2755  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2756  )
2757 {
2758  assert(lp != NULL);
2759  assert(dualfeastol >= 0.0);
2760  assert(success != NULL);
2761 
2763 
2764  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2765  {
2766  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2767  if( *success )
2768  {
2769  SCIP_Real actualdualfeastol;
2770 
2771  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2772  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2773  if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2774  {
2775  /* mark the current solution invalid */
2776  lp->solved = FALSE;
2777  lp->dualfeasible = FALSE;
2778  lp->dualchecked = FALSE;
2779  lp->lpobjval = SCIP_INVALID;
2781  }
2782  else
2783  *success = FALSE;
2784  lp->lpidualfeastol = actualdualfeastol;
2785  }
2786  }
2787  else
2788  *success = FALSE;
2789 
2790  return SCIP_OKAY;
2791 }
2792 
2793 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2794 static
2796  SCIP_LP* lp, /**< current LP data */
2797  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2798  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2799  )
2800 {
2801  assert(lp != NULL);
2802  assert(barrierconvtol >= 0.0);
2803  assert(success != NULL);
2804 
2806 
2807  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2808  {
2809  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2810  if( *success )
2811  {
2812  SCIP_Real actualbarrierconvtol;
2813 
2814  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2815  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
2816  if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
2818  {
2819  /* mark the current solution invalid */
2820  lp->solved = FALSE;
2821  lp->dualfeasible = FALSE;
2822  lp->dualchecked = FALSE;
2823  lp->lpobjval = SCIP_INVALID;
2825  }
2826  else
2827  *success = FALSE;
2828  lp->lpibarrierconvtol = actualbarrierconvtol;
2829  }
2830  }
2831  else
2832  *success = FALSE;
2833 
2834  return SCIP_OKAY;
2835 }
2836 
2837 /** sets the FROMSCRATCH setting of the LP solver */
2838 static
2840  SCIP_LP* lp, /**< current LP data */
2841  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2842  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2843  )
2844 {
2845  assert(lp != NULL);
2846  assert(success != NULL);
2847 
2849 
2850  if( fromscratch != lp->lpifromscratch )
2851  {
2852  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2853  if( *success )
2854  lp->lpifromscratch = fromscratch;
2855  }
2856  else
2857  *success = FALSE;
2858 
2859  return SCIP_OKAY;
2860 }
2861 
2862 /** sets the FASTMIP setting of the LP solver */
2863 static
2865  SCIP_LP* lp, /**< current LP data */
2866  int fastmip, /**< new FASTMIP setting */
2867  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2868  )
2869 {
2870  assert(lp != NULL);
2871  assert(success != NULL);
2872  assert(0 <= fastmip && fastmip <= 1);
2873 
2875 
2876  if( fastmip != lp->lpifastmip )
2877  {
2878  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2879  if( *success )
2880  {
2881  lp->lpifastmip = fastmip;
2882  lp->solved = FALSE;
2883  /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
2884  * demanding setting; however, in the current code, this should have not effect. */
2885  }
2886  }
2887  else
2888  *success = FALSE;
2889 
2890  return SCIP_OKAY;
2891 }
2892 
2893 /** sets the SCALING setting of the LP solver */
2894 static
2896  SCIP_LP* lp, /**< current LP data */
2897  int scaling, /**< new SCALING setting */
2898  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2899  )
2900 {
2901  assert(lp != NULL);
2902  assert(success != NULL);
2903 
2905 
2906  if( scaling != lp->lpiscaling )
2907  {
2908  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2909  if( *success )
2910  lp->lpiscaling = scaling;
2911  }
2912  else
2913  *success = FALSE;
2914 
2915  return SCIP_OKAY;
2916 }
2917 
2918 /** sets the number of THREADS of the LP solver */
2919 static
2921  SCIP_LP* lp, /**< current LP data */
2922  int threads, /**< new number of threads used to solve the LP */
2923  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2924  )
2925 {
2926  assert(lp != NULL);
2927  assert(success != NULL);
2928 
2930 
2931  if( threads != lp->lpithreads )
2932  {
2933  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2934  if( *success )
2935  lp->lpithreads = threads;
2936  }
2937  else
2938  *success = FALSE;
2939 
2940  return SCIP_OKAY;
2941 }
2942 
2943 /** sets the PRESOLVING setting of the LP solver */
2944 static
2946  SCIP_LP* lp, /**< current LP data */
2947  SCIP_Bool presolving, /**< new PRESOLVING setting */
2948  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2949  )
2950 {
2951  assert(lp != NULL);
2952  assert(success != NULL);
2953 
2955 
2956  if( presolving != lp->lpipresolving )
2957  {
2958  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2959  if( *success )
2960  lp->lpipresolving = presolving;
2961  }
2962  else
2963  *success = FALSE;
2964 
2965  return SCIP_OKAY;
2966 }
2967 
2968 /** sets the ROWREPSWITCH setting of the LP solver */
2969 static
2971  SCIP_LP* lp, /**< current LP data */
2972  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2973  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2974  )
2975 {
2976  assert(lp != NULL);
2977  assert(success != NULL);
2978 
2980 
2981  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2982  {
2983  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2984  if( *success )
2985  lp->lpirowrepswitch = rowrepswitch;
2986  }
2987  else
2988  *success = FALSE;
2989 
2990  return SCIP_OKAY;
2991 }
2992 
2993 /** sets the iteration limit of the LP solver */
2994 static
2996  SCIP_LP* lp, /**< current LP data */
2997  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2998  )
2999 {
3000  SCIP_Bool success;
3001 
3002  assert(lp != NULL);
3003  assert(itlim >= -1);
3004 
3005  if( itlim == -1 )
3006  itlim = INT_MAX;
3007 
3009 
3010  if( itlim != lp->lpiitlim )
3011  {
3012  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
3013  if( success )
3014  {
3015  if( itlim > lp->lpiitlim )
3016  {
3017  /* mark the current solution invalid */
3018  lp->solved = FALSE;
3019  lp->lpobjval = SCIP_INVALID;
3021  }
3022  lp->lpiitlim = itlim;
3023  }
3024  }
3025 
3026  return SCIP_OKAY;
3027 }
3028 
3029 /** sets the pricing strategy of the LP solver */
3030 static
3032  SCIP_LP* lp, /**< current LP data */
3033  SCIP_PRICING pricing /**< pricing strategy */
3034  )
3035 {
3036  SCIP_Bool success;
3037 
3038  assert(lp != NULL);
3039 
3041 
3042  if( pricing != lp->lpipricing )
3043  {
3044  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3045  if( success )
3046  lp->lpipricing = pricing;
3047  }
3048 
3049  return SCIP_OKAY;
3050 }
3051 
3052 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3053 static
3055  SCIP_LP* lp, /**< current LP data */
3056  char pricingchar /**< character representing the pricing strategy */
3057  )
3058 {
3059  SCIP_PRICING pricing;
3060 
3061  switch( pricingchar )
3062  {
3063  case 'l':
3064  pricing = SCIP_PRICING_LPIDEFAULT;
3065  break;
3066  case 'a':
3067  pricing = SCIP_PRICING_AUTO;
3068  break;
3069  case 'f':
3070  pricing = SCIP_PRICING_FULL;
3071  break;
3072  case 'p':
3073  pricing = SCIP_PRICING_PARTIAL;
3074  break;
3075  case 's':
3076  pricing = SCIP_PRICING_STEEP;
3077  break;
3078  case 'q':
3079  pricing = SCIP_PRICING_STEEPQSTART;
3080  break;
3081  case 'd':
3082  pricing = SCIP_PRICING_DEVEX;
3083  break;
3084  default:
3085  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3086  return SCIP_INVALIDDATA;
3087  }
3088 
3089  SCIP_CALL( lpSetPricing(lp, pricing) );
3090 
3091  return SCIP_OKAY;
3092 }
3093 
3094 /** sets the verbosity of the LP solver */
3095 static
3097  SCIP_LP* lp, /**< current LP data */
3098  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3099  )
3100 {
3101  SCIP_Bool success;
3102 
3103  assert(lp != NULL);
3104 
3106 
3107  if( lpinfo != lp->lpilpinfo )
3108  {
3109  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3110  if( success )
3111  lp->lpilpinfo = lpinfo;
3112  }
3113 
3114  return SCIP_OKAY;
3115 }
3116 
3117 /** sets the CONDITIONLIMIT setting of the LP solver */
3118 static
3120  SCIP_LP* lp, /**< current LP data */
3121  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3122  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3123  )
3124 {
3125  assert(lp != NULL);
3126  assert(success != NULL);
3127 
3129 
3130  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3131  {
3132  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3133  if( *success )
3134  lp->lpiconditionlimit = condlimit;
3135  }
3136  else
3137  *success = FALSE;
3138 
3139  return SCIP_OKAY;
3140 }
3141 
3142 /** sets the MARKOWITZ setting of the LP solver */
3143 static
3145  SCIP_LP* lp, /**< current LP data */
3146  SCIP_Real threshhold, /**< new MARKOWITZ value */
3147  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3148  )
3149 {
3150  assert(lp != NULL);
3151  assert(success != NULL);
3152 
3154 
3155  if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3156  {
3157  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3158  if( *success )
3159  lp->lpimarkowitz = threshhold;
3160  }
3161  else
3162  *success = FALSE;
3163 
3164  return SCIP_OKAY;
3165 }
3166 
3167 /** sets the type of timer of the LP solver */
3168 static
3170  SCIP_LP* lp, /**< current LP data */
3171  SCIP_CLOCKTYPE timing, /**< new timing value */
3172  SCIP_Bool enabled, /**< is timing enabled? */
3173  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3174  )
3175 {
3176  int lptiming;
3177 
3178  assert(lp != NULL);
3179  assert(success != NULL);
3180  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*//*lint !e1564*/
3181 
3183 
3184  if( !enabled )
3185  lptiming = 0;
3186  else
3187  lptiming = (int) timing;
3188 
3189  if( lptiming != lp->lpitiming ) /*lint !e777*/
3190  {
3191  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3192  if( *success )
3193  lp->lpitiming = lptiming;
3194  }
3195  else
3196  *success = FALSE;
3197 
3198  return SCIP_OKAY;
3199 }
3200 
3201 /** sets the initial random seed of the LP solver */
3202 static
3204  SCIP_LP* lp, /**< current LP data */
3205  int randomseed, /**< new initial random seed */
3206  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3207  )
3208 {
3209  assert(lp != NULL);
3210  assert(success != NULL);
3211 
3212  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3213 
3214  if( randomseed == 0 )
3215  {
3216  lp->lpirandomseed = randomseed;
3217  *success = TRUE;
3218  }
3219  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3220  {
3221  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3222  if( *success )
3223  lp->lpirandomseed = randomseed;
3224  }
3225  else
3226  *success = FALSE;
3227 
3228  return SCIP_OKAY;
3229 }
3230 
3231 /** sets the LP solution polishing method */
3232 static
3234  SCIP_LP* lp, /**< current LP data */
3235  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3236  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3237  )
3238 {
3239  assert(lp != NULL);
3240  assert(success != NULL);
3241 
3242  if( polishing != lp->lpisolutionpolishing )
3243  {
3244  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3245  if( *success )
3246  lp->lpisolutionpolishing = polishing;
3247  }
3248  else
3249  *success = FALSE;
3250 
3251  return SCIP_OKAY;
3252 }
3253 
3254 /** sets the LP refactorization interval */
3255 static
3257  SCIP_LP* lp, /**< current LP data */
3258  int refactor, /**< LP refactorization interval (0: automatic) */
3259  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3260  )
3261 {
3262  assert(lp != NULL);
3263  assert(success != NULL);
3264 
3265  if( refactor != lp->lpirefactorinterval )
3266  {
3267  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3268  if( *success )
3269  lp->lpirefactorinterval = refactor;
3270  }
3271  else
3272  *success = FALSE;
3273 
3274  return SCIP_OKAY;
3275 }
3276 
3277 
3278 /*
3279  * Column methods
3280  */
3281 
3282 /** creates an LP column */
3284  SCIP_COL** col, /**< pointer to column data */
3285  BMS_BLKMEM* blkmem, /**< block memory */
3286  SCIP_SET* set, /**< global SCIP settings */
3287  SCIP_STAT* stat, /**< problem statistics */
3288  SCIP_VAR* var, /**< variable, this column represents */
3289  int len, /**< number of nonzeros in the column */
3290  SCIP_ROW** rows, /**< array with rows of column entries */
3291  SCIP_Real* vals, /**< array with coefficients of column entries */
3292  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3293  )
3294 {
3295  int i;
3296 
3297  assert(col != NULL);
3298  assert(blkmem != NULL);
3299  assert(set != NULL);
3300  assert(stat != NULL);
3301  assert(var != NULL);
3302  assert(len >= 0);
3303  assert(len == 0 || (rows != NULL && vals != NULL));
3304 
3305  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3306 
3307  if( len > 0 )
3308  {
3309  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3310  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3311  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3312 
3313  for( i = 0; i < len; ++i )
3314  {
3315  assert(rows[i] != NULL);
3316  assert(!SCIPsetIsZero(set, vals[i]));
3317  (*col)->linkpos[i] = -1;
3318  }
3319  }
3320  else
3321  {
3322  (*col)->rows = NULL;
3323  (*col)->vals = NULL;
3324  (*col)->linkpos = NULL;
3325  }
3326 
3327  (*col)->var = var;
3328  (*col)->obj = SCIPvarGetObj(var);
3329  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3330  (*col)->lb = SCIPvarGetLbLocal(var);
3331  (*col)->ub = SCIPvarGetUbLocal(var);
3332  (*col)->flushedobj = 0.0;
3333  (*col)->flushedlb = 0.0;
3334  (*col)->flushedub = 0.0;
3335  (*col)->index = stat->ncolidx;
3336  SCIPstatIncrement(stat, set, ncolidx);
3337  (*col)->size = len;
3338  (*col)->len = len;
3339  (*col)->nlprows = 0;
3340  (*col)->nunlinked = len;
3341  (*col)->lppos = -1;
3342  (*col)->lpipos = -1;
3343  (*col)->lpdepth = -1;
3344  (*col)->primsol = 0.0;
3345  (*col)->redcost = SCIP_INVALID;
3346  (*col)->farkascoef = SCIP_INVALID;
3347  (*col)->minprimsol = (*col)->ub;
3348  (*col)->maxprimsol = (*col)->lb;
3349  (*col)->sbdown = SCIP_INVALID;
3350  (*col)->sbup = SCIP_INVALID;
3351  (*col)->sbsolval = SCIP_INVALID;
3352  (*col)->sblpobjval = SCIP_INVALID;
3353  (*col)->sbnode = -1;
3354  (*col)->validredcostlp = -1;
3355  (*col)->validfarkaslp = -1;
3356  (*col)->validsblp = -1;
3357  (*col)->sbitlim = -1;
3358  (*col)->nsbcalls = 0;
3359  (*col)->age = 0;
3360  (*col)->obsoletenode = -1;
3361  (*col)->var_probindex = SCIPvarGetProbindex(var);
3362  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3363  (*col)->lprowssorted = TRUE;
3364  (*col)->nonlprowssorted = (len <= 1);
3365  (*col)->objchanged = FALSE;
3366  (*col)->lbchanged = FALSE;
3367  (*col)->ubchanged = FALSE;
3368  (*col)->coefchanged = FALSE;
3369  (*col)->integral = SCIPvarIsIntegral(var);
3370  (*col)->removable = removable;
3371  (*col)->sbdownvalid = FALSE;
3372  (*col)->sbupvalid = FALSE;
3373  (*col)->lazylb = SCIPvarGetLbLazy(var);
3374  (*col)->lazyub = SCIPvarGetUbLazy(var);
3375  (*col)->storedsolvals = NULL;
3376 
3377  return SCIP_OKAY;
3378 }
3379 
3380 /** frees an LP column */
3382  SCIP_COL** col, /**< pointer to LP column */
3383  BMS_BLKMEM* blkmem, /**< block memory */
3384  SCIP_SET* set, /**< global SCIP settings */
3385  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3386  SCIP_LP* lp /**< current LP data */
3387  )
3388 {
3389  assert(blkmem != NULL);
3390  assert(col != NULL);
3391  assert(*col != NULL);
3392  assert((*col)->var != NULL);
3393  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3394  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3395  assert((*col)->lppos == -1);
3396  assert((*col)->lpipos == -1);
3397 
3398  /* remove column indices from corresponding rows */
3399  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3400 
3401  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3402  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3403  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3404  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3405  BMSfreeBlockMemory(blkmem, col);
3406 
3407  return SCIP_OKAY;
3408 }
3409 
3410 /** output column to file stream */
3412  SCIP_COL* col, /**< LP column */
3413  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3414  FILE* file /**< output file (or NULL for standard output) */
3415  )
3416 {
3417  int r;
3418 
3419  assert(col != NULL);
3420  assert(col->var != NULL);
3421 
3422  /* print bounds */
3423  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3424 
3425  /* print coefficients */
3426  if( col->len == 0 )
3427  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3428  for( r = 0; r < col->len; ++r )
3429  {
3430  assert(col->rows[r] != NULL);
3431  assert(col->rows[r]->name != NULL);
3432  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3433  }
3434  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3435 }
3436 
3437 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3438  */
3440  SCIP_COL* col /**< column to be sorted */
3441  )
3442 {
3443  /* sort LP rows */
3444  colSortLP(col);
3445 
3446  /* sort non-LP rows */
3447  colSortNonLP(col);
3448 }
3449 
3450 /** adds a previously non existing coefficient to an LP column */
3452  SCIP_COL* col, /**< LP column */
3453  BMS_BLKMEM* blkmem, /**< block memory */
3454  SCIP_SET* set, /**< global SCIP settings */
3455  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3456  SCIP_LP* lp, /**< current LP data */
3457  SCIP_ROW* row, /**< LP row */
3458  SCIP_Real val /**< value of coefficient */
3459  )
3460 {
3461  assert(lp != NULL);
3462  assert(!lp->diving);
3463 
3464  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3465 
3466  checkLinks(lp);
3467 
3468  return SCIP_OKAY;
3469 }
3470 
3471 /** deletes existing coefficient from column */
3473  SCIP_COL* col, /**< column to be changed */
3474  BMS_BLKMEM* blkmem, /**< block memory */
3475  SCIP_SET* set, /**< global SCIP settings */
3476  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3477  SCIP_LP* lp, /**< current LP data */
3478  SCIP_ROW* row /**< coefficient to be deleted */
3479  )
3480 {
3481  int pos;
3482 
3483  assert(col != NULL);
3484  assert(col->var != NULL);
3485  assert(lp != NULL);
3486  assert(!lp->diving);
3487  assert(row != NULL);
3488 
3489  /* search the position of the row in the column's row vector */
3490  pos = colSearchCoef(col, row);
3491  if( pos == -1 )
3492  {
3493  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3494  return SCIP_INVALIDDATA;
3495  }
3496  assert(0 <= pos && pos < col->len);
3497  assert(col->rows[pos] == row);
3498 
3499  /* if row knows of the column, remove the column from the row's col vector */
3500  if( col->linkpos[pos] >= 0 )
3501  {
3502  assert(row->cols[col->linkpos[pos]] == col);
3503  assert(row->cols_index[col->linkpos[pos]] == col->index);
3504  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3505  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3506  }
3507 
3508  /* delete the row from the column's row vector */
3509  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3510 
3511  checkLinks(lp);
3512 
3513  return SCIP_OKAY;
3514 }
3515 
3516 /** changes or adds a coefficient to an LP column */
3518  SCIP_COL* col, /**< LP column */
3519  BMS_BLKMEM* blkmem, /**< block memory */
3520  SCIP_SET* set, /**< global SCIP settings */
3521  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3522  SCIP_LP* lp, /**< current LP data */
3523  SCIP_ROW* row, /**< LP row */
3524  SCIP_Real val /**< value of coefficient */
3525  )
3526 {
3527  int pos;
3528 
3529  assert(col != NULL);
3530  assert(lp != NULL);
3531  assert(!lp->diving);
3532  assert(row != NULL);
3533 
3534  /* search the position of the row in the column's row vector */
3535  pos = colSearchCoef(col, row);
3536 
3537  /* check, if row already exists in the column's row vector */
3538  if( pos == -1 )
3539  {
3540  /* add previously not existing coefficient */
3541  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3542  }
3543  else
3544  {
3545  /* modify already existing coefficient */
3546  assert(0 <= pos && pos < col->len);
3547  assert(col->rows[pos] == row);
3548 
3549  /* if row knows of the column, change the corresponding coefficient in the row */
3550  if( col->linkpos[pos] >= 0 )
3551  {
3552  assert(row->cols[col->linkpos[pos]] == col);
3553  assert(row->cols_index[col->linkpos[pos]] == col->index);
3554  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3555  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3556  }
3557 
3558  /* change the coefficient in the column */
3559  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3560  }
3561 
3562  checkLinks(lp);
3563 
3564  return SCIP_OKAY;
3565 }
3566 
3567 /** increases value of an existing or non-existing coefficient in an LP column */
3569  SCIP_COL* col, /**< LP column */
3570  BMS_BLKMEM* blkmem, /**< block memory */
3571  SCIP_SET* set, /**< global SCIP settings */
3572  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3573  SCIP_LP* lp, /**< current LP data */
3574  SCIP_ROW* row, /**< LP row */
3575  SCIP_Real incval /**< value to add to the coefficient */
3576  )
3577 {
3578  int pos;
3579 
3580  assert(col != NULL);
3581  assert(lp != NULL);
3582  assert(!lp->diving);
3583  assert(row != NULL);
3584 
3585  if( SCIPsetIsZero(set, incval) )
3586  return SCIP_OKAY;
3587 
3588  /* search the position of the row in the column's row vector */
3589  pos = colSearchCoef(col, row);
3590 
3591  /* check, if row already exists in the column's row vector */
3592  if( pos == -1 )
3593  {
3594  /* add previously not existing coefficient */
3595  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3596  }
3597  else
3598  {
3599  /* modify already existing coefficient */
3600  assert(0 <= pos && pos < col->len);
3601  assert(col->rows[pos] == row);
3602 
3603  /* if row knows of the column, change the corresponding coefficient in the row */
3604  if( col->linkpos[pos] >= 0 )
3605  {
3606  assert(row->cols[col->linkpos[pos]] == col);
3607  assert(row->cols_index[col->linkpos[pos]] == col->index);
3608  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3609  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3610  }
3611 
3612  /* change the coefficient in the column */
3613  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3614  }
3615 
3616  checkLinks(lp);
3617 
3618  return SCIP_OKAY;
3619 }
3620 
3621 /** insert column in the chgcols list (if not already there) */
3622 static
3624  SCIP_COL* col, /**< LP column to change */
3625  SCIP_SET* set, /**< global SCIP settings */
3626  SCIP_LP* lp /**< current LP data */
3627  )
3628 {
3629  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3630  {
3631  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3632  lp->chgcols[lp->nchgcols] = col;
3633  lp->nchgcols++;
3634  }
3635 
3636  /* mark the current LP unflushed */
3637  lp->flushed = FALSE;
3638 
3639  return SCIP_OKAY;
3640 }
3641 
3642 /** Is the new value reliable or may we have cancellation?
3643  *
3644  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3645  * cancellations which can occur during increasing the oldvalue to the newvalue
3646  */
3647 static
3649  SCIP_SET* set, /**< global SCIP settings */
3650  SCIP_Real newvalue, /**< new value */
3651  SCIP_Real oldvalue /**< old reliable value */
3652  )
3653 {
3654  SCIP_Real quotient;
3655 
3656  assert(set != NULL);
3657  assert(oldvalue != SCIP_INVALID); /*lint !e777*/
3658 
3659  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3660 
3661  return SCIPsetIsZero(set, quotient);
3662 }
3663 
3664 /** update norms of objective function vector */
3665 static
3667  SCIP_LP* lp, /**< current LP data */
3668  SCIP_SET* set, /**< global SCIP settings */
3669  SCIP_Real oldobj, /**< old objective value of variable */
3670  SCIP_Real newobj /**< new objective value of variable */
3671  )
3672 {
3673  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3674  {
3675  if( !lp->objsqrnormunreliable )
3676  {
3677  SCIP_Real oldvalue;
3678 
3679  oldvalue = lp->objsqrnorm;
3680  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3681 
3682  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3683  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3684  lp->objsqrnormunreliable = TRUE;
3685  else
3686  {
3687  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3688 
3689  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3690  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3691 
3692  assert(lp->objsqrnorm >= 0.0);
3693  }
3694  }
3695 
3696  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3697  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3698  }
3699 }
3700 
3701 /** changes objective value of column */
3703  SCIP_COL* col, /**< LP column to change */
3704  SCIP_SET* set, /**< global SCIP settings */
3705  SCIP_LP* lp, /**< current LP data */
3706  SCIP_Real newobj /**< new objective value */
3707  )
3708 {
3709  assert(col != NULL);
3710  assert(col->var != NULL);
3711  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3712  assert(SCIPvarGetCol(col->var) == col);
3713  assert(lp != NULL);
3714 
3715  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3716 
3717  /* only add actual changes */
3718  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3719  {
3720  /* only variables with a real position in the LPI can be inserted */
3721  if( col->lpipos >= 0 )
3722  {
3723  /* insert column in the chgcols list (if not already there) */
3724  SCIP_CALL( insertColChgcols(col, set, lp) );
3725 
3726  /* mark objective value change in the column */
3727  col->objchanged = TRUE;
3728 
3729  assert(lp->nchgcols > 0);
3730  }
3731  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3732  * LP and the LP has to be flushed
3733  */
3734  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3735  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3736  {
3737  /* mark the LP unflushed */
3738  lp->flushed = FALSE;
3739  }
3740  }
3741 
3742  /* store new objective function value */
3743  col->obj = newobj;
3744 
3745  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3746  if( !lp->divingobjchg )
3747  {
3748  SCIP_Real oldobj = col->unchangedobj;
3749 
3750  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3751  col->unchangedobj = newobj;
3752 
3753  /* update the objective function vector norms */
3754  lpUpdateObjNorms(lp, set, oldobj, newobj);
3755  }
3756 
3757  return SCIP_OKAY;
3758 }
3759 
3760 /** changes lower bound of column */
3762  SCIP_COL* col, /**< LP column to change */
3763  SCIP_SET* set, /**< global SCIP settings */
3764  SCIP_LP* lp, /**< current LP data */
3765  SCIP_Real newlb /**< new lower bound value */
3766  )
3767 {
3768  assert(col != NULL);
3769  assert(col->var != NULL);
3770  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3771  assert(SCIPvarGetCol(col->var) == col);
3772  assert(lp != NULL);
3773 
3774  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3775 
3776  /* only add actual changes */
3777  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3778  {
3779  /* only variables with a real position in the LPI can be inserted */
3780  if( col->lpipos >= 0 )
3781  {
3782  /* insert column in the chgcols list (if not already there) */
3783  SCIP_CALL( insertColChgcols(col, set, lp) );
3784 
3785  /* mark bound change in the column */
3786  col->lbchanged = TRUE;
3787 
3788  assert(lp->nchgcols > 0);
3789  }
3790  /* 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
3791  * flushed
3792  */
3793  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3794  {
3795  /* mark the LP unflushed */
3796  lp->flushed = FALSE;
3797  }
3798  }
3799 
3800  col->lb = newlb;
3801 
3802  return SCIP_OKAY;
3803 }
3804 
3805 /** changes upper bound of column */
3807  SCIP_COL* col, /**< LP column to change */
3808  SCIP_SET* set, /**< global SCIP settings */
3809  SCIP_LP* lp, /**< current LP data */
3810  SCIP_Real newub /**< new upper bound value */
3811  )
3812 {
3813  assert(col != NULL);
3814  assert(col->var != NULL);
3815  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3816  assert(SCIPvarGetCol(col->var) == col);
3817  assert(lp != NULL);
3818 
3819  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3820 
3821  /* only add actual changes */
3822  if( !SCIPsetIsEQ(set, col->ub, newub) )
3823  {
3824  /* only variables with a real position in the LPI can be inserted */
3825  if( col->lpipos >= 0 )
3826  {
3827  /* insert column in the chgcols list (if not already there) */
3828  SCIP_CALL( insertColChgcols(col, set, lp) );
3829 
3830  /* mark bound change in the column */
3831  col->ubchanged = TRUE;
3832 
3833  assert(lp->nchgcols > 0);
3834  }
3835  /* 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
3836  * flushed
3837  */
3838  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3839  {
3840  /* mark the LP unflushed */
3841  lp->flushed = FALSE;
3842  }
3843  }
3844 
3845  col->ub = newub;
3846 
3847  return SCIP_OKAY;
3848 }
3849 
3850 /** calculates the reduced costs of a column using the given dual solution vector */
3852  SCIP_COL* col, /**< LP column */
3853  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3854  )
3855 {
3856  SCIP_ROW* row;
3857  SCIP_Real redcost;
3858  int i;
3859 
3860  assert(col != NULL);
3861  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3862  assert(SCIPvarGetCol(col->var) == col);
3863  assert(dualsol != NULL);
3864 
3865  redcost = col->obj;
3866  for( i = 0; i < col->nlprows; ++i )
3867  {
3868  row = col->rows[i];
3869  assert(row != NULL);
3870  assert(row->lppos >= 0);
3871  redcost -= col->vals[i] * dualsol[row->lppos];
3872  }
3873 
3874  if( col->nunlinked > 0 )
3875  {
3876  for( i = col->nlprows; i < col->len; ++i )
3877  {
3878  row = col->rows[i];
3879  assert(row != NULL);
3880  assert(row->lppos == -1 || col->linkpos[i] == -1);
3881  if( row->lppos >= 0 )
3882  redcost -= col->vals[i] * dualsol[row->lppos];
3883  }
3884  }
3885 #ifndef NDEBUG
3886  else
3887  {
3888  for( i = col->nlprows; i < col->len; ++i )
3889  {
3890  row = col->rows[i];
3891  assert(row != NULL);
3892  assert(row->lppos == -1);
3893  assert(col->linkpos[i] >= 0);
3894  }
3895  }
3896 #endif
3897 
3898  return redcost;
3899 }
3900 
3901 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3902 static
3904  SCIP_COL* col /**< LP column */
3905  )
3906 {
3907  SCIP_ROW* row;
3908  SCIP_Real redcost;
3909  int i;
3910 
3911  assert(col != NULL);
3912  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3913  assert(SCIPvarGetCol(col->var) == col);
3914 
3915  redcost = col->obj;
3916  for( i = 0; i < col->nlprows; ++i )
3917  {
3918  row = col->rows[i];
3919  assert(row != NULL);
3920  assert(row->dualsol != SCIP_INVALID); /*lint !e777*/
3921  assert(row->lppos >= 0);
3922  assert(col->linkpos[i] >= 0);
3923  redcost -= col->vals[i] * row->dualsol;
3924  }
3925 
3926  if( col->nunlinked > 0 )
3927  {
3928  for( i = col->nlprows; i < col->len; ++i )
3929  {
3930  row = col->rows[i];
3931  assert(row != NULL);
3932  assert(row->lppos >= 0 || row->dualsol == 0.0);
3933  assert(row->lppos == -1 || col->linkpos[i] == -1);
3934  if( row->lppos >= 0 )
3935  redcost -= col->vals[i] * row->dualsol;
3936  }
3937  }
3938 #ifndef NDEBUG
3939  else
3940  {
3941  for( i = col->nlprows; i < col->len; ++i )
3942  {
3943  row = col->rows[i];
3944  assert(row != NULL);
3945  assert(row->dualsol == 0.0);
3946  assert(row->lppos == -1);
3947  assert(col->linkpos[i] >= 0);
3948  }
3949  }
3950 #endif
3951 
3952  return redcost;
3953 }
3954 
3955 /** gets the reduced costs of a column in last LP or after recalculation */
3957  SCIP_COL* col, /**< LP column */
3958  SCIP_STAT* stat, /**< problem statistics */
3959  SCIP_LP* lp /**< current LP data */
3960  )
3961 {
3962  assert(col != NULL);
3963  assert(stat != NULL);
3964  assert(lp != NULL);
3965  assert(col->validredcostlp <= stat->lpcount);
3966  assert(lp->validsollp == stat->lpcount);
3967 
3968  if( col->validredcostlp < stat->lpcount )
3969  {
3970  col->redcost = colCalcInternalRedcost(col);
3971  col->validredcostlp = stat->lpcount;
3972  }
3973  assert(col->validredcostlp == stat->lpcount);
3974  assert(col->redcost != SCIP_INVALID); /*lint !e777*/
3975 
3976  return col->redcost;
3977 }
3978 
3979 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3981  SCIP_COL* col, /**< LP column */
3982  SCIP_SET* set, /**< global SCIP settings */
3983  SCIP_STAT* stat, /**< problem statistics */
3984  SCIP_LP* lp /**< current LP data */
3985  )
3986 {
3987  assert(col != NULL);
3988  assert(set != NULL);
3989  assert(stat != NULL);
3990  assert(lp != NULL);
3991  assert(lp->validsollp == stat->lpcount);
3992 
3993  /* A column's reduced cost is defined as
3994  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3995  * The activity is equal to the activity of the corresponding row in the dual LP.
3996  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3997  * The sides of the dual row depend on the bounds of the column:
3998  * - lb == ub : dual row is a free row with infinite sides
3999  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
4000  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
4001  * - lb < ub <= 0: obj <= activity => redcost <= 0
4002  */
4003  if( SCIPsetIsEQ(set, col->lb, col->ub) )
4004  {
4005  /* dual row is free */
4006  return SCIPsetInfinity(set);
4007  }
4008  else
4009  {
4010  SCIP_Real redcost;
4011 
4012  /* calculate reduced costs */
4013  redcost = SCIPcolGetRedcost(col, stat, lp);
4014 
4015  if( !SCIPsetIsNegative(set, col->lb) )
4016  {
4017  /* dual row is activity <= obj <=> redcost >= 0 */
4018  return redcost;
4019  }
4020  else if( SCIPsetIsPositive(set, col->ub) )
4021  {
4022  /* dual row is activity == obj <=> redcost == 0 */
4023  return -REALABS(redcost);
4024  }
4025  else
4026  {
4027  /* dual row is activity >= obj <=> redcost <= 0 */
4028  return -redcost;
4029  }
4030  }
4031 }
4032 
4033 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4035  SCIP_COL* col, /**< LP column */
4036  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4037  )
4038 {
4039  SCIP_ROW* row;
4040  SCIP_Real farkas;
4041  int i;
4042 
4043  assert(col != NULL);
4044  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4045  assert(SCIPvarGetCol(col->var) == col);
4046  assert(dualfarkas != NULL);
4047 
4048  farkas = 0.0;
4049  for( i = 0; i < col->nlprows; ++i )
4050  {
4051  row = col->rows[i];
4052  assert(row != NULL);
4053  assert(row->lppos >= 0);
4054  farkas += col->vals[i] * dualfarkas[row->lppos];
4055  }
4056 
4057  if( col->nunlinked > 0 )
4058  {
4059  for( i = col->nlprows; i < col->len; ++i )
4060  {
4061  row = col->rows[i];
4062  assert(row != NULL);
4063  assert(row->lppos == -1 || col->linkpos[i] == -1);
4064  if( row->lppos >= 0 )
4065  farkas += col->vals[i] * dualfarkas[row->lppos];
4066  }
4067  }
4068 #ifndef NDEBUG
4069  else
4070  {
4071  for( i = col->nlprows; i < col->len; ++i )
4072  {
4073  row = col->rows[i];
4074  assert(row != NULL);
4075  assert(row->lppos == -1);
4076  assert(col->linkpos[i] >= 0);
4077  }
4078  }
4079 #endif
4080 
4081  return farkas;
4082 }
4083 
4084 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4085 static
4087  SCIP_COL* col /**< LP column */
4088  )
4089 {
4090  SCIP_ROW* row;
4091  SCIP_Real farkas;
4092  int i;
4093 
4094  assert(col != NULL);
4095  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4096  assert(SCIPvarGetCol(col->var) == col);
4097 
4098  farkas = 0.0;
4099  for( i = 0; i < col->nlprows; ++i )
4100  {
4101  row = col->rows[i];
4102  assert(row != NULL);
4103  assert(row->dualfarkas != SCIP_INVALID); /*lint !e777*/
4104  assert(row->lppos >= 0);
4105  assert(col->linkpos[i] >= 0);
4106  farkas += col->vals[i] * row->dualfarkas;
4107  }
4108 
4109  if( col->nunlinked > 0 )
4110  {
4111  for( i = col->nlprows; i < col->len; ++i )
4112  {
4113  row = col->rows[i];
4114  assert(row != NULL);
4115  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4116  assert(row->lppos == -1 || col->linkpos[i] == -1);
4117  if( row->lppos >= 0 )
4118  farkas += col->vals[i] * row->dualfarkas;
4119  }
4120  }
4121 #ifndef NDEBUG
4122  else
4123  {
4124  for( i = col->nlprows; i < col->len; ++i )
4125  {
4126  row = col->rows[i];
4127  assert(row != NULL);
4128  assert(row->dualfarkas == 0.0);
4129  assert(row->lppos == -1);
4130  assert(col->linkpos[i] >= 0);
4131  }
4132  }
4133 #endif
4134 
4135  return farkas;
4136 }
4137 
4138 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4140  SCIP_COL* col, /**< LP column */
4141  SCIP_STAT* stat, /**< problem statistics */
4142  SCIP_LP* lp /**< current LP data */
4143  )
4144 {
4145  assert(col != NULL);
4146  assert(stat != NULL);
4147  assert(lp != NULL);
4148  assert(col->validfarkaslp <= stat->lpcount);
4149  assert(lp->validfarkaslp == stat->lpcount);
4150 
4151  if( col->validfarkaslp < stat->lpcount )
4152  {
4154  col->validfarkaslp = stat->lpcount;
4155  }
4156  assert(col->validfarkaslp == stat->lpcount);
4157  assert(col->farkascoef != SCIP_INVALID); /*lint !e777*/
4158 
4159  return col->farkascoef;
4160 }
4161 
4162 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4163  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4164  */
4166  SCIP_COL* col, /**< LP column */
4167  SCIP_STAT* stat, /**< problem statistics */
4168  SCIP_LP* lp /**< current LP data */
4169  )
4170 {
4171  SCIP_Real farkascoef;
4172 
4173  assert(col != NULL);
4174 
4175  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4176 
4177  if( farkascoef > 0.0 )
4178  return col->ub * farkascoef;
4179  else
4180  return col->lb * farkascoef;
4181 }
4182 
4183 /** start strong branching - call before any strong branching */
4185  SCIP_LP* lp /**< LP data */
4186  )
4187 {
4188  assert(lp != NULL);
4189  assert(!lp->strongbranching);
4190 
4191  lp->strongbranching = TRUE;
4192  SCIPdebugMessage("starting strong branching ...\n");
4194 
4195  return SCIP_OKAY;
4196 }
4197 
4198 /** end strong branching - call after any strong branching */
4200  SCIP_LP* lp /**< LP data */
4201  )
4202 {
4203  assert(lp != NULL);
4204  assert(lp->strongbranching);
4205 
4206  lp->strongbranching = FALSE;
4207  SCIPdebugMessage("ending strong branching ...\n");
4209 
4210  return SCIP_OKAY;
4211 }
4212 
4213 /** sets strong branching information for a column variable */
4215  SCIP_COL* col, /**< LP column */
4216  SCIP_SET* set, /**< global SCIP settings */
4217  SCIP_STAT* stat, /**< dynamic problem statistics */
4218  SCIP_LP* lp, /**< LP data */
4219  SCIP_Real lpobjval, /**< objective value of the current LP */
4220  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4221  SCIP_Real sbdown, /**< dual bound after branching column down */
4222  SCIP_Real sbup, /**< dual bound after branching column up */
4223  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4224  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4225  SCIP_Longint iter, /**< total number of strong branching iterations */
4226  int itlim /**< iteration limit applied to the strong branching call */
4227  )
4228 {
4229  assert(col != NULL);
4230  assert(col->var != NULL);
4231  assert(SCIPcolIsIntegral(col));
4232  assert(SCIPvarIsIntegral(col->var));
4233  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4234  assert(SCIPvarGetCol(col->var) == col);
4235  assert(col->lpipos >= 0);
4236  assert(col->lppos >= 0);
4237  assert(set != NULL);
4238  assert(stat != NULL);
4239  assert(lp != NULL);
4240  assert(lp->strongbranchprobing);
4241  assert(col->lppos < lp->ncols);
4242  assert(lp->cols[col->lppos] == col);
4243  assert(itlim >= 1);
4244 
4245  col->sblpobjval = lpobjval;
4246  col->sbsolval = primsol;
4247  col->validsblp = stat->nlps;
4248  col->sbnode = stat->nnodes;
4249 
4250  col->sbitlim = itlim;
4251  col->nsbcalls++;
4252 
4253  col->sbdown = MIN(sbdown, lp->cutoffbound);
4254  col->sbup = MIN(sbup, lp->cutoffbound);
4255  col->sbdownvalid = sbdownvalid;
4256  col->sbupvalid = sbupvalid;
4257 
4258  SCIPstatIncrement(stat, set, nstrongbranchs);
4259  SCIPstatAdd(stat, set, nsblpiterations, iter);
4260  if( stat->nnodes == 1 )
4261  {
4262  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4263  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4264  }
4265 }
4266 
4267 /** invalidates strong branching information for a column variable */
4269  SCIP_COL* col, /**< LP column */
4270  SCIP_SET* set, /**< global SCIP settings */
4271  SCIP_STAT* stat, /**< dynamic problem statistics */
4272  SCIP_LP* lp /**< LP data */
4273  )
4274 {
4275  assert(col != NULL);
4276  assert(col->var != NULL);
4277  assert(SCIPcolIsIntegral(col));
4278  assert(SCIPvarIsIntegral(col->var));
4279  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4280  assert(SCIPvarGetCol(col->var) == col);
4281  assert(col->lpipos >= 0);
4282  assert(col->lppos >= 0);
4283  assert(set != NULL);
4284  assert(stat != NULL);
4285  assert(lp != NULL);
4286  assert(lp->strongbranchprobing);
4287  assert(col->lppos < lp->ncols);
4288  assert(lp->cols[col->lppos] == col);
4289 
4290  col->sbdown = SCIP_INVALID;
4291  col->sbup = SCIP_INVALID;
4292  col->sbdownvalid = FALSE;
4293  col->sbupvalid = FALSE;
4294  col->validsblp = -1;
4295  col->sbsolval = SCIP_INVALID;
4296  col->sblpobjval = SCIP_INVALID;
4297  col->sbnode = -1;
4298  col->sbitlim = -1;
4299 }
4300 
4301 
4302 /** gets strong branching information on a column variable */
4304  SCIP_COL* col, /**< LP column */
4305  SCIP_Bool integral, /**< should integral strong branching be performed? */
4306  SCIP_SET* set, /**< global SCIP settings */
4307  SCIP_STAT* stat, /**< dynamic problem statistics */
4308  SCIP_PROB* prob, /**< problem data */
4309  SCIP_LP* lp, /**< LP data */
4310  int itlim, /**< iteration limit for strong branchings */
4311  SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4312  SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4313  SCIP_Real* down, /**< stores dual bound after branching column down */
4314  SCIP_Real* up, /**< stores dual bound after branching column up */
4315  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4316  * otherwise, it can only be used as an estimate value */
4317  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4318  * otherwise, it can only be used as an estimate value */
4319  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4320  )
4321 {
4322  SCIP_Real sbdown;
4323  SCIP_Real sbup;
4324  SCIP_Bool sbdownvalid;
4325  SCIP_Bool sbupvalid;
4326  SCIP_Longint validsblp;
4327  SCIP_Real sbsolval;
4328  SCIP_Real sblpobjval;
4329  SCIP_Longint sbnode;
4330  int sbitlim;
4331  int nsbcalls;
4332 
4333  assert(col != NULL);
4334  assert(col->var != NULL);
4335  assert(SCIPcolIsIntegral(col));
4336  assert(SCIPvarIsIntegral(col->var));
4337  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4338  assert(SCIPvarGetCol(col->var) == col);
4339  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4340  assert(col->lpipos >= 0);
4341  assert(col->lppos >= 0);
4342  assert(set != NULL);
4343  assert(stat != NULL);
4344  assert(lp != NULL);
4345  assert(lp->flushed);
4346  assert(lp->solved);
4347  assert(lp->strongbranching);
4348  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4349  assert(lp->validsollp == stat->lpcount);
4350  assert(col->lppos < lp->ncols);
4351  assert(lp->cols[col->lppos] == col);
4352  assert(itlim >= 1);
4353  /* assert(down != NULL);
4354  * assert(up != NULL); temporary hack for cloud branching
4355  */
4356  assert(lperror != NULL);
4357 
4358  *lperror = FALSE;
4359 
4360  sbdown = col->sbdown;
4361  sbup = col->sbup;
4362  sbdownvalid = col->sbdownvalid;
4363  sbupvalid = col->sbupvalid;
4364  sbitlim = col->sbitlim;
4365  nsbcalls = col->nsbcalls;
4366 
4367  validsblp = stat->nlps;
4368  sbsolval = col->primsol;
4369  sblpobjval = SCIPlpGetObjval(lp, set, prob);
4370  sbnode = stat->nnodes;
4371  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4372 
4373  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4374  if( lp->looseobjvalinf > 0 )
4375  {
4376  sbdown = -SCIPsetInfinity(set);
4377  sbup = -SCIPsetInfinity(set);
4378  sbdownvalid = FALSE;
4379  sbupvalid = FALSE;
4380  }
4381  else
4382  {
4383  SCIP_RETCODE retcode;
4384  int iter;
4385 
4386  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4387  SCIPvarGetName(col->var), col->primsol, itlim);
4388 
4389  /* start timing */
4390  SCIPclockStart(stat->strongbranchtime, set);
4391 
4392  /* call LPI strong branching */
4393  sbitlim = itlim;
4394  nsbcalls++;
4395 
4396  sbdown = lp->lpobjval;
4397  sbup = lp->lpobjval;
4398 
4399  if( integral )
4400  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4401  else
4402  {
4403  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4404  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4405  }
4406 
4407  /* check return code for errors */
4408  if( retcode == SCIP_LPERROR )
4409  {
4410  *lperror = TRUE;
4411  sbdown = SCIP_INVALID;
4412  sbup = SCIP_INVALID;
4413  sbdownvalid = FALSE;
4414  sbupvalid = FALSE;
4415  validsblp = -1;
4416  sbsolval = SCIP_INVALID;
4417  sblpobjval = SCIP_INVALID;
4418  sbnode = -1;
4419  }
4420  else
4421  {
4422  SCIP_Real looseobjval;
4423 
4424  *lperror = FALSE;
4425  SCIP_CALL( retcode );
4426 
4427  looseobjval = getFiniteLooseObjval(lp, set, prob);
4428  sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4429  sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4430 
4431  /* update strong branching statistics */
4432  if( updatestat )
4433  {
4434  if( iter == -1 )
4435  {
4436  /* calculate average iteration number */
4437  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4438  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4439  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4440  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4441  : 0;
4442  if( iter/2 >= itlim )
4443  iter = 2*itlim;
4444  }
4445  SCIPstatIncrement(stat, set, nstrongbranchs);
4446  SCIPstatAdd(stat, set, nsblpiterations, iter);
4447  if( stat->nnodes == 1 )
4448  {
4449  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4450  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4451  }
4452  }
4453  }
4454 
4455  /* stop timing */
4456  SCIPclockStop(stat->strongbranchtime, set);
4457  }
4458  assert(*lperror || sbdown != SCIP_INVALID); /*lint !e777*/
4459  assert(*lperror || sbup != SCIP_INVALID); /*lint !e777*/
4460 
4461  if( down != NULL)
4462  *down = sbdown;
4463  if( up != NULL )
4464  *up = sbup;
4465  if( downvalid != NULL )
4466  *downvalid = sbdownvalid;
4467  if( upvalid != NULL )
4468  *upvalid = sbupvalid;
4469 
4470  if( updatecol )
4471  {
4472  col->sbdown = sbdown;
4473  col->sbup = sbup;
4474  col->sbdownvalid = sbdownvalid;
4475  col->sbupvalid = sbupvalid;
4476  col->validsblp = validsblp;
4477  col->sbsolval = sbsolval;
4478  col->sblpobjval = sblpobjval;
4479  col->sbnode = sbnode;
4480  col->sbitlim = sbitlim;
4481  col->nsbcalls = nsbcalls;
4482  }
4483 
4484  return SCIP_OKAY;
4485 }
4486 
4487 /** gets strong branching information on column variables */
4489  SCIP_COL** cols, /**< LP columns */
4490  int ncols, /**< number of columns */
4491  SCIP_Bool integral, /**< should integral strong branching be performed? */
4492  SCIP_SET* set, /**< global SCIP settings */
4493  SCIP_STAT* stat, /**< dynamic problem statistics */
4494  SCIP_PROB* prob, /**< problem data */
4495  SCIP_LP* lp, /**< LP data */
4496  int itlim, /**< iteration limit for strong branchings */
4497  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4498  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4499  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4500  * otherwise, they can only be used as an estimate value */
4501  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4502  * otherwise, they can only be used as an estimate value */
4503  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4504  )
4505 {
4506  SCIP_RETCODE retcode;
4507  SCIP_Real* sbdown;
4508  SCIP_Real* sbup;
4509  SCIP_Bool* sbdownvalid;
4510  SCIP_Bool* sbupvalid;
4511  SCIP_Real* primsols;
4512  SCIP_COL** subcols;
4513  int* lpipos;
4514  int* subidx;
4515  int nsubcols;
4516  int iter;
4517  int j;
4518 
4519  assert(cols != NULL);
4520  assert(set != NULL);
4521  assert(stat != NULL);
4522  assert(lp != NULL);
4523  assert(lp->flushed);
4524  assert(lp->solved);
4525  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4526  assert(lp->validsollp == stat->lpcount);
4527  assert(itlim >= 1);
4528  assert(down != NULL);
4529  assert(up != NULL);
4530  assert(lperror != NULL);
4531 
4532  *lperror = FALSE;
4533 
4534  if ( ncols <= 0 )
4535  return SCIP_OKAY;
4536 
4537  /* start timing */
4538  SCIPclockStart(stat->strongbranchtime, set);
4539 
4540  /* initialize storage */
4541  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4542  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4543  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4544  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4545  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4546  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4547  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4548  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4549 
4550  nsubcols = 0;
4551  for( j = 0; j < ncols; ++j )
4552  {
4553  SCIP_COL* col;
4554  col = cols[j];
4555 
4556  assert(col->lppos < lp->ncols);
4557  assert(lp->cols[col->lppos] == col);
4558  assert(SCIPcolIsIntegral(col));
4559  assert(SCIPvarIsIntegral(col->var));
4560  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4561  assert(SCIPvarGetCol(col->var) == col);
4562  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4563  assert(col->lpipos >= 0);
4564  assert(col->lppos >= 0);
4565 
4566  col->validsblp = stat->nlps;
4567  col->sbsolval = col->primsol;
4568  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4569  col->sbnode = stat->nnodes;
4570  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4571 
4572  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4573  if( lp->looseobjvalinf > 0 )
4574  {
4575  /* directly set up column and result vectors*/
4576  col->sbdown = -SCIPsetInfinity(set);
4577  col->sbup = -SCIPsetInfinity(set);
4578  col->sbdownvalid = FALSE;
4579  col->sbupvalid = FALSE;
4580  down[j] = col->sbdown;
4581  up[j] = col->sbup;
4582  if( downvalid != NULL )
4583  downvalid[j] = col->sbdownvalid;
4584  if( upvalid != NULL )
4585  upvalid[j] = col->sbupvalid;
4586  }
4587  else
4588  {
4589  col->sbitlim = itlim;
4590  col->nsbcalls++;
4591 
4592  lpipos[nsubcols] = col->lpipos;
4593  primsols[nsubcols] = col->primsol;
4594  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4595  subidx[nsubcols] = j;
4596  subcols[nsubcols++] = col;
4597  }
4598  }
4599 
4600  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4601 
4602  /* call LPI strong branching */
4603  if ( integral )
4604  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4605  else
4606  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4607 
4608  /* check return code for errors */
4609  if( retcode == SCIP_LPERROR )
4610  {
4611  *lperror = TRUE;
4612 
4613  for( j = 0; j < nsubcols; ++j )
4614  {
4615  SCIP_COL* col;
4616  int idx;
4617 
4618  col = subcols[j];
4619  idx = subidx[j];
4620 
4621  col->sbdown = SCIP_INVALID;
4622  col->sbup = SCIP_INVALID;
4623  col->sbdownvalid = FALSE;
4624  col->sbupvalid = FALSE;
4625  col->validsblp = -1;
4626  col->sbsolval = SCIP_INVALID;
4627  col->sblpobjval = SCIP_INVALID;
4628  col->sbnode = -1;
4629 
4630  down[idx] = col->sbdown;
4631  up[idx] = col->sbup;
4632  if( downvalid != NULL )
4633  downvalid[idx] = col->sbdownvalid;
4634  if( upvalid != NULL )
4635  upvalid[idx] = col->sbupvalid;
4636  }
4637  }
4638  else
4639  {
4640  SCIP_Real looseobjval;
4641 
4642  *lperror = FALSE;
4643  SCIP_CALL( retcode );
4644 
4645  looseobjval = getFiniteLooseObjval(lp, set, prob);
4646 
4647  for( j = 0; j < nsubcols; ++j )
4648  {
4649  SCIP_COL* col;
4650  int idx;
4651 
4652  col = subcols[j];
4653  idx = subidx[j];
4654 
4655  assert( col->sbdown != SCIP_INVALID); /*lint !e777*/
4656  assert( col->sbup != SCIP_INVALID); /*lint !e777*/
4657 
4658  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4659  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4660  col->sbdownvalid = sbdownvalid[j];
4661  col->sbupvalid = sbupvalid[j];
4662 
4663  down[idx] = col->sbdown;
4664  up[idx] = col->sbup;
4665  if( downvalid != NULL )
4666  downvalid[idx] = col->sbdownvalid;
4667  if( upvalid != NULL )
4668  upvalid[idx] = col->sbupvalid;
4669  }
4670 
4671  /* update strong branching statistics */
4672  if( iter == -1 )
4673  {
4674  /* calculate average iteration number */
4675  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4676  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4677  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4678  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4679  : 0;
4680  if( iter/2 >= itlim )
4681  iter = 2*itlim;
4682  }
4683  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4684  SCIPstatAdd(stat, set, nsblpiterations, iter);
4685  if( stat->nnodes == 1 )
4686  {
4687  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4688  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4689  }
4690  }
4691 
4692  SCIPsetFreeBufferArray(set, &sbupvalid);
4693  SCIPsetFreeBufferArray(set, &sbdownvalid);
4694  SCIPsetFreeBufferArray(set, &sbup);
4695  SCIPsetFreeBufferArray(set, &sbdown);
4696  SCIPsetFreeBufferArray(set, &primsols);
4697  SCIPsetFreeBufferArray(set, &lpipos);
4698  SCIPsetFreeBufferArray(set, &subidx);
4699  SCIPsetFreeBufferArray(set, &subcols);
4700 
4701  /* stop timing */
4702  SCIPclockStop(stat->strongbranchtime, set);
4703 
4704  return SCIP_OKAY;
4705 }
4706 
4707 /** gets last strong branching information available for a column variable;
4708  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4709  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4710  */
4712  SCIP_COL* col, /**< LP column */
4713  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4714  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4715  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4716  * otherwise, it can only be used as an estimate value */
4717  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4718  * otherwise, it can only be used as an estimate value */
4719  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4720  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4721  )
4722 {
4723  assert(col != NULL);
4724 
4725  if( down != NULL )
4726  *down = col->sbdown;
4727  if( up != NULL )
4728  *up = col->sbup;
4729  if( downvalid != NULL )
4730  *downvalid = col->sbdownvalid;
4731  if( upvalid != NULL )
4732  *upvalid = col->sbupvalid;
4733  if( solval != NULL )
4734  *solval = col->sbsolval;
4735  if( lpobjval != NULL )
4736  *lpobjval = col->sblpobjval;
4737 }
4738 
4739 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4740  * the LP where the strong branching on this column was applied;
4741  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4742  */
4744  SCIP_COL* col, /**< LP column */
4745  SCIP_STAT* stat /**< dynamic problem statistics */
4746  )
4747 {
4748  assert(col != NULL);
4749  assert(stat != NULL);
4750 
4751  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4752 }
4753 
4754 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4756  SCIP_COL* col, /**< LP column */
4757  SCIP_STAT* stat /**< problem statistics */
4758  )
4759 {
4760  assert(col != NULL);
4761  assert(stat != NULL);
4762  assert(stat->nnodes > 0);
4763 
4764  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4765  col->obsoletenode = stat->nnodes;
4766 }
4767 
4768 
4769 /*
4770  * Row methods
4771  */
4772 
4773 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4774 static
4776  SCIP_ROW* row, /**< LP row */
4777  SCIP_SET* set /**< global SCIP settings */
4778  )
4779 {
4780  int i;
4781 
4782  assert(row != NULL);
4783  assert(set != NULL);
4784 
4785  row->sqrnorm = 0.0;
4786  row->sumnorm = 0.0;
4787  row->objprod = 0.0;
4788  row->maxval = 0.0;
4789  row->nummaxval = 1;
4790  row->minval = SCIPsetInfinity(set);
4791  row->numminval = 1;
4792  row->minidx = INT_MAX;
4793  row->maxidx = INT_MIN;
4794  row->validminmaxidx = TRUE;
4795  row->lpcolssorted = TRUE;
4796  row->nonlpcolssorted = TRUE;
4797 
4798  /* check, if row is sorted
4799  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4800  */
4801  for( i = 0; i < row->nlpcols; ++i )
4802  {
4803  assert(row->cols[i] != NULL);
4804  assert(!SCIPsetIsZero(set, row->vals[i]));
4805  assert(row->cols[i]->lppos >= 0);
4806  assert(row->linkpos[i] >= 0);
4807  assert(row->cols[i]->index == row->cols_index[i]);
4808 
4809  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4810  if( i > 0 )
4811  {
4812  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4813  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4814  }
4815  }
4816  for( i = row->nlpcols; i < row->len; ++i )
4817  {
4818  assert(row->cols[i] != NULL);
4819  assert(!SCIPsetIsZero(set, row->vals[i]));
4820  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4821  assert(row->cols[i]->index == row->cols_index[i]);
4822 
4823  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4824  if( i > row->nlpcols )
4825  {
4826  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4827  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4828  }
4829  }
4830 }
4831 
4832 /** calculates min/maxval and min/maxidx from scratch */
4833 static
4835  SCIP_ROW* row, /**< LP row */
4836  SCIP_SET* set /**< global SCIP settings */
4837  )
4838 {
4839  SCIP_COL* col;
4840  SCIP_Real absval;
4841  int i;
4842 
4843  assert(row != NULL);
4844  assert(set != NULL);
4845 
4846  row->maxval = 0.0;
4847  row->nummaxval = 1;
4848  row->numintcols = 0;
4849  row->minval = SCIPsetInfinity(set);
4850  row->numminval = 1;
4851  row->minidx = INT_MAX;
4852  row->maxidx = INT_MIN;
4853  row->validminmaxidx = TRUE;
4854 
4855  /* calculate maxval, minval, minidx, and maxidx */
4856  for( i = 0; i < row->len; ++i )
4857  {
4858  col = row->cols[i];
4859  assert(col != NULL);
4860  assert(!SCIPsetIsZero(set, row->vals[i]));
4861 
4862  absval = REALABS(row->vals[i]);
4863  assert(!SCIPsetIsZero(set, absval));
4864 
4865  /* update min/maxidx */
4866  row->minidx = MIN(row->minidx, col->index);
4867  row->maxidx = MAX(row->maxidx, col->index);
4868  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4869 
4870  /* update maximal and minimal non-zero value */
4871  if( row->nummaxval > 0 )
4872  {
4873  if( SCIPsetIsGT(set, absval, row->maxval) )
4874  {
4875  row->maxval = absval;
4876  row->nummaxval = 1;
4877  }
4878  else if( SCIPsetIsGE(set, absval, row->maxval) )
4879  {
4880  /* make sure the maxval is always exactly the same */
4881  row->maxval = MAX(absval, row->maxval);
4882  row->nummaxval++;
4883  }
4884  }
4885  if( row->numminval > 0 )
4886  {
4887  if( SCIPsetIsLT(set, absval, row->minval) )
4888  {
4889  row->minval = absval;
4890  row->numminval = 1;
4891  }
4892  else if( SCIPsetIsLE(set, absval, row->minval) )
4893  {
4894  /* make sure the minval is always exactly the same */
4895  row->minval = MIN(absval, row->minval);
4896  row->numminval++;
4897  }
4898  }
4899  }
4900 }
4901 
4902 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4903 static
4905  SCIP_Real val, /**< value that should be scaled to an integral value */
4906  SCIP_Real scalar, /**< scalar that should be tried */
4907  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4908  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4909  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4910  )
4911 {
4912  SCIP_Real sval;
4913  SCIP_Real downval;
4914  SCIP_Real upval;
4915 
4916  assert(mindelta <= 0.0);
4917  assert(maxdelta >= 0.0);
4918 
4919  sval = val * scalar;
4920  downval = floor(sval);
4921  upval = ceil(sval);
4922 
4923  if( SCIPrelDiff(sval, downval) <= maxdelta )
4924  {
4925  if( intval != NULL )
4926  *intval = downval;
4927  return TRUE;
4928  }
4929  else if( SCIPrelDiff(sval, upval) >= mindelta )
4930  {
4931  if( intval != NULL )
4932  *intval = upval;
4933  return TRUE;
4934  }
4935 
4936  return FALSE;
4937 }
4938 
4939 /** scales row with given factor, and rounds coefficients to integers if close enough;
4940  * the constant is automatically moved to the sides;
4941  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4942  */
4943 static
4945  SCIP_ROW* row, /**< LP row */
4946  BMS_BLKMEM* blkmem, /**< block memory */
4947  SCIP_SET* set, /**< global SCIP settings */
4948  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4949  SCIP_STAT* stat, /**< problem statistics */
4950  SCIP_LP* lp, /**< current LP data */
4951  SCIP_Real scaleval, /**< value to scale row with */
4952  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4953  * if they are close to integral values? */
4954  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4955  * upto which the integral is used instead of the scaled real coefficient */
4956  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4957  * upto which the integral is used instead of the scaled real coefficient */
4958  )
4959 {
4960  SCIP_COL* col;
4961  SCIP_Real val;
4962  SCIP_Real newval;
4963  SCIP_Real intval;
4964  SCIP_Real mindelta;
4965  SCIP_Real maxdelta;
4966  SCIP_Real lb;
4967  SCIP_Real ub;
4968  SCIP_Bool mindeltainf;
4969  SCIP_Bool maxdeltainf;
4970  int oldlen;
4971  int c;
4972 
4973  assert(row != NULL);
4974  assert(row->len == 0 || row->cols != NULL);
4975  assert(row->len == 0 || row->vals != NULL);
4976  assert(SCIPsetIsPositive(set, scaleval));
4977  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4978  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4979 
4980  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4981 
4982  mindelta = 0.0;
4983  maxdelta = 0.0;
4984  mindeltainf = FALSE;
4985  maxdeltainf = FALSE;
4986  oldlen = row->len;
4987 
4988  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4989  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4990  * this rounding can lead to
4991  */
4992  row->integral = TRUE;
4993 
4994  c = 0;
4995  while( c < row->len )
4996  {
4997  col = row->cols[c];
4998  val = row->vals[c];
4999  assert(!SCIPsetIsZero(set, val));
5000 
5001  /* get local or global bounds for column, depending on the local or global feasibility of the row */
5002  if( row->local )
5003  {
5004  lb = col->lb;
5005  ub = col->ub;
5006  }
5007  else
5008  {
5009  lb = SCIPvarGetLbGlobal(col->var);
5010  ub = SCIPvarGetUbGlobal(col->var);
5011  }
5012 
5013  /* calculate scaled coefficient */
5014  newval = val * scaleval;
5015  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5016  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5017  {
5018  if( !SCIPsetIsEQ(set, intval, newval) )
5019  {
5020  if( intval < newval )
5021  {
5022  mindelta += (intval - newval)*ub;
5023  maxdelta += (intval - newval)*lb;
5024  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5025  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5026  }
5027  else
5028  {
5029  mindelta += (intval - newval)*lb;
5030  maxdelta += (intval - newval)*ub;
5031  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5032  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5033  }
5034  }
5035  newval = intval;
5036  }
5037 
5038  if( !SCIPsetIsEQ(set, val, newval) )
5039  {
5040  /* if column knows of the row, change the corresponding coefficient in the column */
5041  if( row->linkpos[c] >= 0 )
5042  {
5043  assert(col->rows[row->linkpos[c]] == row);
5044  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5045  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5046  }
5047 
5048  /* change the coefficient in the row, and update the norms and integrality status */
5049  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5050 
5051  /* current coefficient has been deleted from the row because it was almost zero */
5052  if( oldlen != row->len )
5053  {
5054  assert(row->len == oldlen - 1);
5055  c--;
5056  oldlen = row->len;
5057  }
5058  }
5059  else
5060  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5061 
5062  ++c;
5063  }
5064 
5065  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5066  * to not destroy feasibility due to rounding
5067  */
5068  /**@todo ensure that returned cut does not have infinite lhs and rhs */
5069  if( !SCIPsetIsInfinity(set, -row->lhs) )
5070  {
5071  if( mindeltainf )
5072  newval = -SCIPsetInfinity(set);
5073  else
5074  {
5075  newval = (row->lhs - row->constant) * scaleval + mindelta;
5076  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5077  newval = SCIPsetSumCeil(set, newval);
5078  }
5079  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5080  }
5081  if( !SCIPsetIsInfinity(set, row->rhs) )
5082  {
5083  if( maxdeltainf )
5084  newval = SCIPsetInfinity(set);
5085  else
5086  {
5087  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5088  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5089  newval = SCIPsetSumFloor(set, newval);
5090  }
5091  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5092  }
5093 
5094  /* clear the row constant */
5095  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5096 
5097  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5098  debugRowPrint(set, row);
5099 
5100 #ifdef SCIP_DEBUG
5101  /* check integrality status of row */
5102  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5103  {}
5104  assert(row->integral == (c == row->len));
5105 #endif
5106 
5107  /* invalid the activity */
5108  row->validactivitylp = -1;
5109 
5110  return SCIP_OKAY;
5111 }
5112 
5113 /** creates and captures an LP row */
5115  SCIP_ROW** row, /**< pointer to LP row data */
5116  BMS_BLKMEM* blkmem, /**< block memory */
5117  SCIP_SET* set, /**< global SCIP settings */
5118  SCIP_STAT* stat, /**< problem statistics */
5119  const char* name, /**< name of row */
5120  int len, /**< number of nonzeros in the row */
5121  SCIP_COL** cols, /**< array with columns of row entries */
5122  SCIP_Real* vals, /**< array with coefficients of row entries */
5123  SCIP_Real lhs, /**< left hand side of row */
5124  SCIP_Real rhs, /**< right hand side of row */
5125  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5126  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5127  SCIP_Bool local, /**< is row only valid locally? */
5128  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5129  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5130  )
5131 {
5132  assert(row != NULL);
5133  assert(blkmem != NULL);
5134  assert(stat != NULL);
5135  assert(len >= 0);
5136  assert(len == 0 || (cols != NULL && vals != NULL));
5137  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5138  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5139  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5140  */
5141  assert(lhs <= rhs);
5142 
5143  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5144 
5145  (*row)->integral = TRUE;
5146  if( len > 0 )
5147  {
5148  SCIP_VAR* var;
5149  int i;
5150 
5151  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5152  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5153  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5154  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5155 
5156  for( i = 0; i < len; ++i )
5157  {
5158  assert(cols[i] != NULL);
5159  assert(!SCIPsetIsZero(set, vals[i]));
5160 
5161  var = cols[i]->var;
5162  (*row)->cols_index[i] = cols[i]->index;
5163  (*row)->linkpos[i] = -1;
5164  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5165  {
5166  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5167  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5168  }
5169  else
5170  {
5171  (*row)->integral = FALSE;
5172  }
5173  }
5174  }
5175  else
5176  {
5177  (*row)->cols = NULL;
5178  (*row)->cols_index = NULL;
5179  (*row)->vals = NULL;
5180  (*row)->linkpos = NULL;
5181  }
5182 
5183  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5184  (*row)->constant = 0.0;
5185  (*row)->lhs = lhs;
5186  (*row)->rhs = rhs;
5187  (*row)->flushedlhs = -SCIPsetInfinity(set);
5188  (*row)->flushedrhs = SCIPsetInfinity(set);
5189  (*row)->sqrnorm = 0.0;
5190  (*row)->sumnorm = 0.0;
5191  (*row)->objprod = 0.0;
5192  (*row)->maxval = 0.0;
5193  (*row)->minval = SCIPsetInfinity(set);
5194  (*row)->dualsol = 0.0;
5195  (*row)->activity = SCIP_INVALID;
5196  (*row)->dualfarkas = 0.0;
5197  (*row)->pseudoactivity = SCIP_INVALID;
5198  (*row)->minactivity = SCIP_INVALID;
5199  (*row)->maxactivity = SCIP_INVALID;
5200  (*row)->origin = origin;
5201  (*row)->eventfilter = NULL;
5202  (*row)->index = stat->nrowidx;
5203  SCIPstatIncrement(stat, set, nrowidx);
5204  (*row)->size = len;
5205  (*row)->len = len;
5206  (*row)->nlpcols = 0;
5207  (*row)->nunlinked = len;
5208  (*row)->nuses = 0;
5209  (*row)->lppos = -1;
5210  (*row)->lpipos = -1;
5211  (*row)->lpdepth = -1;
5212  (*row)->minidx = INT_MAX;
5213  (*row)->maxidx = INT_MIN;
5214  (*row)->nummaxval = 0;
5215  (*row)->numminval = 0;
5216  (*row)->numintcols = -1;
5217  (*row)->validactivitylp = -1;
5218  (*row)->validpsactivitydomchg = -1;
5219  (*row)->validactivitybdsdomchg = -1;
5220  (*row)->nlpsaftercreation = 0L;
5221  (*row)->activeinlpcounter = 0L;
5222  (*row)->age = 0;
5223  (*row)->rank = 0;
5224  (*row)->obsoletenode = -1;
5225  (*row)->fromcutpool = FALSE;
5226  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5227  (*row)->lpcolssorted = TRUE;
5228  (*row)->nonlpcolssorted = (len <= 1);
5229  (*row)->delaysort = FALSE;
5230  (*row)->validminmaxidx = FALSE;
5231  (*row)->lhschanged = FALSE;
5232  (*row)->rhschanged = FALSE;
5233  (*row)->coefchanged = FALSE;
5234  (*row)->local = local;
5235  (*row)->modifiable = modifiable;
5236  (*row)->nlocks = 0;
5237  (*row)->origintype = origintype; /*lint !e641*/
5238  (*row)->removable = removable;
5239  (*row)->inglobalcutpool = FALSE;
5240  (*row)->storedsolvals = NULL;
5241 
5242  /* calculate row norms and min/maxidx, and check if row is sorted */
5243  rowCalcNorms(*row, set);
5244 
5245  /* capture the row */
5246  SCIProwCapture(*row);
5247 
5248  /* create event filter */
5249  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5250 
5251  /* capture origin constraint if available */
5252  if( origintype == SCIP_ROWORIGINTYPE_CONS )
5253  {
5254  SCIP_CONS* cons = (SCIP_CONS*) origin;
5255  assert(cons != NULL);
5256  SCIPconsCapture(cons);
5257  }
5258 
5259  return SCIP_OKAY;
5260 } /*lint !e715*/
5261 
5262 /** frees an LP row */
5264  SCIP_ROW** row, /**< pointer to LP row */
5265  BMS_BLKMEM* blkmem, /**< block memory */
5266  SCIP_SET* set, /**< global SCIP settings */
5267  SCIP_LP* lp /**< current LP data */
5268  )
5269 {
5270  assert(blkmem != NULL);
5271  assert(row != NULL);
5272  assert(*row != NULL);
5273  assert((*row)->nuses == 0);
5274  assert((*row)->lppos == -1);
5275  assert((*row)->eventfilter != NULL);
5276 
5277  /* release constraint that has been used for creating the row */
5278  if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5279  {
5280  SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5281  assert(cons != NULL);
5282  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5283  }
5284 
5285  /* remove column indices from corresponding rows */
5286  SCIP_CALL( rowUnlink(*row, set, lp) );
5287 
5288  /* free event filter */
5289  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5290 
5291  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5292  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5293  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5294  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5295  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5296  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5297  BMSfreeBlockMemory(blkmem, row);
5298 
5299  return SCIP_OKAY;
5300 }
5301 
5302 /** output row to file stream */
5304  SCIP_ROW* row, /**< LP row */
5305  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5306  FILE* file /**< output file (or NULL for standard output) */
5307  )
5308 {
5309  int i;
5310 
5311  assert(row != NULL);
5312 
5313  /* print row name */
5314  if( row->name != NULL && row->name[0] != '\0' )
5315  {
5316  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5317  }
5318 
5319  /* print left hand side */
5320  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5321 
5322  /* print coefficients */
5323  if( row->len == 0 )
5324  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5325  for( i = 0; i < row->len; ++i )
5326  {
5327  assert(row->cols[i] != NULL);
5328  assert(row->cols[i]->var != NULL);
5329  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5330  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5331  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5332  }
5333 
5334  /* print constant */
5335  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5336  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5337 
5338  /* print right hand side */
5339  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5340 }
5341 
5342 /** increases usage counter of LP row */
5344  SCIP_ROW* row /**< LP row */
5345  )
5346 {
5347  assert(row != NULL);
5348  assert(row->nuses >= 0);
5349  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5350 
5351  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5352  row->nuses++;
5353 }
5354 
5355 /** decreases usage counter of LP row, and frees memory if necessary */
5357  SCIP_ROW** row, /**< pointer to LP row */
5358  BMS_BLKMEM* blkmem, /**< block memory */
5359  SCIP_SET* set, /**< global SCIP settings */
5360  SCIP_LP* lp /**< current LP data */
5361  )
5362 {
5363  assert(blkmem != NULL);
5364  assert(row != NULL);
5365  assert(*row != NULL);
5366  assert((*row)->nuses >= 1);
5367  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5368 
5369  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5370  (*row)->nuses--;
5371  if( (*row)->nuses == 0 )
5372  {
5373  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5374  }
5375 
5376  *row = NULL;
5377 
5378  return SCIP_OKAY;
5379 }
5380 
5381 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5383  SCIP_ROW* row /**< LP row */
5384  )
5385 {
5386  assert(row != NULL);
5387 
5388  /* check, if row is modifiable */
5389  if( !row->modifiable )
5390  {
5391  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5392  row->nlocks++;
5393  }
5394 }
5395 
5396 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5398  SCIP_ROW* row /**< LP row */
5399  )
5400 {
5401  assert(row != NULL);
5402 
5403  /* check, if row is modifiable */
5404  if( !row->modifiable )
5405  {
5406  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5407  assert(row->nlocks > 0);
5408  row->nlocks--;
5409  }
5410 }
5411 
5412 /** adds a previously non existing coefficient to an LP row */
5414  SCIP_ROW* row, /**< LP row */
5415  BMS_BLKMEM* blkmem, /**< block memory */
5416  SCIP_SET* set, /**< global SCIP settings */
5417  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5418  SCIP_LP* lp, /**< current LP data */
5419  SCIP_COL* col, /**< LP column */
5420  SCIP_Real val /**< value of coefficient */
5421  )
5422 {
5423  assert(lp != NULL);
5424  assert(!lp->diving || row->lppos == -1);
5425 
5426  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5427 
5428  checkLinks(lp);
5429 
5430  return SCIP_OKAY;
5431 }
5432 
5433 /** deletes coefficient from row */
5435  SCIP_ROW* row, /**< row to be changed */
5436  BMS_BLKMEM* blkmem, /**< block memory */
5437  SCIP_SET* set, /**< global SCIP settings */
5438  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5439  SCIP_LP* lp, /**< current LP data */
5440  SCIP_COL* col /**< coefficient to be deleted */
5441  )
5442 {
5443  int pos;
5444 
5445  assert(row != NULL);
5446  assert(!row->delaysort);
5447  assert(lp != NULL);
5448  assert(!lp->diving || row->lppos == -1);
5449  assert(col != NULL);
5450  assert(col->var != NULL);
5451 
5452  /* search the position of the column in the row's col vector */
5453  pos = rowSearchCoef(row, col);
5454  if( pos == -1 )
5455  {
5456  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5457  return SCIP_INVALIDDATA;
5458  }
5459  assert(0 <= pos && pos < row->len);
5460  assert(row->cols[pos] == col);
5461  assert(row->cols_index[pos] == col->index);
5462 
5463  /* if column knows of the row, remove the row from the column's row vector */
5464  if( row->linkpos[pos] >= 0 )
5465  {
5466  assert(col->rows[row->linkpos[pos]] == row);
5467  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5468  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5469  }
5470 
5471  /* delete the column from the row's col vector */
5472  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5473 
5474  checkLinks(lp);
5475 
5476  return SCIP_OKAY;
5477 }
5478 
5479 /** changes or adds a coefficient to an LP row */
5481  SCIP_ROW* row, /**< LP row */
5482  BMS_BLKMEM* blkmem, /**< block memory */
5483  SCIP_SET* set, /**< global SCIP settings */
5484  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5485  SCIP_LP* lp, /**< current LP data */
5486  SCIP_COL* col, /**< LP column */
5487  SCIP_Real val /**< value of coefficient */
5488  )
5489 {
5490  int pos;
5491 
5492  assert(row != NULL);
5493  assert(!row->delaysort);
5494  assert(lp != NULL);
5495  assert(!lp->diving || row->lppos == -1);
5496  assert(col != NULL);
5497 
5498  /* search the position of the column in the row's col vector */
5499  pos = rowSearchCoef(row, col);
5500 
5501  /* check, if column already exists in the row's col vector */
5502  if( pos == -1 )
5503  {
5504  /* add previously not existing coefficient */
5505  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5506  }
5507  else
5508  {
5509  /* modify already existing coefficient */
5510  assert(0 <= pos && pos < row->len);
5511  assert(row->cols[pos] == col);
5512  assert(row->cols_index[pos] == col->index);
5513 
5514  /* if column knows of the row, change the corresponding coefficient in the column */
5515  if( row->linkpos[pos] >= 0 )
5516  {
5517  assert(col->rows[row->linkpos[pos]] == row);
5518  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5519  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5520  }
5521 
5522  /* change the coefficient in the row */
5523  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5524  }
5525 
5526  checkLinks(lp);
5527 
5528  return SCIP_OKAY;
5529 }
5530 
5531 /** increases value of an existing or non-existing coefficient in an LP row */
5533  SCIP_ROW* row, /**< LP row */
5534  BMS_BLKMEM* blkmem, /**< block memory */
5535  SCIP_SET* set, /**< global SCIP settings */
5536  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5537  SCIP_LP* lp, /**< current LP data */
5538  SCIP_COL* col, /**< LP column */
5539  SCIP_Real incval /**< value to add to the coefficient */
5540  )
5541 {
5542  int pos;
5543 
5544  assert(row != NULL);
5545  assert(lp != NULL);
5546  assert(!lp->diving || row->lppos == -1);
5547  assert(col != NULL);
5548 
5549  if( SCIPsetIsZero(set, incval) )
5550  return SCIP_OKAY;
5551 
5552  /* search the position of the column in the row's col vector */
5553  pos = rowSearchCoef(row, col);
5554 
5555  /* check, if column already exists in the row's col vector */
5556  if( pos == -1 )
5557  {
5558  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5559  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5560  }
5561  else
5562  {
5563  /* modify already existing coefficient */
5564  assert(0 <= pos && pos < row->len);
5565  assert(row->cols[pos] == col);
5566  assert(row->cols_index[pos] == col->index);
5567 
5568  /* if column knows of the row, change the corresponding coefficient in the column */
5569  if( row->linkpos[pos] >= 0 )
5570  {
5571  assert(col->rows[row->linkpos[pos]] == row);
5572  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5573  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5574  }
5575 
5576  /* change the coefficient in the row */
5577  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5578  }
5579 
5580  checkLinks(lp);
5581 
5582  /* invalid the activity */
5583  row->validactivitylp = -1;
5584 
5585  return SCIP_OKAY;
5586 }
5587 
5588 /** changes constant value of a row */
5590  SCIP_ROW* row, /**< LP row */
5591  BMS_BLKMEM* blkmem, /**< block memory */
5592  SCIP_SET* set, /**< global SCIP settings */
5593  SCIP_STAT* stat, /**< problem statistics */
5594  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5595  SCIP_LP* lp, /**< current LP data */
5596  SCIP_Real constant /**< new constant value */
5597  )
5598 {
5599  assert(row != NULL);
5600  assert(row->lhs <= row->rhs);
5601  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5602  assert(stat != NULL);
5603  assert(lp != NULL);
5604  assert(!lp->diving || row->lppos == -1);
5605 
5606  if( !SCIPsetIsEQ(set, constant, row->constant) )
5607  {
5608  SCIP_Real oldconstant;
5609 
5610  if( row->validpsactivitydomchg == stat->domchgcount )
5611  {
5612  assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
5613  row->pseudoactivity += constant - row->constant;
5614  }
5615  if( row->validactivitybdsdomchg == stat->domchgcount )
5616  {
5617  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
5618  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
5619  row->minactivity += constant - row->constant;
5620  row->maxactivity += constant - row->constant;
5621  }
5622 
5623  if( !SCIPsetIsInfinity(set, -row->lhs) )
5624  {
5625  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5626  }
5627  if( !SCIPsetIsInfinity(set, row->rhs) )
5628  {
5629  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5630  }
5631 
5632  oldconstant = row->constant;
5633 
5634  row->constant = constant;
5635 
5636  /* issue row constant changed event */
5637  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5638  }
5639 
5640  return SCIP_OKAY;
5641 }
5642 
5643 /** add constant value to a row */
5645  SCIP_ROW* row, /**< LP row */
5646  BMS_BLKMEM* blkmem, /**< block memory */
5647  SCIP_SET* set, /**< global SCIP settings */
5648  SCIP_STAT* stat, /**< problem statistics */
5649  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5650  SCIP_LP* lp, /**< current LP data */
5651  SCIP_Real addval /**< constant value to add to the row */
5652  )
5653 {
5654  assert(row != NULL);
5655  assert(row->lhs <= row->rhs);
5656  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5657  assert(stat != NULL);
5658  assert(lp != NULL);
5659  assert(!lp->diving || row->lppos == -1);
5660 
5661  if( !SCIPsetIsZero(set, addval) )
5662  {
5663  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5664  }
5665 
5666  return SCIP_OKAY;
5667 }
5668 
5669 /** changes left hand side of LP row */
5671  SCIP_ROW* row, /**< LP row */
5672  BMS_BLKMEM* blkmem, /**< block memory */
5673  SCIP_SET* set, /**< global SCIP settings */
5674  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5675  SCIP_LP* lp, /**< current LP data */
5676  SCIP_Real lhs /**< new left hand side */
5677  )
5678 {
5679  assert(row != NULL);
5680  assert(lp != NULL);
5681 
5682  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5683  {
5684  SCIP_Real oldlhs;
5685 
5686  oldlhs = row->lhs;
5687 
5688  row->lhs = lhs;
5689  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5690 
5691  if( !lp->diving )
5692  {
5693  /* issue row side changed event */
5694  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5695  }
5696  }
5697 
5698  return SCIP_OKAY;
5699 }
5700 
5701 /** changes right hand side of LP row */
5703  SCIP_ROW* row, /**< LP row */
5704  BMS_BLKMEM* blkmem, /**< block memory */
5705  SCIP_SET* set, /**< global SCIP settings */
5706  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5707  SCIP_LP* lp, /**< current LP data */
5708  SCIP_Real rhs /**< new right hand side */
5709  )
5710 {
5711  assert(row != NULL);
5712  assert(lp != NULL);
5713 
5714  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5715  {
5716  SCIP_Real oldrhs;
5717 
5718  oldrhs = row->rhs;
5719 
5720  row->rhs = rhs;
5721  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5722 
5723  if( !lp->diving )
5724  {
5725  /* issue row side changed event */
5726  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5727  }
5728  }
5729 
5730  return SCIP_OKAY;
5731 }
5732 
5733 /** changes the local flag of LP row */
5735  SCIP_ROW* row, /**< LP row */
5736  SCIP_Bool local /**< new value for local flag */
5737  )
5738 {
5739  assert(row != NULL);
5740 
5741  row->local = local;
5742 
5743  return SCIP_OKAY;
5744 }
5745 
5746 /** additional scalars that are tried in integrality scaling */
5747 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5748 static const int nscalars = 9;
5749 
5750 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5752  SCIP_ROW* row, /**< LP row */
5753  SCIP_SET* set, /**< global SCIP settings */
5754  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5755  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5756  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5757  SCIP_Real maxscale, /**< maximal allowed scalar */
5758  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5759  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5760  SCIP_Bool* success /**< stores whether returned value is valid */
5761  )
5762 {
5763 #ifndef NDEBUG
5764  SCIP_COL* col;
5765 #endif
5766  SCIP_Longint gcd;
5767  SCIP_Longint scm;
5768  SCIP_Longint nominator;
5769  SCIP_Longint denominator;
5770  SCIP_Real val;
5771  SCIP_Real absval;
5772  SCIP_Real minval;
5773  SCIP_Real scaleval;
5774  SCIP_Real twomultval;
5775  SCIP_Bool scalable;
5776  SCIP_Bool twomult;
5777  SCIP_Bool rational;
5778  int c;
5779  int s;
5780 
5781  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5782  assert(row != NULL);
5783  assert(row->len == 0 || row->cols != NULL);
5784  assert(row->len == 0 || row->cols_index != NULL);
5785  assert(row->len == 0 || row->vals != NULL);
5786  assert(maxdnom >= 1);
5787  assert(mindelta < 0.0);
5788  assert(maxdelta > 0.0);
5789  assert(success != NULL);
5790 
5791  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5792  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5793 
5794  if( intscalar != NULL )
5795  *intscalar = SCIP_INVALID;
5796  *success = FALSE;
5797 
5798  /* get minimal absolute non-zero value */
5799  minval = SCIP_REAL_MAX;
5800  for( c = 0; c < row->len; ++c )
5801  {
5802 #ifndef NDEBUG
5803  col = row->cols[c];
5804  assert(col != NULL);
5805  assert(col->var != NULL);
5806  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5807  assert(SCIPvarGetCol(col->var) == col);
5808 #endif
5809  val = row->vals[c];
5810  assert(!SCIPsetIsZero(set, val));
5811 
5812  if( val < mindelta || val > maxdelta )
5813  {
5814  absval = REALABS(val);
5815  minval = MIN(minval, absval);
5816  }
5817  }
5818  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5819  {
5820  /* all coefficients are zero (inside tolerances) */
5821  if( intscalar != NULL )
5822  *intscalar = 1.0;
5823  *success = TRUE;
5824  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5825 
5826  return SCIP_OKAY;
5827  }
5828  assert(minval > MIN(-mindelta, maxdelta));
5829  assert(SCIPsetIsPositive(set, minval));
5830  assert(!SCIPsetIsInfinity(set, minval));
5831 
5832  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5833  * and a power of 2
5834  */
5835  scaleval = 1.0/minval;
5836  scalable = (scaleval <= maxscale);
5837  for( c = 0; c < row->len && scalable; ++c )
5838  {
5839  /* don't look at continuous variables, if we don't have to */
5840  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5841  continue;
5842 
5843  /* check, if the coefficient can be scaled with a simple scalar */
5844  val = row->vals[c];
5845  absval = REALABS(val);
5846  while( scaleval <= maxscale
5847  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5848  {
5849  for( s = 0; s < nscalars; ++s )
5850  {
5851  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5852  {
5853  scaleval *= scalars[s];
5854  break;
5855  }
5856  }
5857  if( s >= nscalars )
5858  scaleval *= 2.0;
5859  }
5860  scalable = (scaleval <= maxscale);
5861  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5862  }
5863  if( scalable )
5864  {
5865  /* make row coefficients integral by dividing them by the smallest coefficient
5866  * (and multiplying them with a power of 2)
5867  */
5868  assert(scaleval <= maxscale);
5869  if( intscalar != NULL )
5870  *intscalar = scaleval;
5871  *success = TRUE;
5872  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5873 
5874  return SCIP_OKAY;
5875  }
5876 
5877  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5878  twomultval = 1.0;
5879  twomult = (twomultval <= maxscale);
5880  for( c = 0; c < row->len && twomult; ++c )
5881  {
5882  /* don't look at continuous variables, if we don't have to */
5883  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5884  continue;
5885 
5886  /* check, if the coefficient can be scaled with a simple scalar */
5887  val = row->vals[c];
5888  absval = REALABS(val);
5889  while( twomultval <= maxscale
5890  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5891  {
5892  for( s = 0; s < nscalars; ++s )
5893  {
5894  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5895  {
5896  twomultval *= scalars[s];
5897  break;
5898  }
5899  }
5900  if( s >= nscalars )
5901  twomultval *= 2.0;
5902  }
5903  twomult = (twomultval <= maxscale);
5904  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5905  val, twomultval, val*twomultval, twomult);
5906  }
5907  if( twomult )
5908  {
5909  /* make row coefficients integral by multiplying them with a power of 2 */
5910  assert(twomultval <= maxscale);
5911  if( intscalar != NULL )
5912  *intscalar = twomultval;
5913  *success = TRUE;
5914  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5915 
5916  return SCIP_OKAY;
5917  }
5918 
5919  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5920  * and the smallest common multiple of the denominators
5921  */
5922  gcd = 1;
5923  scm = 1;
5924  rational = (maxdnom > 1);
5925 
5926  /* first coefficient (to initialize gcd) */
5927  for( c = 0; c < row->len && rational; ++c )
5928  {
5929  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5930  {
5931  val = row->vals[c];
5932  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5933  if( rational && nominator != 0 )
5934  {
5935  assert(denominator > 0);
5936  gcd = ABS(nominator);
5937  scm = denominator;
5938  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5939  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5940  val, nominator, denominator, gcd, scm, rational);
5941  break;
5942  }
5943  }
5944  }
5945 
5946  /* remaining coefficients */
5947  for( ++c; c < row->len && rational; ++c )
5948  {
5949  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5950  {
5951  val = row->vals[c];
5952  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5953  if( rational && nominator != 0 )
5954  {
5955  assert(denominator > 0);
5956  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5957  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5958  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5959  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5960  val, nominator, denominator, gcd, scm, rational);
5961  }
5962  }
5963  }
5964 
5965  if( rational )
5966  {
5967  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5968  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5969  if( intscalar != NULL )
5970  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5971  *success = TRUE;
5972  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5973  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5974  }
5975  else
5976  {
5977  assert(!(*success));
5978  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5979  }
5980 
5981  return SCIP_OKAY;
5982 }
5983 
5984 /** tries to scale row, s.t. all coefficients become integral */
5986  SCIP_ROW* row, /**< LP row */
5987  BMS_BLKMEM* blkmem, /**< block memory */
5988  SCIP_SET* set, /**< global SCIP settings */
5989  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5990  SCIP_STAT* stat, /**< problem statistics */
5991  SCIP_LP* lp, /**< current LP data */
5992  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5993  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5994  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5995  SCIP_Real maxscale, /**< maximal value to scale row with */
5996  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5997  SCIP_Bool* success /**< stores whether row could be made rational */
5998  )
5999 {
6000  SCIP_Real intscalar;
6001 
6002  assert(success != NULL);
6003 
6004  /* calculate scalar to make coefficients integral */
6005  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
6006  &intscalar, success) );
6007 
6008  if( *success )
6009  {
6010  /* scale the row */
6011  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
6012  }
6013 
6014  return SCIP_OKAY;
6015 }
6016 
6017 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6018  * higher ones
6019  */
6021  SCIP_ROW* row /**< row to be sorted */
6022  )
6023 {
6024  assert(row != NULL);
6025 
6026  /* sort LP columns */
6027  rowSortLP(row);
6028 
6029  /* sort non-LP columns */
6030  rowSortNonLP(row);
6031 
6032 #ifdef SCIP_MORE_DEBUG
6033  /* check the sorting */
6034  {
6035  int c;
6036  if( !row->delaysort )
6037  {
6038  for( c = 1; c < row->nlpcols; ++c )
6039  assert(row->cols[c]->index >= row->cols[c-1]->index);
6040  for( c = row->nlpcols + 1; c < row->len; ++c )
6041  assert(row->cols[c]->index >= row->cols[c-1]->index);
6042  }
6043  }
6044 #endif
6045 }
6046 
6047 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6048  * zero entries from row
6049  * the row must not be linked to the columns; otherwise, we would need to update the columns as
6050  * well, which is too expensive
6051  */
6052 static
6054  SCIP_ROW* row, /**< row to be sorted */
6055  SCIP_SET* set /**< global SCIP settings */
6056  )
6057 {
6058  assert(row != NULL);
6059  assert(!row->delaysort);
6060  assert(row->nunlinked == row->len);
6061  assert(row->nlpcols == 0);
6062 
6063  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6064 
6065  /* do nothing on empty rows; if row is sorted, nothing has to be done */
6066  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6067  {
6068  SCIP_COL** cols;
6069  int* cols_index;
6070  SCIP_Real* vals;
6071  int s;
6072  int t;
6073 
6074  /* make sure, the row is sorted */
6075  SCIProwSort(row);
6076  assert(row->lpcolssorted);
6077  assert(row->nonlpcolssorted);
6078 
6079  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6080  cols = row->cols;
6081  cols_index = row->cols_index;
6082  vals = row->vals;
6083  assert(cols != NULL);
6084  assert(cols_index != NULL);
6085  assert(vals != NULL);
6086 
6087  t = 0;
6088  row->integral = TRUE;
6089  assert(!SCIPsetIsZero(set, vals[0]));
6090  assert(row->linkpos[0] == -1);
6091 
6092  for( s = 1; s < row->len; ++s )
6093  {
6094  assert(!SCIPsetIsZero(set, vals[s]));
6095  assert(row->linkpos[s] == -1);
6096 
6097  if( cols[s] == cols[t] )
6098  {
6099  /* merge entries with equal column */
6100  vals[t] += vals[s];
6101  }
6102  else
6103  {
6104  /* go to the next entry, overwriting current entry if coefficient is zero */
6105  if( !SCIPsetIsZero(set, vals[t]) )
6106  {
6107  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6108  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6109 
6110  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6111  t++;
6112  }
6113  cols[t] = cols[s];
6114  cols_index[t] = cols_index[s];
6115  vals[t] = vals[s];
6116  }
6117  }
6118  if( !SCIPsetIsZero(set, vals[t]) )
6119  {
6120  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6121  t++;
6122  }
6123  assert(s == row->len);
6124  assert(t <= row->len);
6125 
6126  row->len = t;
6127  row->nunlinked = t;
6128 
6129  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6130  if( t < s )
6131  rowCalcNorms(row, set);
6132  }
6133 
6134 #ifndef NDEBUG
6135  /* check for double entries */
6136  {
6137  int i;
6138  int j;
6139 
6140  for( i = 0; i < row->len; ++i )
6141  {
6142  assert(row->cols[i] != NULL);
6143  assert(row->cols[i]->index == row->cols_index[i]);
6144  for( j = i+1; j < row->len; ++j )
6145  assert(row->cols[i] != row->cols[j]);
6146  }
6147  }
6148 #endif
6149 }
6150 
6151 /** enables delaying of row sorting */
6153  SCIP_ROW* row /**< LP row */
6154  )
6155 {
6156  assert(row != NULL);
6157  assert(!row->delaysort);
6158 
6159  row->delaysort = TRUE;
6160 }
6161 
6162 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6164  SCIP_ROW* row, /**< LP row */
6165  SCIP_SET* set /**< global SCIP settings */
6166  )
6167 {
6168  assert(row != NULL);
6169  assert(row->delaysort);
6170 
6171  row->delaysort = FALSE;
6172  rowMerge(row, set);
6173 }
6174 
6175 /** recalculates the current activity of a row */
6177  SCIP_ROW* row, /**< LP row */
6178  SCIP_STAT* stat /**< problem statistics */
6179  )
6180 {
6181  SCIP_COL* col;
6182  int c;
6183 
6184  assert(row != NULL);
6185  assert(stat != NULL);
6186 
6187  row->activity = row->constant;
6188  for( c = 0; c < row->nlpcols; ++c )
6189  {
6190  col = row->cols[c];
6191  assert(col != NULL);
6192  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
6193  assert(col->lppos >= 0);
6194  assert(row->linkpos[c] >= 0);
6195  row->activity += row->vals[c] * col->primsol;
6196  }
6197 
6198  if( row->nunlinked > 0 )
6199  {
6200  for( c = row->nlpcols; c < row->len; ++c )
6201  {
6202  col = row->cols[c];
6203  assert(col != NULL);
6204  assert(col->lppos >= 0 || col->primsol == 0.0);
6205  assert(col->lppos == -1 || row->linkpos[c] == -1);
6206  if( col->lppos >= 0 )
6207  row->activity += row->vals[c] * col->primsol;
6208  }
6209  }
6210 #ifndef NDEBUG
6211  else
6212  {
6213  for( c = row->nlpcols; c < row->len; ++c )
6214  {
6215  col = row->cols[c];
6216  assert(col != NULL);
6217  assert(col->primsol == 0.0);
6218  assert(col->lppos == -1);
6219  assert(row->linkpos[c] >= 0);
6220  }
6221  }
6222 #endif
6223 
6224  row->validactivitylp = stat->lpcount;
6225 }
6226 
6227 /** returns the activity of a row in the current LP solution */
6229  SCIP_ROW* row, /**< LP row */
6230  SCIP_SET* set, /**< global SCIP settings */
6231  SCIP_STAT* stat, /**< problem statistics */
6232  SCIP_LP* lp /**< current LP data */
6233  )
6234 {
6235  SCIP_Real inf;
6236  SCIP_Real activity;
6237 
6238  assert(row != NULL);
6239  assert(stat != NULL);
6240  assert(lp != NULL);
6241  assert(row->validactivitylp <= stat->lpcount);
6242  assert(lp->validsollp == stat->lpcount);
6243 
6244  if( row->validactivitylp != stat->lpcount )
6245  SCIProwRecalcLPActivity(row, stat);
6246  assert(row->validactivitylp == stat->lpcount);
6247  assert(row->activity != SCIP_INVALID); /*lint !e777*/
6248 
6249  activity = row->activity;
6250  inf = SCIPsetInfinity(set);
6251  activity = MAX(activity, -inf);
6252  activity = MIN(activity, +inf);
6253 
6254  return activity;
6255 }
6256 
6257 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6259  SCIP_ROW* row, /**< LP row */
6260  SCIP_SET* set, /**< global SCIP settings */
6261  SCIP_STAT* stat, /**< problem statistics */
6262  SCIP_LP* lp /**< current LP data */
6263  )
6264 {
6265  SCIP_Real activity;
6266 
6267  assert(row != NULL);
6268 
6269  activity = SCIProwGetLPActivity(row, set, stat, lp);
6270 
6271  return MIN(row->rhs - activity, activity - row->lhs);
6272 }
6273 
6274 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6275  *
6276  * @todo Implement calculation of activities similar to LPs.
6277  */
6279  SCIP_ROW* row, /**< LP row */
6280  SCIP_SET* set, /**< global SCIP settings */
6281  SCIP_STAT* stat /**< problem statistics */
6282  )
6283 {
6284  SCIP_Real inf;
6285  SCIP_Real activity;
6286  SCIP_COL* col;
6287  int c;
6288 
6289  assert( row != NULL );
6290  assert( stat != NULL );
6291 
6292  activity = row->constant;
6293  for (c = 0; c < row->nlpcols; ++c)
6294  {
6295  col = row->cols[c];
6296  assert( col != NULL );
6297  assert( col->lppos >= 0 );
6298  assert( col->var != NULL );
6299  assert( row->linkpos[c] >= 0 );
6300  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6301  }
6302 
6303  if ( row->nunlinked > 0 )
6304  {
6305  for (c = row->nlpcols; c < row->len; ++c)
6306  {
6307  col = row->cols[c];
6308  assert( col != NULL );
6309  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6310  if ( col->lppos >= 0 )
6311  {
6312  assert( col->var != NULL );
6313  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6314  }
6315  }
6316  }
6317 #ifndef NDEBUG
6318  else
6319  {
6320  for (c = row->nlpcols; c < row->len; ++c)
6321  {
6322  col = row->cols[c];
6323  assert( col != NULL );
6324  assert( col->lppos == -1 );
6325  assert( row->linkpos[c] >= 0 );
6326  }
6327  }
6328 #endif
6329  inf = SCIPsetInfinity(set);
6330  activity = MAX(activity, -inf);
6331  activity = MIN(activity, +inf);
6332 
6333  return MIN(row->rhs - activity, activity - row->lhs);
6334 }
6335 
6336 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6337  *
6338  * @todo Implement calculation of activities similar to LPs.
6339  */
6341  SCIP_ROW* row, /**< LP row */
6342  SCIP_SET* set, /**< global SCIP settings */
6343  SCIP_STAT* stat /**< problem statistics */
6344  )
6345 {
6346  SCIP_Real inf;
6347  SCIP_Real activity;
6348  SCIP_COL* col;
6349  int c;
6350 
6351  assert( row != NULL );
6352  assert( stat != NULL );
6353 
6354  activity = row->constant;
6355  for (c = 0; c < row->nlpcols; ++c)
6356  {
6357  col = row->cols[c];
6358  assert( col != NULL );
6359  assert( col->lppos >= 0 );
6360  assert( col->var != NULL );
6361  assert( row->linkpos[c] >= 0 );
6362  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6363  }
6364 
6365  if ( row->nunlinked > 0 )
6366  {
6367  for (c = row->nlpcols; c < row->len; ++c)
6368  {
6369  col = row->cols[c];
6370  assert( col != NULL );
6371  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6372  if ( col->lppos >= 0 )
6373  {
6374  assert( col->var != NULL );
6375  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6376  }
6377  }
6378  }
6379 #ifndef NDEBUG
6380  else
6381  {
6382  for (c = row->nlpcols; c < row->len; ++c)
6383  {
6384  col = row->cols[c];
6385  assert( col != NULL );
6386  assert( col->lppos == -1 );
6387  assert( row->linkpos[c] >= 0 );
6388  }
6389  }
6390 #endif
6391  inf = SCIPsetInfinity(set);
6392  activity = MAX(activity, -inf);
6393  activity = MIN(activity, +inf);
6394 
6395  return MIN(row->rhs - activity, activity - row->lhs);
6396 }
6397 
6398 /** calculates the current pseudo activity of a row */
6400  SCIP_ROW* row, /**< row data */
6401  SCIP_STAT* stat /**< problem statistics */
6402  )
6403 {
6404  SCIP_COL* col;
6405  int i;
6406 
6407  assert(row != NULL);
6408  assert(stat != NULL);
6409 
6410  row->pseudoactivity = row->constant;
6411  for( i = 0; i < row->len; ++i )
6412  {
6413  col = row->cols[i];
6414  assert(col != NULL);
6415  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6416  assert(col->var != NULL);
6417  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6418 
6419  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6420  }
6421  row->validpsactivitydomchg = stat->domchgcount;
6422  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6423 }
6424 
6425 /** returns the pseudo activity of a row in the current pseudo solution */
6427  SCIP_ROW* row, /**< LP row */
6428  SCIP_SET* set, /**< global SCIP settings */
6429  SCIP_STAT* stat /**< problem statistics */
6430  )
6431 {
6432  SCIP_Real inf;
6433  SCIP_Real activity;
6434 
6435  assert(row != NULL);
6436  assert(stat != NULL);
6437  assert(row->validpsactivitydomchg <= stat->domchgcount);
6438 
6439  /* check, if pseudo activity has to be calculated */
6440  if( row->validpsactivitydomchg != stat->domchgcount )
6441  SCIProwRecalcPseudoActivity(row, stat);
6442  assert(row->validpsactivitydomchg == stat->domchgcount);
6443  assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
6444 
6445  activity = row->pseudoactivity;
6446  inf = SCIPsetInfinity(set);
6447  activity = MAX(activity, -inf);
6448  activity = MIN(activity, +inf);
6449 
6450  return activity;
6451 }
6452 
6453 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6455  SCIP_ROW* row, /**< LP row */
6456  SCIP_SET* set, /**< global SCIP settings */
6457  SCIP_STAT* stat /**< problem statistics */
6458  )
6459 {
6460  SCIP_Real pseudoactivity;
6461 
6462  assert(row != NULL);
6463 
6464  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6465 
6466  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6467 }
6468 
6469 /** returns the activity of a row for a given solution */
6471  SCIP_ROW* row, /**< LP row */
6472  SCIP_SET* set, /**< global SCIP settings */
6473  SCIP_STAT* stat, /**< problem statistics data */
6474  SCIP_SOL* sol /**< primal CIP solution */
6475  )
6476 {
6477  SCIP_COL* col;
6478  SCIP_Real inf;
6479  SCIP_Real activity;
6480  SCIP_Real solval;
6481  int i;
6482 
6483  assert(row != NULL);
6484 
6485  activity = row->constant;
6486  for( i = 0; i < row->len; ++i )
6487  {
6488  col = row->cols[i];
6489  assert(col != NULL);
6490  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6491  solval = SCIPsolGetVal(sol, set, stat, col->var);
6492  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6493  {
6494  if( SCIPsetIsInfinity(set, -row->lhs) )
6495  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6496  else if( SCIPsetIsInfinity(set, row->rhs) )
6497  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6498  else
6499  solval = (col->lb + col->ub)/2.0;
6500  }
6501  activity += row->vals[i] * solval;
6502  }
6503 
6504  inf = SCIPsetInfinity(set);
6505  activity = MAX(activity, -inf);
6506  activity = MIN(activity, +inf);
6507 
6508  return activity;
6509 }
6510 
6511 /** returns the feasibility of a row for the given solution */
6513  SCIP_ROW* row, /**< LP row */
6514  SCIP_SET* set, /**< global SCIP settings */
6515  SCIP_STAT* stat, /**< problem statistics data */
6516  SCIP_SOL* sol /**< primal CIP solution */
6517  )
6518 {
6519  SCIP_Real activity;
6520 
6521  assert(row != NULL);
6522 
6523  activity = SCIProwGetSolActivity(row, set, stat, sol);
6524 
6525  return MIN(row->rhs - activity, activity - row->lhs);
6526 }
6527 
6528 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6529 static
6531  SCIP_ROW* row, /**< row data */
6532  SCIP_SET* set, /**< global SCIP settings */
6533  SCIP_STAT* stat /**< problem statistics data */
6534  )
6535 {
6536  SCIP_COL* col;
6537  SCIP_Real val;
6538  SCIP_Bool mininfinite;
6539  SCIP_Bool maxinfinite;
6540  int i;
6541 
6542  assert(row != NULL);
6543  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6544  assert(stat != NULL);
6545 
6546  /* calculate activity bounds */
6547  mininfinite = FALSE;
6548  maxinfinite = FALSE;
6549  row->minactivity = row->constant;
6550  row->maxactivity = row->constant;
6551  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6552  {
6553  col = row->cols[i];
6554  assert(col != NULL);
6555  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6556  val = row->vals[i];
6557  if( val >= 0.0 )
6558  {
6559  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6560  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6561  if( !mininfinite )
6562  row->minactivity += val * col->lb;
6563  if( !maxinfinite )
6564  row->maxactivity += val * col->ub;
6565  }
6566  else
6567  {
6568  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6569  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6570  if( !mininfinite )
6571  row->minactivity += val * col->ub;
6572  if( !maxinfinite )
6573  row->maxactivity += val * col->lb;
6574  }
6575  }
6576 
6577  if( mininfinite )
6578  row->minactivity = -SCIPsetInfinity(set);
6579  if( maxinfinite )
6580  row->maxactivity = SCIPsetInfinity(set);
6581  row->validactivitybdsdomchg = stat->domchgcount;
6582 
6583 #ifndef NDEBUG
6584  {
6585  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6586 
6587  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6588  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6589  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6590  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6591  * tolerance as a proxy to account for the accumulation effect
6592  */
6593  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6594  || EPSISINT(row->minactivity - row->constant, inttol));
6595  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6596  || EPSISINT(row->maxactivity - row->constant, inttol));
6597  }
6598 #endif
6599 }
6600 
6601 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6603  SCIP_ROW* row, /**< LP row */
6604  SCIP_SET* set, /**< global SCIP settings */
6605  SCIP_STAT* stat /**< problem statistics data */
6606  )
6607 {
6608  assert(row != NULL);
6609  assert(stat != NULL);
6610  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6611 
6612  /* check, if activity bounds has to be calculated */
6613  if( row->validactivitybdsdomchg != stat->domchgcount )
6614  rowCalcActivityBounds(row, set, stat);
6615  assert(row->validactivitybdsdomchg == stat->domchgcount);
6616  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6617  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6618 
6619  return row->minactivity;
6620 }
6621 
6622 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6624  SCIP_ROW* row, /**< LP row */
6625  SCIP_SET* set, /**< global SCIP settings */
6626  SCIP_STAT* stat /**< problem statistics data */
6627  )
6628 {
6629  assert(row != NULL);
6630  assert(stat != NULL);
6631  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6632 
6633  /* check, if activity bounds has to be calculated */
6634  if( row->validactivitybdsdomchg != stat->domchgcount )
6635  rowCalcActivityBounds(row, set, stat);
6636  assert(row->validactivitybdsdomchg == stat->domchgcount);
6637  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6638  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6639 
6640  return row->maxactivity;
6641 }
6642 
6643 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6645  SCIP_ROW* row, /**< LP row */
6646  SCIP_SET* set, /**< global SCIP settings */
6647  SCIP_STAT* stat /**< problem statistics data */
6648  )
6649 {
6650  assert(row != NULL);
6651 
6652  if( row->modifiable )
6653  return FALSE;
6654  if( !SCIPsetIsInfinity(set, -row->lhs) )
6655  {
6656  SCIP_Real minactivity;
6657 
6658  minactivity = SCIProwGetMinActivity(row, set, stat);
6659  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6660  return FALSE;
6661  }
6662  if( !SCIPsetIsInfinity(set, row->rhs) )
6663  {
6664  SCIP_Real maxactivity;
6665 
6666  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6667  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6668  return FALSE;
6669  }
6670 
6671  return TRUE;
6672 }
6673 
6674 /** gets maximal absolute value of row vector coefficients */
6676  SCIP_ROW* row, /**< LP row */
6677  SCIP_SET* set /**< global SCIP settings */
6678  )
6679 {
6680  assert(row != NULL);
6681 
6682  if( row->nummaxval == 0 )
6683  rowCalcIdxsAndVals(row, set);
6684  assert(row->nummaxval > 0);
6685  assert(row->maxval >= 0.0 || row->len == 0);
6686 
6687  return row->maxval;
6688 }
6689 
6690 /** gets minimal absolute value of row vector's non-zero coefficients */
6692  SCIP_ROW* row, /**< LP row */
6693  SCIP_SET* set /**< global SCIP settings */
6694  )
6695 {
6696  assert(row != NULL);
6697 
6698  if( row->numminval == 0 )
6699  rowCalcIdxsAndVals(row, set);
6700  assert(row->numminval > 0);
6701  assert(row->minval >= 0.0 || row->len == 0);
6702 
6703  return row->minval;
6704 }
6705 
6706 /** gets maximal column index of row entries */
6708  SCIP_ROW* row, /**< LP row */
6709  SCIP_SET* set /**< global SCIP settings */
6710  )
6711 {
6712  assert(row != NULL);
6713 
6714  if( row->validminmaxidx == 0 )
6715  rowCalcIdxsAndVals(row, set);
6716  assert(row->maxidx >= 0 || row->len == 0);
6717  assert(row->validminmaxidx);
6718 
6719  return row->maxidx;
6720 }
6721 
6722 /** gets minimal column index of row entries */
6724  SCIP_ROW* row, /**< LP row */
6725  SCIP_SET* set /**< global SCIP settings */
6726  )
6727 {
6728  assert(row != NULL);
6729 
6730  if( row->validminmaxidx == 0 )
6731  rowCalcIdxsAndVals(row, set);
6732  assert(row->minidx >= 0 || row->len == 0);
6733  assert(row->validminmaxidx);
6734 
6735  return row->minidx;
6736 }
6737 
6738 /** gets number of integral columns in row */
6740  SCIP_ROW* row, /**< LP row */
6741  SCIP_SET* set /**< global SCIP settings */
6742  )
6743 {
6744  assert(row != NULL);
6745 
6746  if( row->numintcols == -1 )
6747  rowCalcIdxsAndVals(row, set);
6748 
6749  assert(row->numintcols <= row->len && row->numintcols >= 0);
6750 
6751  return row->numintcols;
6752 }
6753 
6754 /** returns row's cutoff distance in the direction of the given primal solution */
6756  SCIP_ROW* row, /**< LP row */
6757  SCIP_SET* set, /**< global SCIP settings */
6758  SCIP_STAT* stat, /**< problem statistics data */
6759  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6760  SCIP_LP* lp /**< current LP data */
6761  )
6762 {
6763  SCIP_Real solcutoffdist;
6764  int k;
6765 
6766  assert(sol != NULL);
6767 
6768  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6769  {
6770  SCIP_Real scale = 0.0;
6771 
6772  lp->validsoldirlp = stat->lpcount;
6773  lp->validsoldirsol = sol;
6774 
6776 
6777  for( k = 0; k < lp->ncols; ++k )
6778  {
6779  assert(lp->cols[k]->lppos == k);
6780  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6781  scale += SQR(lp->soldirection[k]);
6782  }
6783 
6784  if( scale > 0.0 )
6785  {
6786  scale = 1.0 / SQRT(scale);
6787 
6788  for( k = 0; k < lp->ncols; ++k )
6789  lp->soldirection[k] *= scale;
6790  }
6791  }
6792 
6793  solcutoffdist = 0.0;
6794  for( k = 0; k < row->nlpcols; ++k )
6795  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6796 
6797  for( k = row->nlpcols; k < row->len; ++k )
6798  {
6799  if( row->cols[k]->lppos >= 0 )
6800  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6801  }
6802 
6803  if( SCIPsetIsSumZero(set, solcutoffdist) )
6804  solcutoffdist = set->num_sumepsilon;
6805 
6806  solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
6807 
6808  return solcutoffdist;
6809 }
6810 
6811 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6813  SCIP_ROW* row, /**< LP row */
6814  SCIP_SET* set, /**< global SCIP settings */
6815  SCIP_STAT* stat, /**< problem statistics data */
6816  SCIP_LP* lp /**< current LP data */
6817  )
6818 {
6819  SCIP_Real norm;
6820  SCIP_Real feasibility;
6821  SCIP_Real eps;
6822 
6823  assert(set != NULL);
6824 
6825  switch( set->sepa_efficacynorm )
6826  {
6827  case 'e':
6828  norm = SCIProwGetNorm(row);
6829  break;
6830  case 'm':
6831  norm = SCIProwGetMaxval(row, set);
6832  break;
6833  case 's':
6834  norm = SCIProwGetSumNorm(row);
6835  break;
6836  case 'd':
6837  norm = (row->len == 0 ? 0.0 : 1.0);
6838  break;
6839  default:
6840  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6841  SCIPABORT();
6842  norm = 0.0; /*lint !e527*/
6843  }
6844 
6845  eps = SCIPsetSumepsilon(set);
6846  norm = MAX(norm, eps);
6847  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6848 
6849  return -feasibility / norm;
6850 }
6851 
6852 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6854  SCIP_ROW* row, /**< LP row */
6855  SCIP_SET* set, /**< global SCIP settings */
6856  SCIP_STAT* stat, /**< problem statistics data */
6857  SCIP_LP* lp, /**< current LP data */
6858  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6859  )
6860 {
6861  SCIP_Real efficacy;
6862 
6863  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6864 
6865  return SCIPsetIsEfficacious(set, root, efficacy);
6866 }
6867 
6868 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6870  SCIP_ROW* row, /**< LP row */
6871  SCIP_SET* set, /**< global SCIP settings */
6872  SCIP_STAT* stat, /**< problem statistics data */
6873  SCIP_SOL* sol /**< primal CIP solution */
6874  )
6875 {
6876  SCIP_Real norm;
6877  SCIP_Real feasibility;
6878  SCIP_Real eps;
6879 
6880  assert(set != NULL);
6881 
6882  switch( set->sepa_efficacynorm )
6883  {
6884  case 'e':
6885  norm = SCIProwGetNorm(row);
6886  break;
6887  case 'm':
6888  norm = SCIProwGetMaxval(row, set);
6889  break;
6890  case 's':
6891  norm = SCIProwGetSumNorm(row);
6892  break;
6893  case 'd':
6894  norm = (row->len == 0 ? 0.0 : 1.0);
6895  break;
6896  default:
6897  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6898  SCIPABORT();
6899  norm = 0.0; /*lint !e527*/
6900  }
6901 
6902  eps = SCIPsetSumepsilon(set);
6903  norm = MAX(norm, eps);
6904  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6905 
6906  return -feasibility / norm;
6907 }
6908 
6909 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6910  * efficacy
6911  */
6913  SCIP_ROW* row, /**< LP row */
6914  SCIP_SET* set, /**< global SCIP settings */
6915  SCIP_STAT* stat, /**< problem statistics data */
6916  SCIP_SOL* sol, /**< primal CIP solution */
6917  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6918  )
6919 {
6920  SCIP_Real efficacy;
6921 
6922  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6923 
6924  return SCIPsetIsEfficacious(set, root, efficacy);
6925 }
6926 
6927 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6929  SCIP_ROW* row, /**< LP row */
6930  SCIP_SET* set, /**< global SCIP settings */
6931  SCIP_STAT* stat /**< problem statistics data */
6932  )
6933 {
6934  SCIP_Real norm;
6935  SCIP_Real feasibility;
6936  SCIP_Real eps;
6937 
6938  assert(set != NULL);
6939 
6940  switch( set->sepa_efficacynorm )
6941  {
6942  case 'e':
6943  norm = SCIProwGetNorm(row);
6944  break;
6945  case 'm':
6946  norm = SCIProwGetMaxval(row, set);
6947  break;
6948  case 's':
6949  norm = SCIProwGetSumNorm(row);
6950  break;
6951  case 'd':
6952  norm = (row->len == 0 ? 0.0 : 1.0);
6953  break;
6954  default:
6955  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6956  SCIPABORT();
6957  norm = 0.0; /*lint !e527*/
6958  }
6959 
6960  eps = SCIPsetSumepsilon(set);
6961  norm = MAX(norm, eps);
6962  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6963 
6964  return -feasibility / norm;
6965 }
6966 
6967 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6969  SCIP_ROW* row, /**< LP row */
6970  SCIP_SET* set, /**< global SCIP settings */
6971  SCIP_STAT* stat /**< problem statistics data */
6972  )
6973 {
6974  SCIP_Real norm;
6975  SCIP_Real feasibility;
6976  SCIP_Real eps;
6977 
6978  assert(set != NULL);
6979 
6980  switch( set->sepa_efficacynorm )
6981  {
6982  case 'e':
6983  norm = SCIProwGetNorm(row);
6984  break;
6985  case 'm':
6986  norm = SCIProwGetMaxval(row, set);
6987  break;
6988  case 's':
6989  norm = SCIProwGetSumNorm(row);
6990  break;
6991  case 'd':
6992  norm = (row->len == 0 ? 0.0 : 1.0);
6993  break;
6994  default:
6995  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6996  SCIPABORT();
6997  norm = 0.0; /*lint !e527*/
6998  }
6999 
7000  eps = SCIPsetSumepsilon(set);
7001  norm = MAX(norm, eps);
7002  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
7003 
7004  return -feasibility / norm;
7005 }
7006 
7007 /** returns the scalar product of the coefficient vectors of the two given rows
7008  *
7009  * @note the scalar product is computed w.r.t. the current LP columns only
7010  * @todo also consider non-LP columns for the computation?
7011  */
7013  SCIP_ROW* row1, /**< first LP row */
7014  SCIP_ROW* row2 /**< second LP row */
7015  )
7016 {
7017  SCIP_Real scalarprod;
7018  int* row1colsidx;
7019  int* row2colsidx;
7020  int i1;
7021  int i2;
7022 
7023  assert(row1 != NULL);
7024  assert(row2 != NULL);
7025 
7026  /* Sort the column indices of both rows.
7027  *
7028  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7029  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7030  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7031  * for both or one of the non-LP columns for both.
7032  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7033  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7034  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7035  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7036  *
7037  * We distinguish the following cases:
7038  *
7039  * 1) both rows have no unlinked columns
7040  * -> we just check the LP partitions
7041  *
7042  * 2) exactly one row is completely unlinked, the other one is completely linked
7043  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7044  * (thus all common LP columns are regarded)
7045  *
7046  * 3) we have unlinked and LP columns in both rows
7047  * -> we need to compare four partitions at once
7048  *
7049  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7050  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7051  * other row
7052  *
7053  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7054  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7055  *
7056  * 5) both rows are completely unlinked
7057  * -> we need to compare two partitions: both complete rows
7058  */
7059  SCIProwSort(row1);
7060  assert(row1->lpcolssorted);
7061  assert(row1->nonlpcolssorted);
7062  SCIProwSort(row2);
7063  assert(row2->lpcolssorted);
7064  assert(row2->nonlpcolssorted);
7065 
7066  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7067  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7068 
7069  row1colsidx = row1->cols_index;
7070  row2colsidx = row2->cols_index;
7071 
7072 #ifndef NDEBUG
7073  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7074  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7075  {
7076  i1 = 0;
7077  i2 = row2->nlpcols;
7078  while( i1 < row1->nlpcols && i2 < row2->len )
7079  {
7080  assert(row1->cols[i1] != row2->cols[i2]);
7081  if( row1->cols[i1]->index < row2->cols[i2]->index )
7082  ++i1;
7083  else
7084  {
7085  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7086  ++i2;
7087  }
7088  }
7089  assert(i1 == row1->nlpcols || i2 == row2->len);
7090 
7091  i1 = row1->nlpcols;
7092  i2 = 0;
7093  while( i1 < row1->len && i2 < row2->nlpcols )
7094  {
7095  assert(row1->cols[i1] != row2->cols[i2]);
7096  if( row1->cols[i1]->index < row2->cols[i2]->index )
7097  ++i1;
7098  else
7099  {
7100  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7101  ++i2;
7102  }
7103  }
7104  assert(i1 == row1->len || i2 == row2->nlpcols);
7105  }
7106 #endif
7107 
7108  /* The "easy" cases 1) and 2) */
7109  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7110  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7111  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7112  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7113  {
7114  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7115  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7116 
7117  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7118  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7119  */
7120  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7121  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7122  scalarprod = 0.0;
7123 
7124  /* calculate the scalar product */
7125  while( i1 >= 0 && i2 >= 0 )
7126  {
7127  assert(row1->cols[i1]->index == row1colsidx[i1]);
7128  assert(row2->cols[i2]->index == row2colsidx[i2]);
7129  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7130  if( row1colsidx[i1] < row2colsidx[i2] )
7131  --i2;
7132  else if( row1colsidx[i1] > row2colsidx[i2] )
7133  --i1;
7134  else
7135  {
7136  scalarprod += row1->vals[i1] * row2->vals[i2];
7137  --i1;
7138  --i2;
7139  }
7140  }
7141  }
7142  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7143  else
7144  {
7145  SCIP_Bool lpcols;
7146  int ilp1;
7147  int inlp1;
7148  int ilp2;
7149  int inlp2;
7150  int end1;
7151  int end2;
7152 
7153  scalarprod = 0;
7154  ilp1 = 0;
7155  ilp2 = 0;
7156 
7157  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7158  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7159  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7160 
7161  /* handle the case of four partitions (case 3) until one partition is finished;
7162  * cases 4a), 4b), and 5) will fail the while-condition
7163  */
7164  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7165  {
7166  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7167  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7168  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7169  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7170  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7171  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7172  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7173  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7174 
7175  /* rows have the same linked LP columns */
7176  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7177  {
7178  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7179  ++ilp1;
7180  ++ilp2;
7181  }
7182  /* LP column of row1 is the same as unlinked column of row2 */
7183  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7184  {
7185  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7186  ++ilp1;
7187  ++inlp2;
7188  }
7189  /* unlinked column of row1 is the same as LP column of row2 */
7190  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7191  {
7192  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7193  ++inlp1;
7194  ++ilp2;
7195  }
7196  /* two unlinked LP columns are the same */
7197  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7198  {
7199  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7200  ++inlp1;
7201  ++inlp2;
7202  }
7203  /* increase smallest counter */
7204  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7205  {
7206  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7207  {
7208  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7209  ++ilp1;
7210  else
7211  ++ilp2;
7212  }
7213  else
7214  {
7215  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7216  ++ilp1;
7217  else
7218  ++inlp2;
7219  }
7220  }
7221  else
7222  {
7223  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7224  {
7225  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7226  ++inlp1;
7227  else
7228  ++ilp2;
7229  }
7230  else
7231  {
7232  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7233  ++inlp1;
7234  else
7235  ++inlp2;
7236  }
7237  }
7238  }
7239 
7240  /* One partition was completely handled, we just have to handle the three remaining partitions:
7241  * the remaining partition of this row and the two partitions of the other row.
7242  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7243  */
7244  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7245  {
7246  int tmpilp;
7247  int tmpinlp;
7248 
7249  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7250 
7251  SCIPswapPointers((void**) &row1, (void**) &row2);
7252  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7253  tmpilp = ilp1;
7254  tmpinlp = inlp1;
7255  ilp1 = ilp2;
7256  inlp1 = inlp2;
7257  ilp2 = tmpilp;
7258  inlp2 = tmpinlp;
7259  }
7260 
7261  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7262  * -> this merges cases 4a) and 4b)
7263  */
7264  if( ilp1 == row1->nlpcols )
7265  {
7266  i1 = inlp1;
7267  end1 = row1->len;
7268  lpcols = FALSE;
7269  }
7270  else
7271  {
7272  assert(inlp1 == row1->len);
7273 
7274  i1 = ilp1;
7275  end1 = row1->nlpcols;
7276  lpcols = TRUE;
7277  }
7278 
7279  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7280  * case 5) will fail the while-condition
7281  */
7282  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7283  {
7284  assert(row1->cols[i1]->index == row1colsidx[i1]);
7285  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7286  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7287  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7288  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7289 
7290  /* current column in row 1 is the same as the current LP column in row 2 */
7291  if( row1colsidx[i1] == row2colsidx[ilp2] )
7292  {
7293  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7294  ++i1;
7295  ++ilp2;
7296  }
7297  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7298  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7299  {
7300  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7301  ++i1;
7302  ++inlp2;
7303  }
7304  /* increase smallest counter */
7305  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7306  {
7307  if( row1colsidx[i1] < row2colsidx[ilp2] )
7308  ++i1;
7309  else
7310  ++ilp2;
7311  }
7312  else
7313  {
7314  if( row1colsidx[i1] < row2colsidx[inlp2] )
7315  ++i1;
7316  else
7317  ++inlp2;
7318  }
7319  }
7320 
7321  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7322  * the two rows
7323  */
7324  if( i1 < end1 )
7325  {
7326  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7327  if( ilp2 == row2->nlpcols )
7328  {
7329  i2 = inlp2;
7330  end2 = row2->len;
7331  lpcols = FALSE;
7332  }
7333  else
7334  {
7335  assert(inlp2 == row2->len);
7336 
7337  i2 = ilp2;
7338  end2 = row2->nlpcols;
7339  }
7340 
7341  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7342  while( i1 < end1 && i2 < end2 )
7343  {
7344  assert(row1->cols[i1]->index == row1colsidx[i1]);
7345  assert(row2->cols[i2]->index == row2colsidx[i2]);
7346  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7347 
7348  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7349  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7350  {
7351  scalarprod += row1->vals[i1] * row2->vals[i2];
7352  ++i1;
7353  ++i2;
7354  }
7355  /* increase smallest counter */
7356  else if( row1colsidx[i1] < row2colsidx[i2] )
7357  ++i1;
7358  else
7359  ++i2;
7360  }
7361  }
7362  }
7363 
7364  return scalarprod;
7365 }
7366 
7367 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7368 static
7370  SCIP_ROW* row1, /**< first LP row */
7371  SCIP_ROW* row2 /**< second LP row */
7372  )
7373 {
7374  int prod;
7375  int* row1colsidx;
7376  int* row2colsidx;
7377  int i1;
7378  int i2;
7379 
7380  assert(row1 != NULL);
7381  assert(row2 != NULL);
7382 
7383  /* Sort the column indices of both rows.
7384  *
7385  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7386  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7387  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7388  * for both or one of the non-LP columns for both.
7389  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7390  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7391  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7392  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7393  *
7394  * We distinguish the following cases:
7395  *
7396  * 1) both rows have no unlinked columns
7397  * -> we just check the LP partitions
7398  *
7399  * 2) exactly one row is completely unlinked, the other one is completely linked
7400  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7401  * (thus all common LP columns are regarded)
7402  *
7403  * 3) we have unlinked and LP columns in both rows
7404  * -> we need to compare four partitions at once
7405  *
7406  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7407  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7408  * other row
7409  *
7410  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7411  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7412  *
7413  * 5) both rows are completely unlinked
7414  * -> we need to compare two partitions: both complete rows
7415  */
7416  SCIProwSort(row1);
7417  assert(row1->lpcolssorted);
7418  assert(row1->nonlpcolssorted);
7419  SCIProwSort(row2);
7420  assert(row2->lpcolssorted);
7421  assert(row2->nonlpcolssorted);
7422 
7423  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7424  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7425 
7426  row1colsidx = row1->cols_index;
7427  row2colsidx = row2->cols_index;
7428 
7429 #ifndef NDEBUG
7430  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7431  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7432  {
7433  i1 = 0;
7434  i2 = row2->nlpcols;
7435  while( i1 < row1->nlpcols && i2 < row2->len )
7436  {
7437  assert(row1->cols[i1] != row2->cols[i2]);
7438  if( row1->cols[i1]->index < row2->cols[i2]->index )
7439  ++i1;
7440  else
7441  {
7442  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7443  ++i2;
7444  }
7445  }
7446  assert(i1 == row1->nlpcols || i2 == row2->len);
7447 
7448  i1 = row1->nlpcols;
7449  i2 = 0;
7450  while( i1 < row1->len && i2 < row2->nlpcols )
7451  {
7452  assert(row1->cols[i1] != row2->cols[i2]);
7453  if( row1->cols[i1]->index < row2->cols[i2]->index )
7454  ++i1;
7455  else
7456  {
7457  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7458  ++i2;
7459  }
7460  }
7461  assert(i1 == row1->len || i2 == row2->nlpcols);
7462  }
7463 #endif
7464 
7465  /* The "easy" cases 1) and 2) */
7466  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7467  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7468  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7469  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7470  {
7471  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7472  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7473 
7474  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7475  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7476  */
7477  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7478  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7479  prod = 0;
7480 
7481  /* calculate the scalar product */
7482  while( i1 >= 0 && i2 >= 0 )
7483  {
7484  assert(row1->cols[i1]->index == row1colsidx[i1]);
7485  assert(row2->cols[i2]->index == row2colsidx[i2]);
7486  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7487  if( row1colsidx[i1] < row2colsidx[i2] )
7488  --i2;
7489  else if( row1colsidx[i1] > row2colsidx[i2] )
7490  --i1;
7491  else
7492  {
7493  ++prod;
7494  --i1;
7495  --i2;
7496  }
7497  }
7498  }
7499  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7500  else
7501  {
7502  SCIP_Bool lpcols;
7503  int ilp1;
7504  int inlp1;
7505  int ilp2;
7506  int inlp2;
7507  int end1;
7508  int end2;
7509 
7510  prod = 0;
7511  ilp1 = 0;
7512  ilp2 = 0;
7513 
7514  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7515  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7516  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7517 
7518  /* handle the case of four partitions (case 3) until one partition is finished;
7519  * cases 4a), 4b), and 5) will fail the while-condition
7520  */
7521  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7522  {
7523  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7524  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7525  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7526  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7527  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7528  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7529  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7530  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7531 
7532  /* rows have the same linked LP columns */
7533  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7534  {
7535  ++prod;
7536  ++ilp1;
7537  ++ilp2;
7538  }
7539  /* LP column of row1 is the same as unlinked column of row2 */
7540  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7541  {
7542  ++prod;
7543  ++ilp1;
7544  ++inlp2;
7545  }
7546  /* unlinked column of row1 is the same as LP column of row2 */
7547  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7548  {
7549  ++prod;
7550  ++inlp1;
7551  ++ilp2;
7552  }
7553  /* two unlinked LP columns are the same */
7554  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7555  {
7556  ++prod;
7557  ++inlp1;
7558  ++inlp2;
7559  }
7560  /* increase smallest counter */
7561  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7562  {
7563  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7564  {
7565  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7566  ++ilp1;
7567  else
7568  ++ilp2;
7569  }
7570  else
7571  {
7572  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7573  ++ilp1;
7574  else
7575  ++inlp2;
7576  }
7577  }
7578  else
7579  {
7580  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7581  {
7582  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7583  ++inlp1;
7584  else
7585  ++ilp2;
7586  }
7587  else
7588  {
7589  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7590  ++inlp1;
7591  else
7592  ++inlp2;
7593  }
7594  }
7595  }
7596 
7597  /* One partition was completely handled, we just have to handle the three remaining partitions:
7598  * the remaining partition of this row and the two partitions of the other row.
7599  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7600  */
7601  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7602  {
7603  int tmpilp;
7604  int tmpinlp;
7605 
7606  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7607 
7608  SCIPswapPointers((void**) &row1, (void**) &row2);
7609  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7610  tmpilp = ilp1;
7611  tmpinlp = inlp1;
7612  ilp1 = ilp2;
7613  inlp1 = inlp2;
7614  ilp2 = tmpilp;
7615  inlp2 = tmpinlp;
7616  }
7617 
7618  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7619  * -> this merges cases 4a) and 4b)
7620  */
7621  if( ilp1 == row1->nlpcols )
7622  {
7623  i1 = inlp1;
7624  end1 = row1->len;
7625  lpcols = FALSE;
7626  }
7627  else
7628  {
7629  assert(inlp1 == row1->len);
7630 
7631  i1 = ilp1;
7632  end1 = row1->nlpcols;
7633  lpcols = TRUE;
7634  }
7635 
7636  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7637  * case 5) will fail the while-condition
7638  */
7639  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7640  {
7641  assert(row1->cols[i1]->index == row1colsidx[i1]);
7642  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7643  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7644  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7645  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7646 
7647  /* current column in row 1 is the same as the current LP column in row 2 */
7648  if( row1colsidx[i1] == row2colsidx[ilp2] )
7649  {
7650  ++prod;
7651  ++i1;
7652  ++ilp2;
7653  }
7654  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7655  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7656  {
7657  ++prod;
7658  ++i1;
7659  ++inlp2;
7660  }
7661  /* increase smallest counter */
7662  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7663  {
7664  if( row1colsidx[i1] < row2colsidx[ilp2] )
7665  ++i1;
7666  else
7667  ++ilp2;
7668  }
7669  else
7670  {
7671  if( row1colsidx[i1] < row2colsidx[inlp2] )
7672  ++i1;
7673  else
7674  ++inlp2;
7675  }
7676  }
7677 
7678  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7679  * the two rows
7680  */
7681  if( i1 < end1 )
7682  {
7683  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7684  if( ilp2 == row2->nlpcols )
7685  {
7686  i2 = inlp2;
7687  end2 = row2->len;
7688  lpcols = FALSE;
7689  }
7690  else
7691  {
7692  assert(inlp2 == row2->len);
7693 
7694  i2 = ilp2;
7695  end2 = row2->nlpcols;
7696  }
7697 
7698  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7699  while( i1 < end1 && i2 < end2 )
7700  {
7701  assert(row1->cols[i1]->index == row1colsidx[i1]);
7702  assert(row2->cols[i2]->index == row2colsidx[i2]);
7703  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7704 
7705  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7706  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7707  {
7708  ++prod;
7709  ++i1;
7710  ++i2;
7711  }
7712  /* increase smallest counter */
7713  else if( row1colsidx[i1] < row2colsidx[i2] )
7714  ++i1;
7715  else
7716  ++i2;
7717  }
7718  }
7719  }
7720 
7721  return prod;
7722 }
7723 
7724 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7725  * p = |v*w|/(|v|*|w|);
7726  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7727  */
7729  SCIP_ROW* row1, /**< first LP row */
7730  SCIP_ROW* row2, /**< second LP row */
7731  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7732  )
7733 {
7734  SCIP_Real parallelism;
7735  SCIP_Real scalarprod;
7736 
7737  switch( orthofunc )
7738  {
7739  case 'e':
7740  scalarprod = SCIProwGetScalarProduct(row1, row2);
7741  if( scalarprod == 0.0 )
7742  {
7743  parallelism = 0.0;
7744  break;
7745  }
7746 
7747  if( SCIProwGetNorm(row1) == 0.0 )
7748  {
7749  /* In theory, this should not happen if the scalarproduct is not zero
7750  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7751  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7752  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7753  */
7754  int i;
7755  for( i = 0; i < row1->len; ++i )
7756  if( row1->cols[i]->lppos >= 0 )
7757  row1->sqrnorm += SQR(row1->vals[i]);
7758  assert(SCIProwGetNorm(row1) != 0.0);
7759  }
7760 
7761  if( SCIProwGetNorm(row2) == 0.0 )
7762  {
7763  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7764  int i;
7765  for( i = 0; i < row2->len; ++i )
7766  if( row2->cols[i]->lppos >= 0 )
7767  row2->sqrnorm += SQR(row2->vals[i]);
7768  assert(SCIProwGetNorm(row2) != 0.0);
7769  }
7770 
7771  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7772  break;
7773 
7774  case 'd':
7775  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7776  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7777  break;
7778 
7779  default:
7780  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7781  SCIPABORT();
7782  parallelism = 0.0; /*lint !e527*/
7783  }
7784 
7785  return parallelism;
7786 }
7787 
7788 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7789  * o = 1 - |v*w|/(|v|*|w|);
7790  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7791  */
7793  SCIP_ROW* row1, /**< first LP row */
7794  SCIP_ROW* row2, /**< second LP row */
7795  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7796  )
7797 {
7798  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7799 }
7800 
7801 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7802  * function, if the value is 0, it is orthogonal to the objective function
7803  */
7805  SCIP_ROW* row, /**< LP row */
7806  SCIP_SET* set, /**< global SCIP settings */
7807  SCIP_LP* lp /**< current LP data */
7808  )
7809 {
7810  SCIP_Real prod;
7811  SCIP_Real parallelism;
7812 
7813  assert(row != NULL);
7814  assert(lp != NULL);
7815 
7816  if( lp->objsqrnormunreliable )
7817  SCIPlpRecalculateObjSqrNorm(set, lp);
7818 
7819  assert(!lp->objsqrnormunreliable);
7820  assert(lp->objsqrnorm >= 0.0);
7821 
7822  checkRowSqrnorm(row);
7823  checkRowObjprod(row);
7824 
7825  prod = row->sqrnorm * lp->objsqrnorm;
7826 
7827  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7828  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7829  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7830  parallelism = MIN(parallelism, 1.0);
7831  parallelism = MAX(parallelism, 0.0);
7832 
7833  return parallelism;
7834 }
7835 
7836 /** includes event handler with given data in row's event filter */
7838  SCIP_ROW* row, /**< row */
7839  BMS_BLKMEM* blkmem, /**< block memory */
7840  SCIP_SET* set, /**< global SCIP settings */
7841  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7842  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7843  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7844  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7845  )
7846 {
7847  assert(row != NULL);
7848  assert(row->eventfilter != NULL);
7849  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7850  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7851 
7852  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7853  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7854 
7855  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7856 
7857  return SCIP_OKAY;
7858 }
7859 
7860 /** deletes event handler with given data from row's event filter */
7862  SCIP_ROW* row, /**< row */
7863  BMS_BLKMEM* blkmem, /**< block memory */
7864  SCIP_SET* set, /**< global SCIP settings */
7865  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7866  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7867  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7868  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7869  )
7870 {
7871  assert(row != NULL);
7872  assert(row->eventfilter != NULL);
7873 
7874  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7875 
7876  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7877 
7878  return SCIP_OKAY;
7879 }
7880 
7881 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7883  SCIP_ROW* row, /**< LP row */
7884  SCIP_STAT* stat /**< problem statistics */
7885  )
7886 {
7887  assert(row != NULL);
7888  assert(stat != NULL);
7889  assert(stat->nnodes > 0);
7890 
7891  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7892  row->obsoletenode = stat->nnodes;
7893 }
7894 
7895 /*
7896  * LP solver data update
7897  */
7898 
7899 /** resets column data to represent a column not in the LP solver */
7900 static
7902  SCIP_COL* col /**< column to be marked deleted */
7903  )
7904 {
7905  assert(col != NULL);
7906 
7907  col->lpipos = -1;
7908  col->primsol = 0.0;
7909  col->redcost = SCIP_INVALID;
7910  col->farkascoef = SCIP_INVALID;
7911  col->sbdown = SCIP_INVALID;
7912  col->sbup = SCIP_INVALID;
7913  col->sbdownvalid = FALSE;
7914  col->sbupvalid = FALSE;
7915  col->validredcostlp = -1;
7916  col->validfarkaslp = -1;
7917  col->sbitlim = -1;
7918  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7919 }
7920 
7921 /** applies all cached column removals to the LP solver */
7922 static
7924  SCIP_LP* lp /**< current LP data */
7925  )
7926 {
7927  assert(lp != NULL);
7928  assert(lp->lpifirstchgcol <= lp->nlpicols);
7929  assert(lp->lpifirstchgcol <= lp->ncols);
7930 
7931  /* find the first column to change */
7932  while( lp->lpifirstchgcol < lp->nlpicols
7933  && lp->lpifirstchgcol < lp->ncols
7934  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7935  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7936  {
7937  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7938  lp->lpifirstchgcol++;
7939  }
7940 
7941  /* shrink LP to the part which didn't change */
7942  if( lp->lpifirstchgcol < lp->nlpicols )
7943  {
7944  int i;
7945 
7946  assert(!lp->diving);
7947  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7948  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7949  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7950  {
7951  markColDeleted(lp->lpicols[i]);
7952  }
7953  lp->nlpicols = lp->lpifirstchgcol;
7954  lp->flushdeletedcols = TRUE;
7955  lp->updateintegrality = TRUE;
7956 
7957  /* mark the LP unsolved */
7958  lp->solved = FALSE;
7959  lp->primalfeasible = FALSE;
7960  lp->primalchecked = FALSE;
7961  lp->lpobjval = SCIP_INVALID;
7963  }
7964  assert(lp->nlpicols == lp->lpifirstchgcol);
7965 
7966  return SCIP_OKAY;
7967 }
7968 
7969 /** computes for the given column the lower and upper bound that should be flushed into the LP
7970  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7971  * the bounds are explicitly added to the LP in any case
7972  */
7973 static
7975  SCIP_LP* lp, /**< current LP data */
7976  SCIP_SET* set, /**< global SCIP settings */
7977  SCIP_COL* col, /**< column to compute bounds for */
7978  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7979  SCIP_Real* lb, /**< pointer to store the new lower bound */
7980  SCIP_Real* ub /**< pointer to store the new upper bound */
7981  )
7982 {
7983  assert(lp != NULL);
7984  assert(set != NULL);
7985  assert(col != NULL);
7986  assert(lb != NULL);
7987  assert(ub != NULL);
7988 
7989  /* get the correct new lower bound:
7990  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7991  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7992  */
7993  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7994  (*lb) = -lpiinf;
7995  else
7996  (*lb) = col->lb;
7997  /* get the correct new upper bound:
7998  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7999  * if we are in diving mode, ignore lazy bounds and always take the upper bound
8000  */
8001  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
8002  (*ub) = lpiinf;
8003  else
8004  (*ub) = col->ub;
8005 }
8006 
8007 /** applies all cached column additions to the LP solver */
8008 static
8010  SCIP_LP* lp, /**< current LP data */
8011  BMS_BLKMEM* blkmem, /**< block memory */
8012  SCIP_SET* set, /**< global SCIP settings */
8013  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8014  )
8015 {
8016  SCIP_Real* obj;
8017  SCIP_Real* lb;
8018  SCIP_Real* ub;
8019  int* beg;
8020  int* ind;
8021  SCIP_Real* val;
8022  char** name;
8023  SCIP_COL* col;
8024  SCIP_Real lpiinf;
8025  int c;
8026  int pos;
8027  int nnonz;
8028  int naddcols;
8029  int naddcoefs;
8030  int i;
8031  int lpipos;
8032 
8033  assert(lp != NULL);
8034  assert(lp->lpifirstchgcol == lp->nlpicols);
8035  assert(blkmem != NULL);
8036  assert(set != NULL);
8037 
8038  /* if there are no columns to add, we are ready */
8039  if( lp->ncols == lp->nlpicols )
8040  return SCIP_OKAY;
8041 
8042  /* add the additional columns */
8043  assert(!lp->diving);
8044  assert(lp->ncols > lp->nlpicols);
8045  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8046 
8047  /* get the solver's infinity value */
8048  lpiinf = SCIPlpiInfinity(lp->lpi);
8049 
8050  /* count the (maximal) number of added coefficients, calculate the number of added columns */
8051  naddcols = lp->ncols - lp->nlpicols;
8052  naddcoefs = 0;
8053  for( c = lp->nlpicols; c < lp->ncols; ++c )
8054  naddcoefs += lp->cols[c]->len;
8055  assert(naddcols > 0);
8056 
8057  /* get temporary memory for changes */
8058  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8059  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8060  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8061  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8062  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8063  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8064  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8065 
8066  /* fill temporary memory with column data */
8067  nnonz = 0;
8068  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8069  {
8070  col = lp->cols[c];
8071  assert(col != NULL);
8072  assert(col->var != NULL);
8073  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8074  assert(SCIPvarGetCol(col->var) == col);
8075  assert(col->lppos == c);
8076  assert(nnonz + col->nlprows <= naddcoefs);
8077 
8078  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8079  debugColPrint(set, col);
8080 
8081  /* Because the column becomes a member of the LP solver, it now can take values
8082  * different from zero. That means, we have to include the column in the corresponding
8083  * row vectors.
8084  */
8085  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8086 
8087  lp->lpicols[c] = col;
8088  col->lpipos = c;
8089  col->primsol = SCIP_INVALID;
8090  col->redcost = SCIP_INVALID;
8091  col->farkascoef = SCIP_INVALID;
8092  col->sbdown = SCIP_INVALID;
8093  col->sbup = SCIP_INVALID;
8094  col->sbdownvalid = FALSE;
8095  col->sbupvalid = FALSE;
8096  col->validredcostlp = -1;
8097  col->validfarkaslp = -1;
8098  col->sbitlim = -1;
8099  col->objchanged = FALSE;
8100  col->lbchanged = FALSE;
8101  col->ubchanged = FALSE;
8102  col->coefchanged = FALSE;
8103  obj[pos] = col->obj;
8104 
8105  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8106  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8107 
8108  beg[pos] = nnonz;
8109  name[pos] = (char*)SCIPvarGetName(col->var);
8110 
8111  col->flushedobj = obj[pos];
8112  col->flushedlb = lb[pos];
8113  col->flushedub = ub[pos];
8114 
8115  for( i = 0; i < col->nlprows; ++i )
8116  {
8117  assert(col->rows[i] != NULL);
8118  lpipos = col->rows[i]->lpipos;
8119  if( lpipos >= 0 )
8120  {
8121  assert(lpipos < lp->nrows);
8122  assert(nnonz < naddcoefs);
8123  ind[nnonz] = lpipos;
8124  val[nnonz] = col->vals[i];
8125  nnonz++;
8126  }
8127  }
8128 #ifndef NDEBUG
8129  for( i = col->nlprows; i < col->len; ++i )
8130  {
8131  assert(col->rows[i] != NULL);
8132  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8133  }
8134 #endif
8135  }
8136 
8137  /* call LP interface */
8138  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8139  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8140  lp->nlpicols = lp->ncols;
8141  lp->lpifirstchgcol = lp->nlpicols;
8142 
8143  /* free temporary memory */
8144  SCIPsetFreeBufferArray(set, &name);
8145  SCIPsetFreeBufferArray(set, &val);
8146  SCIPsetFreeBufferArray(set, &ind);
8147  SCIPsetFreeBufferArray(set, &beg);
8148  SCIPsetFreeBufferArray(set, &ub);
8149  SCIPsetFreeBufferArray(set, &lb);
8150  SCIPsetFreeBufferArray(set, &obj);
8151 
8152  lp->flushaddedcols = TRUE;
8153  lp->updateintegrality = TRUE;
8154 
8155  /* mark the LP unsolved */
8156  lp->solved = FALSE;
8157  lp->dualfeasible = FALSE;
8158  lp->dualchecked = FALSE;
8159  lp->lpobjval = SCIP_INVALID;
8161 
8162  return SCIP_OKAY;
8163 }
8164 
8165 /** resets row data to represent a row not in the LP solver */
8166 static
8168  SCIP_ROW* row /**< row to be marked deleted */
8169  )
8170 {
8171  assert(row != NULL);
8172 
8173  row->lpipos = -1;
8174  row->dualsol = 0.0;
8175  row->activity = SCIP_INVALID;
8176  row->dualfarkas = 0.0;
8177  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8178  row->validactivitylp = -1;
8179 }
8180 
8181 /** applies all cached row removals to the LP solver */
8182 static
8184  SCIP_LP* lp, /**< current LP data */
8185  BMS_BLKMEM* blkmem, /**< block memory */
8186  SCIP_SET* set /**< global SCIP settings */
8187  )
8188 {
8189  assert(lp != NULL);
8190  assert(lp->lpifirstchgrow <= lp->nlpirows);
8191  assert(lp->lpifirstchgrow <= lp->nrows);
8192 
8193  /* find the first row to change */
8194  while( lp->lpifirstchgrow < lp->nlpirows
8195  && lp->lpifirstchgrow < lp->nrows
8196  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8197  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8198  {
8199  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8200  lp->lpifirstchgrow++;
8201  }
8202 
8203  /* shrink LP to the part which didn't change */
8204  if( lp->lpifirstchgrow < lp->nlpirows )
8205  {
8206  int i;
8207 
8208  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8209  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8210  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8211  {
8212  markRowDeleted(lp->lpirows[i]);
8213  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8214  }
8215  lp->nlpirows = lp->lpifirstchgrow;
8216  lp->flushdeletedrows = TRUE;
8217 
8218  /* mark the LP unsolved */
8219  lp->solved = FALSE;
8220  lp->dualfeasible = FALSE;
8221  lp->dualchecked = FALSE;
8222  lp->lpobjval = SCIP_INVALID;
8224  }
8225  assert(lp->nlpirows == lp->lpifirstchgrow);
8226 
8227  return SCIP_OKAY;
8228 }
8229 
8230 /** applies all cached row additions and removals to the LP solver */
8231 static
8233  SCIP_LP* lp, /**< current LP data */
8234  BMS_BLKMEM* blkmem, /**< block memory */
8235  SCIP_SET* set, /**< global SCIP settings */
8236  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8237  )
8238 {
8239  SCIP_Real* lhs;
8240  SCIP_Real* rhs;
8241  int* beg;
8242  int* ind;
8243  SCIP_Real* val;
8244  char** name;
8245  SCIP_ROW* row;
8246  SCIP_Real lpiinf;
8247  int r;
8248  int pos;
8249  int nnonz;
8250  int naddrows;
8251  int naddcoefs;
8252  int i;
8253  int lpipos;
8254 
8255  assert(lp != NULL);
8256  assert(lp->lpifirstchgrow == lp->nlpirows);
8257  assert(blkmem != NULL);
8258 
8259  /* if there are no rows to add, we are ready */
8260  if( lp->nrows == lp->nlpirows )
8261  return SCIP_OKAY;
8262 
8263  /* add the additional rows */
8264  assert(lp->nrows > lp->nlpirows);
8265  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8266 
8267  /* get the solver's infinity value */
8268  lpiinf = SCIPlpiInfinity(lp->lpi);
8269 
8270  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8271  naddrows = lp->nrows - lp->nlpirows;
8272  naddcoefs = 0;
8273  for( r = lp->nlpirows; r < lp->nrows; ++r )
8274  naddcoefs += lp->rows[r]->len;
8275  assert(naddrows > 0);
8276 
8277  /* get temporary memory for changes */
8278  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8279  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8280  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8281  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8282  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8283  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8284 
8285  /* fill temporary memory with row data */
8286  nnonz = 0;
8287  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8288  {
8289  row = lp->rows[r];
8290  assert(row != NULL);
8291  assert(row->lppos == r);
8292  assert(nnonz + row->nlpcols <= naddcoefs);
8293 
8294  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8295  debugRowPrint(set, row);
8296 
8297  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8298  * different from zero. That means, we have to include the row in the corresponding
8299  * column vectors.
8300  */
8301  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8302 
8303  SCIProwCapture(row);
8304  lp->lpirows[r] = row;
8305  row->lpipos = r;
8306  row->dualsol = SCIP_INVALID;
8307  row->activity = SCIP_INVALID;
8308  row->dualfarkas = SCIP_INVALID;
8309  row->validactivitylp = -1;
8310  row->lhschanged = FALSE;
8311  row->rhschanged = FALSE;
8312  row->coefchanged = FALSE;
8313  if( SCIPsetIsInfinity(set, -row->lhs) )
8314  lhs[pos] = -lpiinf;
8315  else
8316  lhs[pos] = row->lhs - row->constant;
8317  if( SCIPsetIsInfinity(set, row->rhs) )
8318  rhs[pos] = lpiinf;
8319  else
8320  rhs[pos] = row->rhs - row->constant;
8321  beg[pos] = nnonz;
8322  name[pos] = row->name;
8323 
8324  row->flushedlhs = lhs[pos];
8325  row->flushedrhs = rhs[pos];
8326 
8327  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8328  for( i = 0; i < row->nlpcols; ++i )
8329  {
8330  assert(row->cols[i] != NULL);
8331  lpipos = row->cols[i]->lpipos;
8332  if( lpipos >= 0 )
8333  {
8334  assert(lpipos < lp->ncols);
8335  assert(nnonz < naddcoefs);
8336  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8337  ind[nnonz] = lpipos;
8338  val[nnonz] = row->vals[i];
8339  nnonz++;
8340  }
8341  }
8342  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8343 #ifndef NDEBUG
8344  for( i = row->nlpcols; i < row->len; ++i )
8345  {
8346  assert(row->cols[i] != NULL);
8347  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8348  }
8349 #endif
8350  }
8351 
8352  /* call LP interface */
8353  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8354  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8355  lp->nlpirows = lp->nrows;
8356  lp->lpifirstchgrow = lp->nlpirows;
8357 
8358  /* free temporary memory */
8359  SCIPsetFreeBufferArray(set, &name);
8360  SCIPsetFreeBufferArray(set, &val);
8361  SCIPsetFreeBufferArray(set, &ind);
8362  SCIPsetFreeBufferArray(set, &beg);
8363  SCIPsetFreeBufferArray(set, &rhs);
8364  SCIPsetFreeBufferArray(set, &lhs);
8365 
8366  lp->flushaddedrows = TRUE;
8367 
8368  /* mark the LP unsolved */
8369  lp->solved = FALSE;
8370  lp->primalfeasible = FALSE;
8371  lp->primalchecked = FALSE;
8372  lp->lpobjval = SCIP_INVALID;
8374 
8375  return SCIP_OKAY;
8376 }
8377 
8378 /** applies all cached column bound and objective changes to the LP */
8379 static
8381  SCIP_LP* lp, /**< current LP data */
8382  SCIP_SET* set /**< global SCIP settings */
8383  )
8384 {
8385 #ifndef NDEBUG
8386  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8387 #endif
8388  SCIP_COL* col;
8389  int* objind;
8390  int* bdind;
8391  SCIP_Real* obj;
8392  SCIP_Real* lb;
8393  SCIP_Real* ub;
8394  SCIP_Real lpiinf;
8395  int nobjchg;
8396  int nbdchg;
8397  int i;
8398 
8399  assert(lp != NULL);
8400 
8401  if( lp->nchgcols == 0 )
8402  return SCIP_OKAY;
8403 
8404  /* get the solver's infinity value */
8405  lpiinf = SCIPlpiInfinity(lp->lpi);
8406 
8407  /* get temporary memory for changes */
8408  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8409  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8410  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8411  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8412  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8413 
8414  /* collect all cached bound and objective changes */
8415  nobjchg = 0;
8416  nbdchg = 0;
8417  for( i = 0; i < lp->nchgcols; ++i )
8418  {
8419  col = lp->chgcols[i];
8420  assert(col != NULL);
8421  assert(col->var != NULL);
8422  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8423  assert(SCIPvarGetCol(col->var) == col);
8424 
8425  if( col->lpipos >= 0 )
8426  {
8427 #ifndef NDEBUG
8428  /* do not check consistency of data with LPI in case of LPI=none */
8429  if( !lpinone )
8430  {
8431  SCIP_Real lpiobj;
8432  SCIP_Real lpilb;
8433  SCIP_Real lpiub;
8434 
8435  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8436  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8437  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8438  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8439  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8440  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8441  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8442  }
8443 #endif
8444 
8445  if( col->objchanged )
8446  {
8447  SCIP_Real newobj;
8448 
8449  newobj = col->obj;
8450  if( col->flushedobj != newobj ) /*lint !e777*/
8451  {
8452  assert(nobjchg < lp->ncols);
8453  objind[nobjchg] = col->lpipos;
8454  obj[nobjchg] = newobj;
8455  nobjchg++;
8456  col->flushedobj = newobj;
8457  }
8458  col->objchanged = FALSE;
8459  }
8460 
8461  if( col->lbchanged || col->ubchanged )
8462  {
8463  SCIP_Real newlb;
8464  SCIP_Real newub;
8465 
8466  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8467  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8468 
8469  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8470  {
8471  assert(nbdchg < lp->ncols);
8472  bdind[nbdchg] = col->lpipos;
8473  lb[nbdchg] = newlb;
8474  ub[nbdchg] = newub;
8475  nbdchg++;
8476  col->flushedlb = newlb;
8477  col->flushedub = newub;
8478  }
8479  col->lbchanged = FALSE;
8480  col->ubchanged = FALSE;
8481  }
8482  }
8483  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8484  }
8485 
8486  /* change objective values in LP */
8487  if( nobjchg > 0 )
8488  {
8489  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8490  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8491 
8492  /* mark the LP unsolved */
8493  lp->solved = FALSE;
8494  lp->dualfeasible = FALSE;
8495  lp->dualchecked = FALSE;
8496  lp->lpobjval = SCIP_INVALID;
8498  }
8499 
8500  /* change bounds in LP */
8501  if( nbdchg > 0 )
8502  {
8503  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8504  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8505 
8506  /* mark the LP unsolved */
8507  lp->solved = FALSE;
8508  lp->primalfeasible = FALSE;
8509  lp->primalchecked = FALSE;
8510  lp->lpobjval = SCIP_INVALID;
8512  }
8513 
8514  lp->nchgcols = 0;
8515 
8516  /* free temporary memory */
8517  SCIPsetFreeBufferArray(set, &ub);
8518  SCIPsetFreeBufferArray(set, &lb);
8519  SCIPsetFreeBufferArray(set, &bdind);
8520  SCIPsetFreeBufferArray(set, &obj);
8521  SCIPsetFreeBufferArray(set, &objind);
8522 
8523  return SCIP_OKAY;
8524 }
8525 
8526 /** applies all cached row side changes to the LP */
8527 static
8529  SCIP_LP* lp, /**< current LP data */
8530  SCIP_SET* set /**< global SCIP settings */
8531  )
8532 {
8533 #ifndef NDEBUG
8534  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8535 #endif
8536  SCIP_ROW* row;
8537  int* ind;
8538  SCIP_Real* lhs;
8539  SCIP_Real* rhs;
8540  SCIP_Real lpiinf;
8541  int i;
8542  int nchg;
8543 
8544  assert(lp != NULL);
8545 
8546  if( lp->nchgrows == 0 )
8547  return SCIP_OKAY;
8548 
8549  /* get the solver's infinity value */
8550  lpiinf = SCIPlpiInfinity(lp->lpi);
8551 
8552  /* get temporary memory for changes */
8553  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8554  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8555  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8556 
8557  /* collect all cached left and right hand side changes */
8558  nchg = 0;
8559  for( i = 0; i < lp->nchgrows; ++i )
8560  {
8561  row = lp->chgrows[i];
8562  assert(row != NULL);
8563 
8564  if( row->lpipos >= 0 )
8565  {
8566 #ifndef NDEBUG
8567  /* do not check consistency of data with LPI in case of LPI=none */
8568  if( !lpinone )
8569  {
8570  SCIP_Real lpilhs;
8571  SCIP_Real lpirhs;
8572 
8573  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8574  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8575  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8576  }
8577 #endif
8578  if( row->lhschanged || row->rhschanged )
8579  {
8580  SCIP_Real newlhs;
8581  SCIP_Real newrhs;
8582 
8583  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8584  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8585  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8586  {
8587  assert(nchg < lp->nrows);
8588  ind[nchg] = row->lpipos;
8589  lhs[nchg] = newlhs;
8590  rhs[nchg] = newrhs;
8591  nchg++;
8592  row->flushedlhs = newlhs;
8593  row->flushedrhs = newrhs;
8594  }
8595  row->lhschanged = FALSE;
8596  row->rhschanged = FALSE;
8597  }
8598  }
8599  }
8600 
8601  /* change left and right hand sides in LP */
8602  if( nchg > 0 )
8603  {
8604  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8605  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8606 
8607  /* mark the LP unsolved */
8608  lp->solved = FALSE;
8609  lp->primalfeasible = FALSE;
8610  lp->primalchecked = FALSE;
8611  lp->lpobjval = SCIP_INVALID;
8613  }
8614 
8615  lp->nchgrows = 0;
8616 
8617  /* free temporary memory */
8618  SCIPsetFreeBufferArray(set, &rhs);
8619  SCIPsetFreeBufferArray(set, &lhs);
8620  SCIPsetFreeBufferArray(set, &ind);
8621 
8622  return SCIP_OKAY;
8623 }
8624 
8625 /** copy integrality information to the LP */
8626 static
8628  SCIP_LP* lp, /**< current LP data */
8629  SCIP_SET* set /**< global SCIP settings */
8630  )
8631 {
8632  int i;
8633  int nintegers;
8634  int* integerInfo;
8635  SCIP_VAR* var;
8636 
8637  assert(lp != NULL);
8638 
8639  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8640 
8641  /* count total number of integralities */
8642  nintegers = 0;
8643 
8644  for( i = 0; i < lp->ncols; ++i )
8645  {
8646  var = SCIPcolGetVar(lp->cols[i]);
8647  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8648  {
8649  integerInfo[i] = 1;
8650  ++nintegers;
8651  }
8652  else
8653  integerInfo[i] = 0;
8654  }
8655 
8656  /* only pass integrality information if integer variables are present */
8657  if( nintegers > 0 )
8658  {
8659  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8660  }
8661  else
8662  {
8664  }
8665 
8666  SCIPsetFreeBufferArray(set, &integerInfo);
8667 
8668  /* mark integralities to be updated */
8669  lp->updateintegrality = FALSE;
8670 
8671  return SCIP_OKAY;
8672 }
8673 
8674 /** applies all cached changes to the LP solver */
8676  SCIP_LP* lp, /**< current LP data */
8677  BMS_BLKMEM* blkmem, /**< block memory */
8678  SCIP_SET* set, /**< global SCIP settings */
8679  SCIP_PROB* prob, /**< problem data */
8680  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8681  )
8682 {
8683  assert(lp != NULL);
8684  assert(blkmem != NULL);
8685 
8686  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",
8687  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8688 
8689  if( !lp->flushed )
8690  {
8691  lp->flushdeletedcols = FALSE;
8692  lp->flushaddedcols = FALSE;
8693  lp->flushdeletedrows = FALSE;
8694  lp->flushaddedrows = FALSE;
8695 
8696  SCIP_CALL( lpFlushDelCols(lp) );
8697  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8698  SCIP_CALL( lpFlushChgCols(lp, set) );
8699  SCIP_CALL( lpFlushChgRows(lp, set) );
8700  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8701  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8702 
8703  lp->flushed = TRUE;
8704 
8705  checkLinks(lp);
8706  }
8707 
8708  /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8709  * we want to re-optimize the LP even if nothing else has changed */
8710  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 && ! lpCutoffDisabled(set, prob) ) /*lint !e777*/
8711  {
8712  lp->solved = FALSE;
8714  }
8715 
8716  assert(lp->nlpicols == lp->ncols);
8717  assert(lp->lpifirstchgcol == lp->nlpicols);
8718  assert(lp->nlpirows == lp->nrows);
8719  assert(lp->lpifirstchgrow == lp->nlpirows);
8720  assert(lp->nchgcols == 0);
8721  assert(lp->nchgrows == 0);
8722 #ifndef NDEBUG
8723  {
8724  int ncols;
8725  int nrows;
8726 
8727  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8728  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8729  assert(ncols == lp->ncols);
8730  assert(nrows == lp->nrows);
8731  }
8732 #endif
8733 
8734  return SCIP_OKAY;
8735 }
8736 
8737 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8739  SCIP_LP* lp, /**< current LP data */
8740  SCIP_SET* set /**< global SCIP settings */
8741  )
8742 {
8743 #ifndef NDEBUG
8744  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8745 #endif
8746  int i;
8747 
8748  assert(lp != NULL);
8749 
8750 #ifndef NDEBUG
8751  /* check, if there are really no column or row deletions or coefficient changes left */
8752  while( lp->lpifirstchgcol < lp->nlpicols
8753  && lp->lpifirstchgcol < lp->ncols
8754  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8755  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8756  {
8757  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8758  lp->lpifirstchgcol++;
8759  }
8760  assert(lp->nlpicols == lp->lpifirstchgcol);
8761 
8762  while( lp->lpifirstchgrow < lp->nlpirows
8763  && lp->lpifirstchgrow < lp->nrows
8764  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8765  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8766  {
8767  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8768  lp->lpifirstchgrow++;
8769  }
8770  assert(lp->nlpirows == lp->lpifirstchgrow);
8771 #endif
8772 
8773  lp->lpifirstchgcol = lp->nlpicols;
8774  lp->lpifirstchgrow = lp->nlpirows;
8775 
8776  /* check, if there are really no column or row additions left */
8777  assert(lp->ncols == lp->nlpicols);
8778  assert(lp->nrows == lp->nlpirows);
8779 
8780  /* mark the changed columns to be unchanged, and check, if this is really correct */
8781  for( i = 0; i < lp->nchgcols; ++i )
8782  {
8783  SCIP_COL* col;
8784 
8785  col = lp->chgcols[i];
8786  assert(col != NULL);
8787  assert(col->var != NULL);
8788  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8789  assert(SCIPvarGetCol(col->var) == col);
8790 
8791  if( col->lpipos >= 0 )
8792  {
8793 #ifndef NDEBUG
8794  /* do not check consistency of data with LPI in case of LPI=none */
8795  if( !lpinone )
8796  {
8797  SCIP_Real lpiobj;
8798  SCIP_Real lpilb;
8799  SCIP_Real lpiub;
8800 
8801  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8802  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8803  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8804  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8805  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8806  assert(col->flushedobj == col->obj); /*lint !e777*/
8807  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8808  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8809  }
8810 #endif
8811  col->objchanged = FALSE;
8812  col->lbchanged = FALSE;
8813  col->ubchanged = FALSE;
8814  }
8815  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8816  }
8817  lp->nchgcols = 0;
8818 
8819  /* mark the changed rows to be unchanged, and check, if this is really correct */
8820  for( i = 0; i < lp->nchgrows; ++i )
8821  {
8822  SCIP_ROW* row;
8823 
8824  row = lp->chgrows[i];
8825  assert(row != NULL);
8826 
8827  if( row->lpipos >= 0 )
8828  {
8829 #ifndef NDEBUG
8830  /* do not check consistency of data with LPI in case of LPI=none */
8831  if( !lpinone )
8832  {
8833  SCIP_Real lpilhs;
8834  SCIP_Real lpirhs;
8835 
8836  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8837  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8838  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8839  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8840  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8841  }
8842 #endif
8843  row->lhschanged = FALSE;
8844  row->rhschanged = FALSE;
8845  }
8846  }
8847  lp->nchgrows = 0;
8848 
8849  /* mark the LP to be flushed */
8850  lp->flushed = TRUE;
8851 
8852  checkLinks(lp);
8853 
8854  return SCIP_OKAY;
8855 }
8856 
8857 
8858 
8859 
8860 /*
8861  * LP methods
8862  */
8863 
8864 /** updates link data after addition of column */
8865 static
8867  SCIP_COL* col, /**< LP column */
8868  SCIP_SET* set /**< global SCIP settings */
8869  )
8870 {
8871  SCIP_ROW* row;
8872  int i;
8873  int pos;
8874 
8875  assert(col != NULL);
8876  assert(col->lppos >= 0);
8877 
8878  /* update column arrays of all linked rows */
8879  for( i = 0; i < col->len; ++i )
8880  {
8881  pos = col->linkpos[i];
8882  if( pos >= 0 )
8883  {
8884  row = col->rows[i];
8885  assert(row != NULL);
8886  assert(row->linkpos[pos] == i);
8887  assert(row->cols[pos] == col);
8888  assert(row->nlpcols <= pos && pos < row->len);
8889 
8890  row->nlpcols++;
8891  rowSwapCoefs(row, pos, row->nlpcols-1);
8892  assert(row->cols[row->nlpcols-1] == col);
8893 
8894  /* if no swap was necessary, mark lpcols to be unsorted */
8895  if( pos == row->nlpcols-1 )
8896  row->lpcolssorted = FALSE;
8897 
8898  /* update norms */
8899  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8900  }
8901  }
8902 }
8903 
8904 /** updates link data after addition of row */
8905 static
8907  SCIP_ROW* row /**< LP row */
8908  )
8909 {
8910  SCIP_COL* col;
8911  int i;
8912  int pos;
8913 
8914  assert(row != NULL);
8915  assert(row->lppos >= 0);
8916 
8917  /* update row arrays of all linked columns */
8918  for( i = 0; i < row->len; ++i )
8919  {
8920  pos = row->linkpos[i];
8921  if( pos >= 0 )
8922  {
8923  col = row->cols[i];
8924  assert(col != NULL);
8925  assert(col->linkpos[pos] == i);
8926  assert(col->rows[pos] == row);
8927  assert(col->nlprows <= pos && pos < col->len);
8928 
8929  col->nlprows++;
8930  colSwapCoefs(col, pos, col->nlprows-1);
8931 
8932  /* if no swap was necessary, mark lprows to be unsorted */
8933  if( pos == col->nlprows-1 )
8934  col->lprowssorted = FALSE;
8935  }
8936  }
8937 }
8938 
8939 /** updates link data after removal of column */
8940 static
8942  SCIP_COL* col, /**< LP column */
8943  SCIP_SET* set /**< global SCIP settings */
8944  )
8945 {
8946  SCIP_ROW* row;
8947  int i;
8948  int pos;
8949 
8950  assert(col != NULL);
8951  assert(col->lppos == -1);
8952 
8953  /* update column arrays of all linked rows */
8954  for( i = 0; i < col->len; ++i )
8955  {
8956  pos = col->linkpos[i];
8957  if( pos >= 0 )
8958  {
8959  row = col->rows[i];
8960  assert(row != NULL);
8961  assert(row->linkpos[pos] == i);
8962  assert(row->cols[pos] == col);
8963  assert(0 <= pos && pos < row->nlpcols);
8964 
8965  /* update norms */
8966  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8967 
8968  row->nlpcols--;
8969  rowSwapCoefs(row, pos, row->nlpcols);
8970 
8971  /* if no swap was necessary, mark nonlpcols to be unsorted */
8972  if( pos == row->nlpcols )
8973  row->nonlpcolssorted = FALSE;
8974  }
8975  }
8976 }
8977 
8978 /** updates link data after removal of row */
8979 static
8981  SCIP_ROW* row /**< LP row */
8982  )
8983 {
8984  SCIP_COL* col;
8985  int i;
8986  int pos;
8987 
8988  assert(row != NULL);
8989  assert(row->lppos == -1);
8990 
8991  /* update row arrays of all linked columns */
8992  for( i = 0; i < row->len; ++i )
8993  {
8994  pos = row->linkpos[i];
8995  if( pos >= 0 )
8996  {
8997  col = row->cols[i];
8998  assert(col != NULL);
8999  assert(0 <= pos && pos < col->nlprows);
9000  assert(col->linkpos[pos] == i);
9001  assert(col->rows[pos] == row);
9002 
9003  col->nlprows--;
9004  colSwapCoefs(col, pos, col->nlprows);
9005 
9006  /* if no swap was necessary, mark lprows to be unsorted */
9007  if( pos == col->nlprows )
9008  col->nonlprowssorted = FALSE;
9009  }
9010  }
9011 }
9012 
9013 static
9015  SCIP_LP* lp, /**< LP data object */
9016  int initsize /**< initial size of the arrays */
9017  )
9018 {
9019  assert(lp != NULL);
9020  assert(lp->divechgsides == NULL);
9021  assert(lp->divechgsidetypes == NULL);
9022  assert(lp->divechgrows == NULL);
9023  assert(lp->ndivechgsides == 0);
9024  assert(lp->divechgsidessize == 0);
9025  assert(initsize > 0);
9026 
9027  lp->divechgsidessize = initsize;
9031 
9032  return SCIP_OKAY;
9033 }
9034 
9035 static
9037  SCIP_LP* lp, /**< LP data object */
9038  int minsize, /**< minimal number of elements */
9039  SCIP_Real growfact /**< growing factor */
9040  )
9041 {
9042  assert(lp != NULL);
9043  assert(lp->divechgsides != NULL);
9044  assert(lp->divechgsidetypes != NULL);
9045  assert(lp->divechgrows != NULL);
9046  assert(lp->ndivechgsides > 0);
9047  assert(lp->divechgsidessize > 0);
9048  assert(minsize > 0);
9049 
9050  if( minsize <= lp->divechgsidessize )
9051  return SCIP_OKAY;
9052 
9053  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9057 
9058  return SCIP_OKAY;
9059 }
9060 
9061 static
9063  SCIP_LP* lp /**< LP data object */
9064  )
9065 {
9066  assert(lp != NULL);
9067  assert(lp->divechgsides != NULL);
9068  assert(lp->divechgsidetypes != NULL);
9069  assert(lp->divechgrows != NULL);
9070  assert(lp->ndivechgsides == 0);
9071  assert(lp->divechgsidessize > 0);
9072 
9076  lp->divechgsidessize = 0;
9077 }
9078 
9079 #define DIVESTACKINITSIZE 100
9080 
9081 /** creates empty LP data object */
9083  SCIP_LP** lp, /**< pointer to LP data object */
9084  SCIP_SET* set, /**< global SCIP settings */
9085  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9086  SCIP_STAT* stat, /**< problem statistics */
9087  const char* name /**< problem name */
9088  )
9089 {
9090  SCIP_Bool success;
9091 
9092  assert(lp != NULL);
9093  assert(set != NULL);
9094  assert(stat != NULL);
9095  assert(name != NULL);
9096 
9097  SCIP_ALLOC( BMSallocMemory(lp) );
9098 
9099  /* open LP Solver interface */
9100  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9101 
9102  (*lp)->lpicols = NULL;
9103  (*lp)->lpirows = NULL;
9104  (*lp)->chgcols = NULL;
9105  (*lp)->chgrows = NULL;
9106  (*lp)->cols = NULL;
9107  (*lp)->soldirection = NULL;
9108  (*lp)->lazycols = NULL;
9109  (*lp)->rows = NULL;
9110  (*lp)->lpobjval = 0.0;
9111  (*lp)->glbpseudoobjval = 0.0;
9112  (*lp)->relglbpseudoobjval = 0.0;
9113  (*lp)->glbpseudoobjvalid = TRUE;
9114  (*lp)->glbpseudoobjvalinf = 0;
9115  (*lp)->pseudoobjval = 0.0;
9116  (*lp)->relpseudoobjval = 0.0;
9117  (*lp)->pseudoobjvalid = TRUE;
9118  (*lp)->pseudoobjvalinf = 0;
9119  (*lp)->looseobjval = 0.0;
9120  (*lp)->rellooseobjval = 0.0;
9121  (*lp)->looseobjvalid = TRUE;
9122  (*lp)->looseobjvalinf = 0;
9123  (*lp)->nloosevars = 0;
9124  (*lp)->rootlpobjval = SCIP_INVALID;
9125  (*lp)->rootlooseobjval = SCIP_INVALID;
9126  (*lp)->cutoffbound = SCIPsetInfinity(set);
9127  (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9128  SCIPlpResetFeastol(*lp, set);
9129  (*lp)->validdegeneracylp = -1;
9130  (*lp)->objsqrnorm = 0.0;
9131  (*lp)->objsumnorm = 0.0;
9132  (*lp)->lpicolssize = 0;
9133  (*lp)->nlpicols = 0;
9134  (*lp)->lpirowssize = 0;
9135  (*lp)->nlpirows = 0;
9136  (*lp)->lpifirstchgcol = 0;
9137  (*lp)->lpifirstchgrow = 0;
9138  (*lp)->colssize = 0;
9139  (*lp)->soldirectionsize = 0;
9140  (*lp)->ncols = 0;
9141  (*lp)->lazycolssize = 0;
9142  (*lp)->nlazycols = 0;
9143  (*lp)->rowssize = 0;
9144  (*lp)->nrows = 0;
9145  (*lp)->chgcolssize = 0;
9146  (*lp)->nchgcols = 0;
9147  (*lp)->chgrowssize = 0;
9148  (*lp)->nchgrows = 0;
9149  (*lp)->firstnewcol = 0;
9150  (*lp)->firstnewrow = 0;
9151  (*lp)->nremovablecols = 0;
9152  (*lp)->nremovablerows = 0;
9153  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9154  (*lp)->validfarkaslp = -1;
9155  (*lp)->validsoldirlp = -1;
9156  (*lp)->validsoldirsol = NULL;
9157  (*lp)->objsqrnormunreliable = FALSE;
9158  (*lp)->flushdeletedcols = FALSE;
9159  (*lp)->flushaddedcols = FALSE;
9160  (*lp)->flushdeletedrows = FALSE;
9161  (*lp)->flushaddedrows = FALSE;
9162  (*lp)->updateintegrality = TRUE;
9163  (*lp)->flushed = TRUE;
9164  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9165  (*lp)->solved = TRUE;
9166  (*lp)->primalfeasible = TRUE;
9167  (*lp)->primalchecked = TRUE;
9168  (*lp)->dualfeasible = TRUE;
9169  (*lp)->dualchecked = TRUE;
9170  (*lp)->solisbasic = FALSE;
9171  (*lp)->rootlpisrelax = TRUE;
9172  (*lp)->isrelax = TRUE;
9173  (*lp)->installing = FALSE;
9174  (*lp)->strongbranching = FALSE;
9175  (*lp)->strongbranchprobing = FALSE;
9176  (*lp)->probing = FALSE;
9177  (*lp)->diving = FALSE;
9178  (*lp)->divingobjchg = FALSE;
9179  (*lp)->divinglazyapplied = FALSE;
9180  (*lp)->divelpistate = NULL;
9181  (*lp)->divelpwasprimfeas = TRUE;
9182  (*lp)->divelpwasprimchecked = TRUE;
9183  (*lp)->divelpwasdualfeas = TRUE;
9184  (*lp)->divelpwasdualchecked = TRUE;
9185  (*lp)->divechgsides = NULL;
9186  (*lp)->divechgsidetypes = NULL;
9187  (*lp)->divechgrows = NULL;
9188  (*lp)->ndivechgsides = 0;
9189  (*lp)->divechgsidessize = 0;
9190  (*lp)->ndivingrows = 0;
9191  (*lp)->divinglpiitlim = INT_MAX;
9192  (*lp)->resolvelperror = FALSE;
9193  (*lp)->divenolddomchgs = 0;
9194  (*lp)->adjustlpval = FALSE;
9195  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9196  (*lp)->lpifeastol = (*lp)->feastol;
9197  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9198  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9199  (*lp)->lpifromscratch = FALSE;
9200  (*lp)->lpifastmip = set->lp_fastmip;
9201  (*lp)->lpiscaling = set->lp_scaling;
9202  (*lp)->lpipresolving = set->lp_presolving;
9203  (*lp)->lpilpinfo = set->disp_lpinfo;
9204  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9205  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9206  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9207  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9208  (*lp)->lpimarkowitz = set->lp_markowitz;
9209  (*lp)->lpiitlim = INT_MAX;
9210  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9211  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9212  (*lp)->lpithreads = set->lp_threads;
9213  (*lp)->lpitiming = (int) set->time_clocktype;
9214  (*lp)->lpirandomseed = set->random_randomseed;
9215  (*lp)->storedsolvals = NULL;
9216 
9217  /* allocate arrays for diving */
9219 
9220  /* set default parameters in LP solver */
9221  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9222  if( !success )
9223  {
9224  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9225  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9227  }
9228  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9229  (*lp)->lpihasfeastol = success;
9230  if( !success )
9231  {
9232  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9233  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9235  }
9236  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9237  (*lp)->lpihasdualfeastol = success;
9238  if( !success )
9239  {
9240  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9241  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9243  }
9244  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9245  (*lp)->lpihasbarrierconvtol = success;
9246  if( !success )
9247  {
9248  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9249  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9251  }
9252  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9253  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9254  (*lp)->lpihasfastmip = success;
9255  if( !success )
9256  {
9257  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9258  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9260  }
9261  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9262  (*lp)->lpihasscaling = success;
9263  if( !success )
9264  {
9265  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9266  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9268  }
9269  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9270  (*lp)->lpihaspresolving = success;
9271  if( !success )
9272  {
9273  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9274  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9276  }
9277  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9278  if( !success )
9279  {
9280  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9281  "LP Solver <%s>: clock type cannot be set\n",
9283  }
9284  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9285  if( !success )
9286  {
9287  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9288  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9290  }
9291  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9292  if( !success )
9293  {
9294  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9295  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9297  }
9298  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9299  if( !success )
9300  {
9301  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9302  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9304  }
9305  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9306  (*lp)->lpihasrowrep = success;
9307  if( !success )
9308  {
9309  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9310  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9312  }
9313  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9314  (*lp)->lpihaspolishing = success;
9315  if( !success )
9316  {
9317  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9318  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9320  }
9321  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9322  (*lp)->lpihasrefactor = success;
9323  if( !success )
9324  {
9325  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9326  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9328  }
9329  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9330  if( !success )
9331  {
9332  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9333  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9335  }
9336  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9337  if( !success )
9338  {
9339  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9340  "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9342  }
9343  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9344  if( !success )
9345  {
9346  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9347  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9349  }
9350  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9351  if( (*lp)->lpirandomseed != 0 )
9352  {
9353  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9354  if( !success )
9355  {
9356  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9357  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9359  }
9360  }
9361 
9362  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9363  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9364  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9365  {
9366  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9367  return SCIP_PARAMETERWRONGVAL;
9368  }
9369 
9370  return SCIP_OKAY;
9371 }
9372 
9373 /** frees LP data object */
9375  SCIP_LP** lp, /**< pointer to LP data object */
9376  BMS_BLKMEM* blkmem, /**< block memory */
9377  SCIP_SET* set, /**< global SCIP settings */
9378  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9379  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9380  )
9381 {
9382  int i;
9383 
9384  assert(lp != NULL);
9385  assert(*lp != NULL);
9386 
9387  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9388 
9389  freeDiveChgSideArrays(*lp);
9390 
9391  /* release LPI rows */
9392  for( i = 0; i < (*lp)->nlpirows; ++i )
9393  {
9394  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9395  }
9396 
9397  if( (*lp)->lpi != NULL )
9398  {
9399  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9400  }
9401 
9402  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9403  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9404  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9405  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9406  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9407  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9408  BMSfreeMemoryArrayNull(&(*lp)->cols);
9409  BMSfreeMemoryArrayNull(&(*lp)->rows);
9410  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9411  BMSfreeMemory(lp);
9412 
9413  return SCIP_OKAY;
9414 }
9415 
9416 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9417  * changes to the LP solver
9418  */
9420  SCIP_LP* lp, /**< LP data */
9421  BMS_BLKMEM* blkmem, /**< block memory */
9422  SCIP_SET* set, /**< global SCIP settings */
9423  SCIP_PROB* prob, /**< problem data */
9424  SCIP_STAT* stat, /**< problem statistics */
9425  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9426  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9427  )
9428 {
9429  assert(stat != NULL);
9430 
9431  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9432  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
9433 
9434  /* mark the empty LP to be solved */
9436  lp->lpobjval = 0.0;
9437  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9438  lp->validfarkaslp = -1;
9439  lp->validdegeneracylp = -1;
9440  lp->validsoldirlp = -1;
9441  lp->validsoldirsol = NULL;
9442  lp->solved = TRUE;
9443  lp->primalfeasible = TRUE;
9444  lp->primalchecked = TRUE;
9445  lp->dualfeasible = TRUE;
9446  lp->dualchecked = TRUE;
9447  lp->solisbasic = FALSE;
9449 
9450  return SCIP_OKAY;
9451 }
9452 
9453 /** adds a column to the LP */
9455  SCIP_LP* lp, /**< LP data */
9456  SCIP_SET* set, /**< global SCIP settings */
9457  SCIP_COL* col, /**< LP column */
9458  int depth /**< depth in the tree where the column addition is performed */
9459  )
9460 {
9461  assert(lp != NULL);
9462  assert(!lp->diving);
9463  assert(col != NULL);
9464  assert(col->len == 0 || col->rows != NULL);
9465  assert(col->lppos == -1);
9466  assert(col->var != NULL);
9467  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9468  assert(SCIPvarGetCol(col->var) == col);
9469  assert(SCIPvarIsIntegral(col->var) == col->integral);
9470 
9471  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9472 #ifdef SCIP_DEBUG
9473  {
9474  int i;
9475  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9476  for( i = 0; i < col->len; ++i )
9477  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9478  SCIPsetDebugMsgPrint(set, "\n");
9479  }
9480 #endif
9481 
9482  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9483  lp->cols[lp->ncols] = col;
9484  col->lppos = lp->ncols;
9485  col->lpdepth = depth;
9486  col->age = 0;
9487  lp->ncols++;
9488  if( col->removable )
9489  lp->nremovablecols++;
9490 
9491  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9492  {
9493  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9494  lp->lazycols[lp->nlazycols] = col;
9495  lp->nlazycols++;
9496  }
9497 
9498  /* mark the current LP unflushed */
9499  lp->flushed = FALSE;
9500 
9501  /* update column arrays of all linked rows */
9502  colUpdateAddLP(col, set);
9503 
9504  /* update the objective function vector norms */
9505  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9506 
9507  checkLinks(lp);
9508 
9509  return SCIP_OKAY;
9510 }
9511 
9512 /** adds a row to the LP and captures it */
9514  SCIP_LP* lp, /**< LP data */
9515  BMS_BLKMEM* blkmem, /**< block memory buffers */
9516  SCIP_SET* set, /**< global SCIP settings */
9517  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9518  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9519  SCIP_ROW* row, /**< LP row */
9520  int depth /**< depth in the tree where the row addition is performed */
9521  )
9522 {
9523  assert(lp != NULL);
9524  assert(row != NULL);
9525  assert(row->len == 0 || row->cols != NULL);
9526  assert(row->lppos == -1);
9527 
9528  SCIProwCapture(row);
9529  SCIProwLock(row);
9530 
9531  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9532 #ifdef SCIP_DEBUG
9533  {
9534  int i;
9535  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9536  for( i = 0; i < row->len; ++i )
9537  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9538  if( !SCIPsetIsZero(set, row->constant) )
9539  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9540  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9541  }
9542 #endif
9543 
9544  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9545  lp->rows[lp->nrows] = row;
9546  row->lppos = lp->nrows;
9547  row->lpdepth = depth;
9548  row->age = 0;
9549  lp->nrows++;
9550  if( row->removable )
9551  lp->nremovablerows++;
9552 
9553  /* mark the current LP unflushed */
9554  lp->flushed = FALSE;
9555 
9556  /* update row arrays of all linked columns */
9557  rowUpdateAddLP(row);
9558 
9559  checkLinks(lp);
9560 
9561  rowCalcNorms(row, set);
9562 
9563  /* check, if row addition to LP events are tracked
9564  * if so, issue ROWADDEDLP event
9565  */
9566  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9567  {
9568  SCIP_EVENT* event;
9569 
9570  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9571  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9572  }
9573 
9574  return SCIP_OKAY;
9575 }
9576 
9577 
9578 #ifndef NDEBUG
9579 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9580  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9581  * the lazycols array
9582  */
9583 static
9585  SCIP_LP* lp, /**< LP data */
9586  SCIP_SET* set /**< global SCIP settings */
9587  )
9588 {
9589  SCIP_Bool contained;
9590  int c;
9591  int i;
9592 
9593  assert(lp != NULL);
9594 
9595  /* check if each column in the lazy column array has a counter part in the column array */
9596  for( i = 0; i < lp->nlazycols; ++i )
9597  {
9598  /* check if each lazy column has at least on lazy bound */
9599  assert(lp->lazycols[i] != NULL);
9600  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9601 
9602  contained = FALSE;
9603  for( c = 0; c < lp->ncols; ++c )
9604  {
9605  if( lp->lazycols[i] == lp->cols[c] )
9606  {
9607  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9608  contained = TRUE;
9609  }
9610  }
9611  assert(contained);
9612  }
9613 
9614  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9615  * array */
9616  for( c = 0; c < lp->ncols; ++c )
9617  {
9618  contained = FALSE;
9619  assert(lp->cols[c] != NULL);
9620 
9621  for( i = 0; i < lp->nlazycols; ++i )
9622  {
9623  if( lp->lazycols[i] == lp->cols[c] )
9624  {
9625  contained = TRUE;
9626  }
9627  }
9628 
9629  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9630  }
9631 }
9632 #else
9633 #define checkLazyColArray(lp, set) /**/
9634 #endif
9635 
9636 /** removes all columns after the given number of cols from the LP */
9638  SCIP_LP* lp, /**< LP data */
9639  SCIP_SET* set, /**< global SCIP settings */
9640  int newncols /**< new number of columns in the LP */
9641  )
9642 {
9643  SCIP_COL* col;
9644  int c;
9645 
9646  assert(lp != NULL);
9647 
9648  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9649  assert(0 <= newncols);
9650  assert(newncols <= lp->ncols);
9651 
9652  if( newncols < lp->ncols )
9653  {
9654  assert(!lp->diving);
9655 
9656  for( c = lp->ncols-1; c >= newncols; --c )
9657  {
9658  col = lp->cols[c];
9659  assert(col != NULL);
9660  assert(col->len == 0 || col->rows != NULL);
9661  assert(col->var != NULL);
9662  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9663  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9664  assert(col->lppos == c);
9665 
9666  /* mark column to be removed from the LP */
9667  col->lppos = -1;
9668  col->lpdepth = -1;
9669  lp->ncols--;
9670 
9671  /* count removable columns */
9672  if( col->removable )
9673  lp->nremovablecols--;
9674 
9675  /* update column arrays of all linked rows */
9676  colUpdateDelLP(col, set);
9677 
9678  /* update the objective function vector norms */
9679  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9680  }
9681  assert(lp->ncols == newncols);
9682  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9683 
9684  /* remove columns which are deleted from the lazy column array */
9685  c = 0;
9686  while( c < lp->nlazycols )
9687  {
9688  if( lp->lazycols[c]->lppos < 0 )
9689  {
9690  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9691  lp->nlazycols--;
9692  }
9693  else
9694  c++;
9695  }
9696 
9697  /* mark the current LP unflushed */
9698  lp->flushed = FALSE;
9699 
9700  checkLazyColArray(lp, set);
9701  checkLinks(lp);
9702  }
9703  assert(lp->nremovablecols <= lp->ncols);
9704 
9705  return SCIP_OKAY;
9706 }
9707 
9708 /** removes and releases all rows after the given number of rows from the LP */
9710  SCIP_LP* lp, /**< LP data */
9711  BMS_BLKMEM* blkmem, /**< block memory */
9712  SCIP_SET* set, /**< global SCIP settings */
9713  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9714  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9715  int newnrows /**< new number of rows in the LP */
9716  )
9717 {
9718  SCIP_ROW* row;
9719  int r;
9720 
9721  assert(lp != NULL);
9722  assert(0 <= newnrows && newnrows <= lp->nrows);
9723 
9724  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9725  if( newnrows < lp->nrows )
9726  {
9727  for( r = lp->nrows-1; r >= newnrows; --r )
9728  {
9729  row = lp->rows[r];
9730  assert(row != NULL);
9731  assert(row->len == 0 || row->cols != NULL);
9732  assert(row->lppos == r);
9733 
9734  /* mark row to be removed from the LP */
9735  row->lppos = -1;
9736  row->lpdepth = -1;
9737  lp->nrows--;
9738 
9739  /* count removable rows */
9740  if( row->removable )
9741  lp->nremovablerows--;
9742 
9743  /* update row arrays of all linked columns */
9744  rowUpdateDelLP(row);
9745 
9746  SCIProwUnlock(lp->rows[r]);
9747 
9748  /* check, if row deletion events are tracked
9749  * if so, issue ROWDELETEDLP event
9750  */
9751  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9752  {
9753  SCIP_EVENT* event;
9754 
9755  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9756  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9757  }
9758 
9759  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9760  }
9761  assert(lp->nrows == newnrows);
9762  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9763 
9764  /* mark the current LP unflushed */
9765  lp->flushed = FALSE;
9766 
9767  checkLinks(lp);
9768  }
9769  assert(lp->nremovablerows <= lp->nrows);
9770 
9771  return SCIP_OKAY;
9772 }
9773 
9774 /** removes all columns and rows from LP, releases all rows */
9776  SCIP_LP* lp, /**< LP data */
9777  BMS_BLKMEM* blkmem, /**< block memory */
9778  SCIP_SET* set, /**< global SCIP settings */
9779  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9780  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9781  )
9782 {
9783  assert(lp != NULL);
9784  assert(!lp->diving);
9785 
9786  SCIPsetDebugMsg(set, "clearing LP\n");
9787  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9788  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9789 
9790  return SCIP_OKAY;
9791 }
9792 
9793 /** remembers number of columns and rows to track the newly added ones */
9795  SCIP_LP* lp /**< current LP data */
9796  )
9797 {
9798  assert(lp != NULL);
9799  assert(!lp->diving);
9800 
9801  lp->firstnewrow = lp->nrows;
9802  lp->firstnewcol = lp->ncols;
9803 }
9804 
9805 /** sets the remembered number of columns and rows to the given values */
9807  SCIP_LP* lp, /**< current LP data */
9808  int nrows, /**< number of rows to set the size marker to */
9809  int ncols /**< number of columns to set the size marker to */
9810  )
9811 {
9812  assert(lp != NULL);
9813  assert(!lp->diving);
9814 
9815  lp->firstnewrow = nrows;
9816  lp->firstnewcol = ncols;
9817 }
9818 
9819 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9821  SCIP_LP* lp, /**< LP data */
9822  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9823  )
9824 {
9825  assert(lp != NULL);
9826  assert(lp->flushed);
9827  assert(lp->solved);
9828  assert(lp->solisbasic);
9829  assert(basisind != NULL);
9830 
9831  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9832 
9833  return SCIP_OKAY;
9834 }
9835 
9836 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9838  SCIP_LP* lp, /**< LP data */
9839  int* cstat, /**< array to store column basis status, or NULL */
9840  int* rstat /**< array to store row basis status, or NULL */
9841  )
9842 {
9843  assert(lp != NULL);
9844  assert(lp->flushed);
9845  assert(lp->solved);
9846  assert(lp->solisbasic);
9847 
9848  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9849 
9850  return SCIP_OKAY;
9851 }
9852 
9853 /** gets a row from the inverse basis matrix B^-1 */
9855  SCIP_LP* lp, /**< LP data */
9856  int r, /**< row number */
9857  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9858  int* inds, /**< array to store the non-zero indices, or NULL */
9859  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9860  * (-1: if we do not store sparsity informations) */
9861  )
9862 {
9863  assert(lp != NULL);
9864  assert(lp->flushed);
9865  assert(lp->solved);
9866  assert(lp->solisbasic);
9867  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9868  assert(coef != NULL);
9869 
9870  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9871 
9872  return SCIP_OKAY;
9873 }
9874 
9875 /** gets a column from the inverse basis matrix B^-1 */
9877  SCIP_LP* lp, /**< LP data */
9878  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9879  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9880  * to get the array which links the B^-1 column numbers to the row and
9881  * column numbers of the LP! c must be between 0 and nrows-1, since the
9882  * basis has the size nrows * nrows */
9883  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9884  int* inds, /**< array to store the non-zero indices, or NULL */
9885  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9886  * (-1: if we do not store sparsity informations) */
9887  )
9888 {
9889  assert(lp != NULL);
9890  assert(lp->flushed);
9891  assert(lp->solved);
9892  assert(lp->solisbasic);
9893  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9894  assert(coef != NULL);
9895 
9896  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9897 
9898  return SCIP_OKAY;
9899 }
9900 
9901 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9903  SCIP_LP* lp, /**< LP data */
9904  int r, /**< row number */
9905  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9906  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9907  int* inds, /**< array to store the non-zero indices, or NULL */
9908  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9909  * (-1: if we do not store sparsity informations) */
9910  )
9911 {
9912  assert(lp != NULL);
9913  assert(lp->flushed);
9914  assert(lp->solved);
9915  assert(lp->solisbasic);
9916  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9917  assert(coef != NULL);
9918 
9919  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9920 
9921  return SCIP_OKAY;
9922 }
9923 
9924 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9925  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9926  */
9928  SCIP_LP* lp, /**< LP data */
9929  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9930  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9931  int* inds, /**< array to store the non-zero indices, or NULL */
9932  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9933  * (-1: if we do not store sparsity informations) */
9934  )
9935 {
9936  assert(lp != NULL);
9937  assert(lp->flushed);
9938  assert(lp->solved);
9939  assert(lp->solisbasic);
9940  assert(0 <= c && c < lp->ncols);
9941  assert(coef != NULL);
9942 
9943  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9944 
9945  return SCIP_OKAY;
9946 }
9947 
9948 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9949  * LP row are swapped in the summation
9950  */
9952  SCIP_LP* lp, /**< LP data */
9953  SCIP_SET* set, /**< global SCIP settings */
9954  SCIP_PROB* prob, /**< problem data */
9955  SCIP_Real* weights, /**< row weights in row summation */
9956  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9957  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9958  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9959  )
9960 {
9961  SCIP_ROW* row;
9962  int r;
9963  int i;
9964  int idx;
9965  SCIP_Bool lhsinfinite;
9966  SCIP_Bool rhsinfinite;
9967 
9968  assert(lp != NULL);
9969  assert(prob != NULL);
9970  assert(weights != NULL);
9971  assert(sumcoef != NULL);
9972  assert(sumlhs != NULL);
9973  assert(sumrhs != NULL);
9974 
9975  /**@todo test, if a column based summation is faster */
9976 
9977  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9978  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9979  *sumlhs = 0.0;
9980  *sumrhs = 0.0;
9981  lhsinfinite = FALSE;
9982  rhsinfinite = FALSE;
9983  for( r = 0; r < lp->nrows; ++r )
9984  {
9985  if( !SCIPsetIsZero(set, weights[r]) )
9986  {
9987  row = lp->rows[r];
9988  assert(row != NULL);
9989  assert(row->len == 0 || row->cols != NULL);
9990  assert(row->len == 0 || row->cols_index != NULL);
9991  assert(row->len == 0 || row->vals != NULL);
9992 
9993  /* add the row coefficients to the sum */
9994  for( i = 0; i < row->len; ++i )
9995  {
9996  assert(row->cols[i] != NULL);
9997  assert(row->cols[i]->var != NULL);
9998  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9999  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
10000  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
10001  idx = row->cols[i]->var_probindex;
10002  assert(0 <= idx && idx < prob->nvars);
10003  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
10004  }
10005 
10006  /* add the row sides to the sum, depending on the sign of the weight */
10007  if( weights[r] > 0.0 )
10008  {
10009  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10010  if( !lhsinfinite )
10011  (*sumlhs) += weights[r] * (row->lhs - row->constant);
10012  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10013  if( !rhsinfinite )
10014  (*sumrhs) += weights[r] * (row->rhs - row->constant);
10015  }
10016  else
10017  {
10018  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10019  if( !lhsinfinite )
10020  (*sumlhs) += weights[r] * (row->rhs - row->constant);
10021  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10022  if( !rhsinfinite )
10023  (*sumrhs) += weights[r] * (row->lhs - row->constant);
10024  }
10025  }
10026  }
10027 
10028  if( lhsinfinite )
10029  *sumlhs = -SCIPsetInfinity(set);
10030  if( rhsinfinite )
10031  *sumrhs = SCIPsetInfinity(set);
10032 
10033  return SCIP_OKAY;
10034 }
10035 
10036 /** stores LP state (like basis information) into LP state object */
10038  SCIP_LP* lp, /**< LP data */
10039  BMS_BLKMEM* blkmem, /**< block memory */
10040  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10041  )
10042 {
10043  assert(lp != NULL);
10044  assert(lp->flushed);
10045  assert(lp->solved);
10046  assert(blkmem != NULL);
10047  assert(lpistate != NULL);
10048 
10049  /* check whether there is no lp */
10050  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10051  *lpistate = NULL;
10052  else
10053  {
10054  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10055  }
10056 
10057  return SCIP_OKAY;
10058 }
10059 
10060 /** loads LP state (like basis information) into solver */
10062  SCIP_LP* lp, /**< LP data */
10063  BMS_BLKMEM* blkmem, /**< block memory */
10064  SCIP_SET* set, /**< global SCIP settings */
10065  SCIP_PROB* prob, /**< problem data */
10066  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10067  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10068  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10069  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10070  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10071  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10072  )
10073 {
10074  assert(lp != NULL);
10075  assert(blkmem != NULL);
10076 
10077  /* flush changes to the LP solver */
10078  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
10079  assert(lp->flushed);
10080 
10081  if( lp->solved && lp->solisbasic )
10082  return SCIP_OKAY;
10083 
10084  /* set LPI state in the LP solver */
10085  if( lpistate == NULL )
10086  lp->solisbasic = FALSE;
10087  else
10088  {
10089  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10090  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10091  }
10092  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10093  * flushed and solved, also, e.g., when we hit the iteration limit
10094  */
10095  lp->primalfeasible = wasprimfeas;
10096  lp->primalchecked = wasprimchecked;
10097  lp->dualfeasible = wasdualfeas;
10098  lp->dualchecked = wasdualchecked;
10099 
10100  return SCIP_OKAY;
10101 }
10102 
10103 /** frees LP state information */
10105  SCIP_LP* lp, /**< LP data */
10106  BMS_BLKMEM* blkmem, /**< block memory */
10107  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10108  )
10109 {
10110  assert(lp != NULL);
10111 
10112  if( *lpistate != NULL )
10113  {
10114  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10115  }
10116 
10117  return SCIP_OKAY;
10118 }
10119 
10120 /** interrupts the currently ongoing lp solve, or disables the interrupt */
10122  SCIP_LP* lp, /**< LP data */
10123  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
10124  )
10125 {
10126  assert(lp != NULL);
10127 
10128  if( lp->lpi == NULL )
10129  return SCIP_OKAY;
10130 
10131  SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
10132 
10133  return SCIP_OKAY;
10134 }
10135 
10136 /** stores pricing norms into LP norms object */
10138  SCIP_LP* lp, /**< LP data */
10139  BMS_BLKMEM* blkmem, /**< block memory */
10140  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10141  )
10142 {
10143  assert(lp != NULL);
10144  assert(lp->flushed);
10145  assert(lp->solved);
10146  assert(blkmem != NULL);
10147  assert(lpinorms != NULL);
10148 
10149  /* check whether there is no lp */
10150  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10151  *lpinorms = NULL;
10152  else
10153  {
10154  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10155  }
10156 
10157  return SCIP_OKAY;
10158 }
10159 
10160 /** loads pricing norms from LP norms object into solver */
10162  SCIP_LP* lp, /**< LP data */
10163  BMS_BLKMEM* blkmem, /**< block memory */
10164  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10165  )
10166 {
10167  assert(lp != NULL);
10168  assert(blkmem != NULL);
10169  assert(lp->flushed);
10170 
10171  /* set LPI norms in the LP solver */
10172  if( lpinorms != NULL )
10173  {
10174  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10175  }
10176 
10177  return SCIP_OKAY;
10178 }
10179 
10180 /** frees pricing norms information */
10182  SCIP_LP* lp, /**< LP data */
10183  BMS_BLKMEM* blkmem, /**< block memory */
10184  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10185  )
10186 {
10187  assert(lp != NULL);
10188 
10189  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10190 
10191  return SCIP_OKAY;
10192 }
10193 
10194 /** return the current cutoff bound of the lp */
10196  SCIP_LP* lp /**< current LP data */
10197  )
10198 {
10199  assert(lp != NULL);
10200 
10201  return lp->cutoffbound;
10202 }
10203 
10204 /** sets the upper objective limit of the LP solver */
10206  SCIP_LP* lp, /**< current LP data */
10207  SCIP_SET* set, /**< global SCIP settings */
10208  SCIP_PROB* prob, /**< problem data */
10209  SCIP_Real cutoffbound /**< new upper objective limit */
10210  )
10211 {
10212  assert(lp != NULL);
10213 
10214  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10215 
10216  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10217  * in SCIPendDive())
10218  */
10219  if( SCIPlpDivingObjChanged(lp) )
10220  {
10221  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10222  return SCIP_OKAY;
10223  }
10224 
10225  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10226  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10227  {
10228  /* mark the current solution invalid */
10229  lp->solved = FALSE;
10230  lp->lpobjval = SCIP_INVALID;
10232  }
10233  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10234  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10235  */
10236  else if( !lpCutoffDisabled(set, prob) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
10237  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10238  {
10239  assert(lp->flushed);
10240  assert(lp->solved);
10242  }
10243 
10244  lp->cutoffbound = cutoffbound;
10245 
10246  return SCIP_OKAY;
10247 }
10248 
10249 /** gets current primal feasibility tolerance of LP solver */
10251  SCIP_LP* lp /**< current LP data */
10252  )
10253 {
10254  assert(lp != NULL);
10255 
10256  return lp->feastol;
10257 }
10258 
10259 /** sets primal feasibility tolerance of LP solver */
10261  SCIP_LP* lp, /**< current LP data */
10262  SCIP_SET* set, /**< global SCIP settings */
10263  SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10264  )
10265 {
10266  assert(lp != NULL);
10267  assert(newfeastol > 0.0);
10268 
10269  SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10270 
10271  /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10272  if( newfeastol < lp->feastol )
10273  {
10274  lp->solved = FALSE;
10276  }
10277 
10278  lp->feastol = newfeastol;
10279 }
10280 
10281 /** resets primal feasibility tolerance of LP solver
10282  *
10283  * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10284  */
10286  SCIP_LP* lp, /**< current LP data */
10287  SCIP_SET* set /**< global SCIP settings */
10288  )
10289 {
10290  assert(lp != NULL);
10291 
10292  SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10293 
10294  if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10295  SCIPlpSetFeastol(lp, set, MIN(SCIPsetRelaxfeastol(set), SCIPsetLPFeastolFactor(set) * SCIPsetFeastol(set))); /*lint !e666*/
10296  else
10298 }
10299 
10300 /** returns the name of the given LP algorithm */
10301 static
10302 const char* lpalgoName(
10303  SCIP_LPALGO lpalgo /**< LP algorithm */
10304  )
10305 {
10306  switch( lpalgo )
10307  {
10309  return "primal simplex";
10311  return "dual simplex";
10312  case SCIP_LPALGO_BARRIER:
10313  return "barrier";
10315  return "barrier/crossover";
10316  default:
10317  SCIPerrorMessage("invalid LP algorithm\n");
10318  SCIPABORT();
10319  return "invalid"; /*lint !e527*/
10320  }
10321 }
10322 
10323 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10324 static
10326  SCIP_LP* lp, /**< current LP data */
10327  SCIP_SET* set, /**< global SCIP settings */
10328  SCIP_STAT* stat, /**< problem statistics */
10329  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10330  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10331  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10332  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10333  )
10334 {
10335  SCIP_Real timedelta;
10336  SCIP_RETCODE retcode;
10337  int iterations;
10338 
10339  assert(lp != NULL);
10340  assert(lp->flushed);
10341  assert(set != NULL);
10342  assert(stat != NULL);
10343  assert(lperror != NULL);
10344 
10345  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",
10346  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10347 
10348  *lperror = FALSE;
10349 
10350 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10351  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10352  {
10353  char fname[SCIP_MAXSTRLEN];
10354  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10355  SCIP_CALL( SCIPlpWrite(lp, fname) );
10356  SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10357  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10358  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10359  }
10360 #endif
10361 
10362  /* start timing */
10363  if( lp->diving || lp->probing )
10364  {
10365  if( lp->strongbranchprobing )
10366  SCIPclockStart(stat->strongbranchtime, set);
10367  else
10368  SCIPclockStart(stat->divinglptime, set);
10369 
10370  timedelta = 0.0; /* unused for diving or probing */
10371  }
10372  else
10373  {
10374  SCIPclockStart(stat->primallptime, set);
10375  timedelta = -SCIPclockGetTime(stat->primallptime);
10376  }
10377 
10378  /* if this is a call to resolve an instable LP, collect time */
10379  if( instable )
10380  {
10382  }
10383 
10384  /* call primal simplex */
10385  retcode = SCIPlpiSolvePrimal(lp->lpi);
10386  if( retcode == SCIP_LPERROR )
10387  {
10388  *lperror = TRUE;
10389  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10390  }
10391  else
10392  {
10393  SCIP_CALL( retcode );
10394  }
10396  lp->solisbasic = TRUE;
10397 
10398  /* stop timing */
10399  if( lp->diving || lp->probing )
10400  {
10401  if( lp->strongbranchprobing )
10402  SCIPclockStop(stat->strongbranchtime, set);
10403  else
10404  SCIPclockStop(stat->divinglptime, set);
10405  }
10406  else
10407  {
10408  timedelta += SCIPclockGetTime(stat->primallptime);
10409  SCIPclockStop(stat->primallptime, set);
10410  }
10411 
10412  if ( instable )
10413  {
10415  }
10416 
10417  /* count number of iterations */
10418  SCIPstatIncrement(stat, set, lpcount);
10419  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10420  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10421  {
10422  if( !lp->strongbranchprobing )
10423  {
10424  SCIPstatIncrement(stat, set, nlps);
10425  SCIPstatAdd( stat, set, nlpiterations, iterations );
10426  }
10427  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10428  {
10429  SCIPstatIncrement(stat, set, nprimalresolvelps );
10430  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10431  }
10432  if ( instable )
10433  {
10434  SCIPstatIncrement(stat, set, nresolveinstablelps);
10435  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10436  }
10437  if( lp->diving || lp->probing )
10438  {
10439  if( lp->strongbranchprobing )
10440  {
10441  SCIPstatIncrement(stat, set, nsbdivinglps);
10442  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10443  }
10444  else
10445  {
10446  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10447  SCIPstatIncrement(stat, set, ndivinglps);
10448  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10449  }
10450  }
10451  else
10452  {
10453  SCIPstatIncrement(stat, set, nprimallps);
10454  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10455  }
10456  }
10457  else
10458  {
10459  if ( ! lp->diving && ! lp->probing )
10460  {
10461  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10462  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10463  }
10464 
10465  if ( keepsol && !(*lperror) )
10466  {
10467  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10468  if( lp->validsollp == stat->lpcount-1 )
10469  lp->validsollp = stat->lpcount;
10470  if( lp->validfarkaslp == stat->lpcount-1 )
10471  lp->validfarkaslp = stat->lpcount;
10472  }
10473  }
10474 
10475  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10476  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10477 
10478  return SCIP_OKAY;
10479 }
10480 
10481 /** calls LPI to perform dual simplex, measures time and counts iterations */
10482 static
10484  SCIP_LP* lp, /**< current LP data */
10485  SCIP_SET* set, /**< global SCIP settings */
10486  SCIP_STAT* stat, /**< problem statistics */
10487  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10488  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10489  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10490  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10491  )
10492 {
10493  SCIP_Real timedelta;
10494  SCIP_RETCODE retcode;
10495  int iterations;
10496 
10497  assert(lp != NULL);
10498  assert(lp->flushed);
10499  assert(set != NULL);
10500  assert(stat != NULL);
10501  assert(lperror != NULL);
10502 
10503  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",
10504  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10505 
10506  *lperror = FALSE;
10507 
10508 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10509  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10510  {
10511  char fname[SCIP_MAXSTRLEN];
10512  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10513  SCIP_CALL( SCIPlpWrite(lp, fname) );
10514  SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10515  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10516  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10517  }
10518 #endif
10519 
10520  /* start timing */
10521  if( lp->diving || lp->probing )
10522  {
10523  if( lp->strongbranchprobing )
10524  SCIPclockStart(stat->strongbranchtime, set);
10525  else
10526  SCIPclockStart(stat->divinglptime, set);
10527 
10528  timedelta = 0.0; /* unused for diving or probing */
10529  }
10530  else
10531  {
10532  SCIPclockStart(stat->duallptime, set);
10533  timedelta = -SCIPclockGetTime(stat->duallptime);
10534  }
10535 
10536  /* if this is a call to resolve an instable LP, collect time */
10537  if ( instable )
10538  {
10540  }
10541 
10542  /* call dual simplex */
10543  retcode = SCIPlpiSolveDual(lp->lpi);
10544  if( retcode == SCIP_LPERROR )
10545  {
10546  *lperror = TRUE;
10547  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10548  }
10549  else
10550  {
10551  SCIP_CALL( retcode );
10552  }
10554  lp->solisbasic = TRUE;
10555 
10556  /* stop timing */
10557  if( lp->diving || lp->probing )
10558  {
10559  if( lp->strongbranchprobing )
10560  SCIPclockStop(stat->strongbranchtime, set);
10561  else
10562  SCIPclockStop(stat->divinglptime, set);
10563  }
10564  else
10565  {
10566  timedelta += SCIPclockGetTime(stat->duallptime);
10567  SCIPclockStop(stat->duallptime, set);
10568  }
10569 
10570  if ( instable )
10571  {
10573  }
10574 
10575  /* count number of iterations */
10576  SCIPstatIncrement(stat, set, lpcount);
10577  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10578  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10579  {
10580  if( !lp->strongbranchprobing )
10581  {
10582  SCIPstatIncrement(stat, set, nlps);
10583  SCIPstatAdd(stat, set, nlpiterations, iterations);
10584  }
10585  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10586  {
10587  SCIPstatIncrement(stat, set, ndualresolvelps);
10588  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10589  }
10590  if ( instable )
10591  {
10592  SCIPstatIncrement(stat, set, nresolveinstablelps);
10593  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10594  }
10595  if( lp->diving || lp->probing )
10596  {
10597  if( lp->strongbranchprobing )
10598  {
10599  SCIPstatIncrement(stat, set, nsbdivinglps);
10600  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10601  }
10602  else
10603  {
10604  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10605  SCIPstatIncrement(stat, set, ndivinglps);
10606  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10607  }
10608  }
10609  else
10610  {
10611  SCIPstatIncrement(stat, set, nduallps);
10612  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10613  }
10614  }
10615  else
10616  {
10617  if ( ! lp->diving && ! lp->probing )
10618  {
10619  SCIPstatIncrement(stat, set, ndualzeroitlps);
10620  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10621  }
10622 
10623  if( keepsol && !(*lperror) )
10624  {
10625  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10626  if( lp->validsollp == stat->lpcount-1 )
10627  lp->validsollp = stat->lpcount;
10628  if( lp->validfarkaslp == stat->lpcount-1 )
10629  lp->validfarkaslp = stat->lpcount;
10630  }
10631  }
10632 
10633  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10634  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10635 
10636  return SCIP_OKAY;
10637 }
10638 
10639 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10640  *
10641  * We follow the approach of the following paper to find a lexicographically minimal optimal
10642  * solution:
10643  *
10644  * Zanette, Fischetti, Balas@n
10645  * Can pure cutting plane algorithms work?@n
10646  * IPCO 2008, Bertinoro, Italy.
10647  *
10648  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10649  * heuristic, i.e., we limit the number of components which are minimized.
10650  *
10651  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10652  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10653  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10654  * pivots that will not change the objective are allowed afterwards.
10655  *
10656  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10657  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10658  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10659  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10660  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10661  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10662  * reduced cost. We then choose the next variable and iterate.
10663  *
10664  * We stop the process once we do not find candidates or have performed a maximum number of
10665  * iterations.
10666  *
10667  * @todo Does this really produce a lexicographically minimal solution?
10668  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10669  * guarantee that these variables will not be changed in later stages? We can fix these variables
10670  * to their lower bound, but this destroys the basis.
10671  * @todo Should we use lexicographical minimization in diving/probing or not?
10672  */
10673 static
10675  SCIP_LP* lp, /**< current LP data */
10676  SCIP_SET* set, /**< global SCIP settings */
10677  SCIP_STAT* stat, /**< problem statistics */
10678  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10679  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10680  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10681  )
10682 {
10683  SCIP_Real timedelta;
10684  SCIP_RETCODE retcode;
10685  int totalIterations;
10686  int lexIterations;
10687  int iterations;
10688  int rounds;
10689 
10690  assert(lp != NULL);
10691  assert(lp->flushed);
10692  assert(set != NULL);
10693  assert(stat != NULL);
10694  assert(lperror != NULL);
10695 
10696  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",
10697  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10698 
10699  *lperror = FALSE;
10700 
10701  /* start timing */
10702  if( lp->diving || lp->probing )
10703  {
10704  if( lp->strongbranchprobing )
10705  SCIPclockStart(stat->strongbranchtime, set);
10706  else
10707  SCIPclockStart(stat->divinglptime, set);
10708 
10709  timedelta = 0.0; /* unused for diving or probing */
10710  }
10711  else
10712  {
10713  SCIPclockStart(stat->duallptime, set);
10714  timedelta = -SCIPclockGetTime(stat->duallptime);
10715  }
10716 
10717  /* call dual simplex for first lp */
10718  retcode = SCIPlpiSolveDual(lp->lpi);
10719  if( retcode == SCIP_LPERROR )
10720  {
10721  *lperror = TRUE;
10722  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10723  }
10724  else
10725  {
10726  SCIP_CALL( retcode );
10727  }
10728  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10729  totalIterations = iterations;
10730 
10731  /* stop timing */
10732  if( lp->diving || lp->probing )
10733  {
10734  if( lp->strongbranchprobing )
10735  SCIPclockStop(stat->strongbranchtime, set);
10736  else
10737  SCIPclockStop(stat->divinglptime, set);
10738  }
10739  else
10740  {
10741  timedelta += SCIPclockGetTime(stat->duallptime);
10742  SCIPclockStop(stat->duallptime, set);
10743  }
10744 
10745  /* count number of iterations */
10746  SCIPstatIncrement(stat, set, lpcount);
10747  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10748  {
10749  if( lp->strongbranchprobing )
10750  {
10751  SCIPstatAdd(stat, set, nlpiterations, iterations);
10752  }
10753  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10754  {
10755  SCIPstatIncrement(stat, set, ndualresolvelps);
10756  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10757  }
10758  if( lp->diving || lp->probing )
10759  {
10760  if( lp->strongbranchprobing )
10761  {
10762  SCIPstatIncrement(stat, set, nsbdivinglps);
10763  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10764  }
10765  else
10766  {
10767  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10768  SCIPstatIncrement(stat, set, ndivinglps);
10769  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10770  }
10771  }
10772  else
10773  {
10774  SCIPstatIncrement(stat, set, nduallps);
10775  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10776  }
10777  }
10778  else
10779  {
10780  if ( ! lp->diving && ! lp->probing )
10781  {
10782  SCIPstatIncrement(stat, set, ndualzeroitlps);
10783  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10784  }
10785  }
10786  lexIterations = 0;
10787 
10788  /* search for lexicographically minimal optimal solution */
10789  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10790  {
10791  SCIP_Bool chooseBasic;
10792  SCIP_Real* primsol;
10793  SCIP_Real* dualsol;
10794  SCIP_Real* redcost;
10795  int* cstat;
10796  int* rstat;
10797  SCIP_Real* newobj;
10798  SCIP_Real* newlb;
10799  SCIP_Real* newub;
10800  SCIP_Real* newlhs;
10801  SCIP_Real* newrhs;
10802  SCIP_Real* oldlb;
10803  SCIP_Real* oldub;
10804  SCIP_Real* oldlhs;
10805  SCIP_Real* oldrhs;
10806  SCIP_Real* oldobj;
10807  SCIP_Bool* fixedc;
10808  SCIP_Bool* fixedr;
10809  int* indcol;
10810  int* indrow;
10811  int* indallcol;
10812  int* indallrow;
10813  int nDualDeg;
10814  int r, c;
10815  int cntcol;
10816  int cntrow;
10817  int nruns;
10818  int pos;
10819 
10820  chooseBasic = set->lp_lexdualbasic;
10821 
10822  /* start timing */
10823  SCIPclockStart(stat->lexduallptime, set);
10824 
10825  /* get all solution information */
10826  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10827  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10828  if( chooseBasic )
10829  {
10830  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10831  }
10832  else
10833  primsol = NULL;
10834 
10835  /* get basic and nonbasic information */
10836  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10837  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10838 
10839  /* save bounds, lhs/rhs, and objective */
10840  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10841  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10842  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10843  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10844  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10845  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10846  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10847  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10848 
10849  /* get storage for several arrays */
10850  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10851  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10852  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10853 
10854  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10855  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10856  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10857 
10858  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10859  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10860 
10861  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10862  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10863 
10864  /* initialize: set objective to 0, get fixed variables */
10865  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10866  for( c = 0; c < lp->nlpicols; ++c )
10867  {
10868  newobj[c] = 0.0;
10869  indallcol[c] = c;
10870  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10871  fixedc[c] = TRUE;
10872  else
10873  fixedc[c] = FALSE;
10874  }
10875 
10876  /* initialize: get fixed slack variables */
10877  for( r = 0; r < lp->nlpirows; ++r )
10878  {
10879  indallrow[r] = r;
10880  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10881  fixedr[r] = TRUE;
10882  else
10883  fixedr[r] = FALSE;
10884  }
10885 
10886 #ifdef DEBUG_LEXDUAL
10887  {
10888  int j;
10889 
10890  if( !chooseBasic )
10891  {
10892  assert(primsol == NULL);
10893  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10894  }
10895  assert(primsol != NULL);
10896  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10897  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10898 
10899  for( j = 0; j < lp->nlpicols; ++j )
10900  {
10901  if( fixedc[j] )
10902  {
10903  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10904  }
10905  else
10906  {
10907  char type;
10908  switch( (SCIP_BASESTAT) cstat[j] )
10909  {
10910  case SCIP_BASESTAT_LOWER:
10911  type = 'l';
10912  break;
10913  case SCIP_BASESTAT_UPPER:
10914  type = 'u';
10915  break;
10916  case SCIP_BASESTAT_ZERO:
10917  type = 'z';
10918  break;
10919  case SCIP_BASESTAT_BASIC:
10920  type = 'b';
10921  break;
10922  default:
10923  type = '?';
10924  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10925  SCIPABORT();
10926  }
10927  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10928  }
10929  }
10930  SCIPsetDebugMsg(set, "\n\n");
10931 
10932  if( !chooseBasic )
10933  {
10934  SCIPsetFreeBufferArray(set, &primsol);
10935  assert(primsol == NULL);
10936  }
10937  }
10938 #endif
10939 
10940  /* perform lexicographic rounds */
10941  pos = -1;
10942  nruns = 0;
10943  rounds = 0;
10944  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10945  do
10946  {
10947  int oldpos;
10948 
10949  /* get current solution */
10950  if( chooseBasic )
10951  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10952  else
10953  {
10954  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10955  assert(primsol == NULL);
10956  }
10957 
10958  /* get current basis */
10959  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10960 
10961  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10962  nDualDeg = 0;
10963  cntcol = 0;
10964  oldpos = pos;
10965  pos = -1;
10966  for( c = 0; c < lp->nlpicols; ++c )
10967  {
10968  if( !fixedc[c] )
10969  {
10970  /* check whether variable is in basis */
10971  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10972  {
10973  /* store first candidate */
10974  if( pos == -1 && c > oldpos )
10975  {
10976  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10977  pos = c;
10978  }
10979  }
10980  else
10981  {
10982  /* reduced cost == 0 -> possible candidate */
10983  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10984  {
10985  ++nDualDeg;
10986  /* only if we have not yet found a candidate */
10987  if( pos == -1 && c > oldpos )
10988  {
10989  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10990  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10991  {
10992  newlb[cntcol] = oldlb[c];
10993  newub[cntcol] = oldlb[c];
10994  indcol[cntcol++] = c;
10995  fixedc[c] = TRUE;
10996  }
10997  else /* found a non-fixed candidate */
10998  {
10999  if( !chooseBasic )
11000  pos = c;
11001  }
11002  }
11003  }
11004  else
11005  {
11006  /* nonzero reduced cost -> variable can be fixed */
11007  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
11008  {
11009  newlb[cntcol] = oldlb[c];
11010  newub[cntcol] = oldlb[c];
11011  }
11012  else
11013  {
11014  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
11015  {
11016  newlb[cntcol] = oldub[c];
11017  newub[cntcol] = oldub[c];
11018  }
11019  else
11020  {
11021  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
11022  newlb[cntcol] = 0.0;
11023  newub[cntcol] = 0.0;
11024  }
11025  }
11026  indcol[cntcol++] = c;
11027  fixedc[c] = TRUE;
11028  }
11029  }
11030  }
11031  }
11032 
11033  /* check rows */
11034  cntrow = 0;
11035  for( r = 0; r < lp->nlpirows; ++r )
11036  {
11037  if( !fixedr[r] )
11038  {
11039  /* consider only nonbasic rows */
11040  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11041  {
11042  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
11043  if( SCIPsetIsFeasZero(set, dualsol[r]) )
11044  ++nDualDeg;
11045  else
11046  {
11047  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11048  {
11049  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11050  newlhs[cntrow] = oldlhs[r];
11051  newrhs[cntrow] = oldlhs[r];
11052  }
11053  else
11054  {
11055  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11056  newlhs[cntrow] = oldrhs[r];
11057  newrhs[cntrow] = oldrhs[r];
11058  }
11059  indrow[cntrow++] = r;
11060  fixedr[r] = TRUE;
11061  }
11062  }
11063  }
11064  }
11065 
11066  if( nDualDeg > 0 && pos >= 0 )
11067  {
11068  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11069 
11070  /* change objective */
11071  if( nruns == 0 )
11072  {
11073  /* set objective to appropriate unit vector for first run */
11074  newobj[pos] = 1.0;
11075  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11076  }
11077  else
11078  {
11079  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11080  SCIP_Real obj = 1.0;
11081  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11082  }
11083 
11084  /* fix variables */
11085  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11086  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11087 
11088  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11089  retcode = SCIPlpiSolvePrimal(lp->lpi);
11090  if( retcode == SCIP_LPERROR )
11091  {
11092  *lperror = TRUE;
11093  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11094  }
11095  else
11096  {
11097  SCIP_CALL( retcode );
11098  }
11099  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11100  lexIterations += iterations;
11101 
11102 #ifdef DEBUG_LEXDUAL
11103  if( iterations > 0 )
11104  {
11105  int j;
11106 
11107  if( !chooseBasic )
11108  {
11109  assert(primsol == NULL);
11110  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
11111  }
11112  assert(primsol != NULL);
11113  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
11114 
11115  for( j = 0; j < lp->nlpicols; ++j )
11116  {
11117  if( fixedc[j] )
11118  {
11119  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11120  }
11121  else
11122  {
11123  char cstart = '[';
11124  char cend = ']';
11125  char type;
11126 
11127  if(j == pos)
11128  {
11129  cstart = '*';
11130  cend = '*';
11131  }
11132 
11133  switch( (SCIP_BASESTAT) cstat[j] )
11134  {
11135  case SCIP_BASESTAT_LOWER:
11136  type = 'l';
11137  break;
11138  case SCIP_BASESTAT_UPPER:
11139  type = 'u';
11140  break;
11141  case SCIP_BASESTAT_ZERO:
11142  type = 'z';
11143  break;
11144  case SCIP_BASESTAT_BASIC:
11145  type = 'b';
11146  break;
11147  default:
11148  type = '?';
11149  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11150  SCIPABORT();
11151  }
11152  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11153  }
11154  }
11155  SCIPsetDebugMsg(set, "\n\n");
11156 
11157  if( !chooseBasic )
11158  {
11159  SCIPsetFreeBufferArray(set, &primsol);
11160  assert(primsol == NULL);
11161  }
11162  }
11163 #endif
11164 
11165  /* count only as round if iterations have been performed */
11166  if( iterations > 0 )
11167  ++rounds;
11168  ++nruns;
11169  }
11170  }
11171  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11172 
11173  /* reset bounds, lhs/rhs, and obj */
11174  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11175  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11176  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11177 
11178  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
11179  retcode = SCIPlpiSolveDual(lp->lpi);
11180  if( retcode == SCIP_LPERROR )
11181  {
11182  *lperror = TRUE;
11183  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11184  }
11185  else
11186  {
11187  SCIP_CALL( retcode );
11188  }
11189  assert(SCIPlpiIsOptimal(lp->lpi));
11190  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11191  lexIterations += iterations;
11192 
11193  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11194 
11195  /* count number of iterations */
11196  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11197  SCIPstatIncrement(stat, set, nlps);
11198 
11199  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11200  {
11201  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11202  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11203  {
11204  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11205  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11206  }
11207  SCIPstatIncrement(stat, set, nlexduallps);
11208  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11209 
11210  totalIterations += lexIterations;
11211  }
11212 
11213  /* free space */
11214  SCIPsetFreeBufferArray(set, &newobj);
11215 
11216  SCIPsetFreeBufferArray(set, &fixedr);
11217  SCIPsetFreeBufferArray(set, &fixedc);
11218 
11219  SCIPsetFreeBufferArray(set, &indallrow);
11220  SCIPsetFreeBufferArray(set, &indallcol);
11221 
11222  SCIPsetFreeBufferArray(set, &indrow);
11223  SCIPsetFreeBufferArray(set, &newrhs);
11224  SCIPsetFreeBufferArray(set, &newlhs);
11225 
11226  SCIPsetFreeBufferArray(set, &indcol);
11227  SCIPsetFreeBufferArray(set, &newub);
11228  SCIPsetFreeBufferArray(set, &newlb);
11229 
11230  SCIPsetFreeBufferArray(set, &oldobj);
11231  SCIPsetFreeBufferArray(set, &oldrhs);
11232  SCIPsetFreeBufferArray(set, &oldlhs);
11233  SCIPsetFreeBufferArray(set, &oldub);
11234  SCIPsetFreeBufferArray(set, &oldlb);
11235 
11236  SCIPsetFreeBufferArray(set, &rstat);
11237  SCIPsetFreeBufferArray(set, &cstat);
11238 
11239  SCIPsetFreeBufferArray(set, &redcost);
11240  SCIPsetFreeBufferArray(set, &dualsol);
11241  if( chooseBasic )
11242  SCIPsetFreeBufferArray(set, &primsol);
11243 
11244  /* stop timing */
11245  SCIPclockStop(stat->lexduallptime, set);
11246 
11247  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11248  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11249  }
11251  lp->solisbasic = TRUE;
11252 
11253  if( totalIterations > 0 && !lp->strongbranchprobing )
11254  SCIPstatIncrement(stat, set, nlps);
11255  else
11256  {
11257  if( keepsol && !(*lperror) )
11258  {
11259  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11260  if( lp->validsollp == stat->lpcount-1 )
11261  lp->validsollp = stat->lpcount;
11262  if( lp->validfarkaslp == stat->lpcount-1 )
11263  lp->validfarkaslp = stat->lpcount;
11264  }
11265  }
11266 
11267  return SCIP_OKAY;
11268 }
11269 
11270 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11271 static
11273  SCIP_LP* lp, /**< current LP data */
11274  SCIP_SET* set, /**< global SCIP settings */
11275  SCIP_STAT* stat, /**< problem statistics */
11276  SCIP_Bool crossover, /**< should crossover be performed? */
11277  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11278  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11279  )
11280 {
11281  SCIP_Real timedelta;
11282  SCIP_RETCODE retcode;
11283  int iterations;
11284 
11285  assert(lp != NULL);
11286  assert(lp->flushed);
11287  assert(set != NULL);
11288  assert(stat != NULL);
11289  assert(lperror != NULL);
11290 
11291  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",
11292  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11293  stat->nbarrierlps, stat->ndivinglps);
11294 
11295  *lperror = FALSE;
11296 
11297 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11298  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11299  {
11300  char fname[SCIP_MAXSTRLEN];
11301  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11302  SCIP_CALL( SCIPlpWrite(lp, fname) );
11303  SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11304  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11305  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11306  }
11307 #endif
11308 
11309  /* start timing */
11310  if( lp->diving || lp->probing )
11311  {
11312  if( lp->strongbranchprobing )
11313  SCIPclockStart(stat->strongbranchtime, set);
11314  else
11315  SCIPclockStart(stat->divinglptime, set);
11316 
11317  timedelta = 0.0; /* unused for diving or probing */
11318  }
11319  else
11320  {
11321  SCIPclockStart(stat->barrierlptime, set);
11322  timedelta = -SCIPclockGetTime(stat->barrierlptime);
11323  }
11324 
11325  /* call barrier algorithm */
11326  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11327  if( retcode == SCIP_LPERROR )
11328  {
11329  *lperror = TRUE;
11330  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11331  }
11332  else
11333  {
11334  SCIP_CALL( retcode );
11335  }
11337  lp->solisbasic = crossover;
11338 
11339  /* stop timing */
11340  if( lp->diving || lp->probing )
11341  {
11342  if( lp->strongbranchprobing )
11343  SCIPclockStop(stat->strongbranchtime, set);
11344  else
11345  SCIPclockStop(stat->divinglptime, set);
11346  }
11347  else
11348  {
11349  SCIPclockStop(stat->barrierlptime, set);
11350  timedelta += SCIPclockGetTime(stat->barrierlptime);
11351  }
11352 
11353  /* count number of iterations */
11354  SCIPstatIncrement(stat, set, lpcount);
11355  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11356  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11357  {
11358  if( !lp->strongbranchprobing )
11359  {
11360  SCIPstatIncrement(stat, set, nlps);
11361  SCIPstatAdd(stat, set, nlpiterations, iterations);
11362  }
11363  if( lp->diving || lp->probing )
11364  {
11365  if( lp->strongbranchprobing )
11366  {
11367  SCIPstatIncrement(stat, set, nsbdivinglps);
11368  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11369  }
11370  else
11371  {
11372  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11373  SCIPstatIncrement(stat, set, ndivinglps);
11374  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11375  }
11376  }
11377  else
11378  {
11379  SCIPstatIncrement(stat, set, nbarrierlps);
11380  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11381  }
11382  }
11383  else
11384  {
11385  if ( ! lp->diving && ! lp->probing )
11386  {
11387  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11388  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11389  }
11390 
11391  if( keepsol && !(*lperror) )
11392  {
11393  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11394  if( lp->validsollp == stat->lpcount-1 )
11395  lp->validsollp = stat->lpcount;
11396  if( lp->validfarkaslp == stat->lpcount-1 )
11397  lp->validfarkaslp = stat->lpcount;
11398  }
11399  }
11400 
11401  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11402  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11403 
11404  return SCIP_OKAY;
11405 }
11406 
11407 /** solves the LP with the given algorithm */
11408 static
11410  SCIP_LP* lp, /**< current LP data */
11411  SCIP_SET* set, /**< global SCIP settings */
11412  SCIP_STAT* stat, /**< problem statistics */
11413  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11414  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11415  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11416  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11417  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11418  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11419  )
11420 {
11421  SCIP_Real lptimelimit;
11422  SCIP_Bool success;
11423 
11424  assert(lp != NULL);
11425  assert(lp->flushed);
11426  assert(lperror != NULL);
11427 
11428  /* check if a time limit is set, and set time limit for LP solver accordingly */
11429  lptimelimit = SCIPlpiInfinity(lp->lpi);
11430  if( set->istimelimitfinite )
11431  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11432 
11433  success = FALSE;
11434  if( lptimelimit > 0.0 )
11435  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11436 
11437  if( lptimelimit <= 0.0 || !success )
11438  {
11439  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11440  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11441  *timelimit = TRUE;
11442  return SCIP_OKAY;
11443  }
11444  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11445 
11446  /* call appropriate LP algorithm */
11447  switch( lpalgo )
11448  {
11450  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11451  break;
11452 
11454  /* run dual lexicographic simplex if required */
11455  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11456  {
11457  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11458  }
11459  else
11460  {
11461  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11462  }
11463  break;
11464 
11465  case SCIP_LPALGO_BARRIER:
11466  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11467  break;
11468 
11470  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11471  break;
11472 
11473  default:
11474  SCIPerrorMessage("invalid LP algorithm\n");
11475  return SCIP_INVALIDDATA;
11476  }
11477 
11478  if( !(*lperror) )
11479  {
11480  /* check for primal and dual feasibility */
11482 
11483  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11484  }
11485 
11486  return SCIP_OKAY;
11487 }
11488 
11489 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11490  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11491  */
11492 #define MAXNUMTROUBLELPMSGS 10
11493 
11494 /** prints message about numerical trouble
11495  *
11496  * If message has verblevel at most high and display/verblevel is not full,
11497  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11498  * were printed before in the current run.
11499  */
11500 static
11502  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11503  SCIP_SET* set, /**< global SCIP settings */
11504  SCIP_STAT* stat, /**< problem statistics */
11505  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11506  const char* formatstr, /**< message format string */
11507  ... /**< arguments to format string */
11508  )
11509 {
11510  va_list ap;
11511 
11512  assert(verblevel > SCIP_VERBLEVEL_NONE);
11513  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11514  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11515 
11516  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11517  {
11518  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11519  {
11520  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11522  return;
11523 
11524  /* increase count on messages with verblevel high */
11525  ++stat->nnumtroublelpmsgs ;
11526  }
11527 
11528  /* if messages wouldn't be printed, then return already */
11529  if( verblevel > set->disp_verblevel )
11530  return;
11531  }
11532 
11533  /* print common begin of message */
11534  SCIPmessagePrintInfo(messagehdlr,
11535  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11536  stat->nnodes, stat->nlps);
11537 
11538  /* print individual part of message */
11539  va_start(ap, formatstr); /*lint !e838*/
11540  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11541  va_end(ap);
11542 
11543  /* warn that further messages will be suppressed */
11544  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11545  {
11546  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11547  }
11548 
11549  /* print closing new-line */
11550  SCIPmessagePrintInfo(messagehdlr, "\n");
11551 }
11552 
11553 static
11555  SCIP_LP* lp, /**< current LP data */
11556  SCIP_SET* set, /**< global SCIP settings */
11557  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11558  SCIP_STAT* stat, /**< problem statistics */
11559  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11560  SCIP_Bool* success /**< was instability successfully ignored */
11561  )
11562 {
11563  assert(lp != NULL);
11564  assert(set != NULL);
11565 
11566  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11567 
11568  if( *success )
11569  {
11570  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11571  if( !set->lp_checkdualfeas )
11572  lp->dualfeasible = TRUE;
11573  if( !set->lp_checkprimfeas )
11574  lp->primalchecked = TRUE;
11575  }
11576 
11577  return SCIP_OKAY;
11578 }
11579 
11580 #define FEASTOLTIGHTFAC 0.001
11581 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11582 static
11584  SCIP_LP* lp, /**< current LP data */
11585  SCIP_SET* set, /**< global SCIP settings */
11586  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11587  SCIP_STAT* stat, /**< problem statistics */
11588  SCIP_PROB* prob, /**< problem data */
11589  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11590  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11591  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11592  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11593  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11594  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11595  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11596  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11597  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
11598  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11599  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11600  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11601  )
11602 {
11603  SCIP_Bool success;
11604  SCIP_Bool success2;
11605  SCIP_Bool success3;
11606  SCIP_Bool simplex;
11607  SCIP_Bool itlimishard;
11608  SCIP_Bool usepolishing;
11609 
11610  assert(lp != NULL);
11611  assert(lp->flushed);
11612  assert(set != NULL);
11613  assert(stat != NULL);
11614  assert(lperror != NULL);
11615  assert(timelimit != NULL);
11616 
11617  *lperror = FALSE;
11618 
11619  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11620  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11621  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11622  * SCIP_LP such that we can return a primal ray
11623  */
11624  if( lp->looseobjvalinf > 0 )
11625  {
11626  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11627  return SCIP_ERROR;
11628  }
11629 
11630  /* check, whether we solve with a simplex algorithm */
11631  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11632 
11633  /* check whether the iteration limit is a hard one */
11634  itlimishard = (itlim == harditlim);
11635 
11636  /* check whether solution polishing should be used */
11637  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11638  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11639  {
11640  usepolishing = TRUE;
11641  if( lp->updateintegrality )
11642  {
11643  SCIP_CALL( lpCopyIntegrality(lp, set) );
11644  }
11645  }
11646  else
11647  usepolishing = FALSE;
11648 
11649  /* solve with given settings (usually fast but imprecise) */
11650  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11651  {
11652  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound, &success) );
11653  }
11654  else
11655  {
11656  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11657  }
11658  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11659  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11660  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11661  &success) );
11662  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11663  : SCIPsetBarrierconvtol(set), &success) );
11664  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11665  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11666  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11667  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11668  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11669  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11670  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11671  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11672  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11673  SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11674  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11675  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11676  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11677  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11678 
11679  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11680 
11681  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11682  * optimal without preforming scaling/change tolerances/presolving */
11683  resolve = FALSE;
11684 
11685  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11686  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11687  return SCIP_OKAY;
11688 
11689  if( !set->lp_checkstability )
11690  {
11691  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11692 
11693  if( success )
11694  return SCIP_OKAY;
11695  }
11696 
11697  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11698  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11699  */
11700 
11701  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11702  * do this only if the iteration limit was not exceeded in the last LP solving call
11703  */
11704  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11705  {
11706  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11707  if( success )
11708  {
11709  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11710  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11711 
11712  /* check for stability */
11713  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11714  return SCIP_OKAY;
11715 
11716  if( !set->lp_checkstability )
11717  {
11718  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11719 
11720  if( success )
11721  return SCIP_OKAY;
11722  }
11723  }
11724  }
11725 
11726  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11727  * and go directly to solving the LP from scratch
11728  */
11729  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11730  {
11731  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11732  SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
11733  if( success )
11734  {
11735  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11736  lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
11737  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11738 
11739  /* check for stability */
11740  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11741  return SCIP_OKAY;
11742 
11743  if( !set->lp_checkstability )
11744  {
11745  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11746 
11747  if( success )
11748  return SCIP_OKAY;
11749  }
11750 
11751  /* reset scaling */
11752  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11753  assert(success);
11754  }
11755  }
11756 
11757  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11758  * and go directly to solving the LP from scratch */
11759  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11760  {
11761  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11762  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11763  if( success )
11764  {
11765  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11766  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11767  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11768 
11769  /* check for stability */
11770  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11771  return SCIP_OKAY;
11772 
11773  if( !set->lp_checkstability )
11774  {
11775  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11776 
11777  if( success )
11778  return SCIP_OKAY;
11779  }
11780 
11781  /* reset presolving */
11782  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11783  assert(success);
11784  }
11785  }
11786 
11787  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11788  * do this only if the iteration limit was not exceeded in the last LP solving call
11789  */
11790  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11791  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11792  {
11793  success = FALSE;
11794  if( !tightprimfeastol )
11795  {
11796  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11797  }
11798 
11799  success2 = FALSE;
11800  if( !tightdualfeastol )
11801  {
11802  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11803  }
11804 
11805  success3 = FALSE;
11806  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11807  {
11808  SCIP_CALL( lpSetBarrierconvtol(lp, FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set), &success3) );
11809  }
11810 
11811  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11812  if( success || success2 || success3 )
11813  {
11814  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11815  lpalgoName(lpalgo));
11816  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11817 
11818  /* check for stability */
11819  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11820  return SCIP_OKAY;
11821 
11822  if( !set->lp_checkstability )
11823  {
11824  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11825 
11826  if( success )
11827  return SCIP_OKAY;
11828  }
11829 
11830  /* reset feasibility tolerance */
11831  if( !tightprimfeastol )
11832  {
11833  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11834  }
11835  if( !tightdualfeastol )
11836  {
11837  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11838  }
11839  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11840  {
11841  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11842  }
11843  }
11844  }
11845 
11846  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11847  * the given iteration limit might be a soft one to restrict resolving calls only */
11848  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11849 
11850  /* if not already done, solve again from scratch */
11851  if( !fromscratch && simplex )
11852  {
11853  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11854  if( success )
11855  {
11856  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11857  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11858 
11859  /* check for stability */
11860  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11861  return SCIP_OKAY;
11862 
11863  if( !set->lp_checkstability )
11864  {
11865  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11866 
11867  if( success )
11868  return SCIP_OKAY;
11869  }
11870  }
11871  }
11872 
11873  /* solve again, use other simplex this time */
11874  if( simplex )
11875  {
11877  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11878  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11879 
11880  /* check for stability */
11881  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11882  return SCIP_OKAY;
11883 
11884  if( !set->lp_checkstability )
11885  {
11886  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11887 
11888  if( success )
11889  return SCIP_OKAY;
11890  }
11891 
11892  /* solve again with opposite scaling and other simplex */
11893  SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
11894  if( success )
11895  {
11896  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11897  lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
11898  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11899 
11900  /* check for stability */
11901  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11902  return SCIP_OKAY;
11903 
11904  if( !set->lp_checkstability )
11905  {
11906  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11907 
11908  if( success )
11909  return SCIP_OKAY;
11910  }
11911 
11912  /* reset scaling */
11913  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11914  assert(success);
11915  }
11916 
11917  /* solve again with opposite presolving and other simplex */
11918  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11919  if( success )
11920  {
11921  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11922  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11923  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11924 
11925  /* check for stability */
11926  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11927  return SCIP_OKAY;
11928 
11929  if( !set->lp_checkstability )
11930  {
11931  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11932 
11933  if( success )
11934  return SCIP_OKAY;
11935  }
11936 
11937  /* reset presolving */
11938  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11939  assert(success);
11940  }
11941 
11942  /* solve again with tighter feasibility tolerance, use other simplex this time */
11943  if( !tightprimfeastol || !tightdualfeastol )
11944  {
11945  success = FALSE;
11946  if( !tightprimfeastol )
11947  {
11948  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11949  }
11950 
11951  success2 = FALSE;
11952  if( !tightdualfeastol )
11953  {
11954  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11955  }
11956 
11957  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11958  if( success || success2 )
11959  {
11960  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11961  lpalgoName(lpalgo));
11962  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11963 
11964  /* check for stability */
11965  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11966  return SCIP_OKAY;
11967 
11968  if( !set->lp_checkstability )
11969  {
11970  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11971 
11972  if( success )
11973  return SCIP_OKAY;
11974  }
11975 
11976  /* reset feasibility tolerance */
11977  if( !tightprimfeastol )
11978  {
11979  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11980  }
11981  if( !tightdualfeastol )
11982  {
11983  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11984  }
11985  SCIP_UNUSED(success);
11986  }
11987  }
11988  }
11989 
11990  /* nothing worked -- exit with an LPERROR */
11991  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11992  *lperror = TRUE;
11993 
11994  return SCIP_OKAY;
11995 }
11996 
11997 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11998 static
12000  SCIP_LP* lp, /**< current LP data */
12001  SCIP_SET* set, /**< global SCIP settings */
12002  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
12003  )
12004 {
12005  assert(lp != NULL);
12006  assert(set != NULL);
12007 
12008  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
12009  {
12010  if( !lp->adjustlpval && messagehdlr != NULL )
12011  {
12012  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
12013  lp->adjustlpval = TRUE;
12014  }
12015  lp->lpobjval = SCIPsetInfinity(set);
12016  }
12017  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
12018  {
12019  if( !lp->adjustlpval && messagehdlr != NULL )
12020  {
12021  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
12022  lp->adjustlpval = TRUE;
12023  }
12024  lp->lpobjval = -SCIPsetInfinity(set);
12025  }
12026 }
12027 
12028 /** solves the LP with the given algorithm and evaluates return status */
12029 static
12031  SCIP_LP* lp, /**< current LP data */
12032  SCIP_SET* set, /**< global SCIP settings */
12033  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12034  SCIP_STAT* stat, /**< problem statistics */
12035  SCIP_PROB* prob, /**< problem data */
12036  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12037  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12038  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12039  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12040  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12041  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12042  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12043  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12044  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12045  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12046  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12047  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12048  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12049  )
12050 {
12051  SCIP_Bool solvedprimal;
12052  SCIP_Bool solveddual;
12053  SCIP_Bool timelimit;
12054  int itlim;
12055 
12056  assert(lp != NULL);
12057  assert(lp->flushed);
12058  assert(set != NULL);
12059  assert(stat != NULL);
12060  assert(lperror != NULL);
12061 
12062  checkLinks(lp);
12063 
12064  solvedprimal = FALSE;
12065  solveddual = FALSE;
12066  timelimit = FALSE;
12067 
12068  /* select the basic iteration limit depending on whether this is a resolving call or not */
12069  itlim = ( resolve ? resolveitlim : harditlim );
12070 
12071  SOLVEAGAIN:
12072  /* call simplex */
12073  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12074  scaling, keepsol, &timelimit, lperror) );
12075  resolve = FALSE; /* only the first solve should be counted as resolving call */
12076  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12077  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12078 
12079  /* check, if an error occurred */
12080  if( *lperror )
12081  {
12082  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12083  lp->solved = FALSE;
12085  return SCIP_OKAY;
12086  }
12087 
12088  /* check, if a time limit was exceeded */
12089  if( timelimit )
12090  {
12091  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12092  lp->solved = TRUE;
12094  lp->lpobjval = -SCIPsetInfinity(set);
12095  return SCIP_OKAY;
12096  }
12097 
12098  /* only one should return true */
12099  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
12101 
12102  /* evaluate solution status */
12103  if( SCIPlpiIsOptimal(lp->lpi) )
12104  {
12105  assert(lp->primalfeasible);
12106  assert(lp->dualfeasible);
12108  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12109  adjustLPobjval(lp, set, messagehdlr);
12110 
12111  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
12112  {
12113  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12114  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12116  lp->lpobjval = SCIPsetInfinity(set);
12117  }
12118  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12119  * reached if the LP objective value is greater than the cutoff bound
12120  */
12121  assert(lpCutoffDisabled(set, prob) || lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT || SCIPsetIsInfinity(set, lp->cutoffbound)
12122  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12123  }
12124  else if( SCIPlpiIsObjlimExc(lp->lpi) )
12125  {
12126  assert(!lpCutoffDisabled(set, prob));
12127 
12128 #ifndef NDEBUG
12129  /* the LP solution objective should exceed the limit in this case */
12130  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12131  assert(!set->lp_checkstability || SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
12132 #endif
12133 
12135  lp->lpobjval = SCIPsetInfinity(set);
12136  }
12137  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12138  {
12139  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12140  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12141  {
12142  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12143  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12144  goto SOLVEAGAIN;
12145  }
12147  lp->lpobjval = SCIPsetInfinity(set);
12148  }
12149  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12150  {
12151  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12152  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12153  {
12154  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12155  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12156  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12157  goto SOLVEAGAIN;
12158  }
12160  lp->lpobjval = -SCIPsetInfinity(set);
12161  }
12162  else if( SCIPlpiIsIterlimExc(lp->lpi) )
12163  {
12164  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12165 
12166  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12167  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12168  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12169  adjustLPobjval(lp, set, NULL);
12170  else
12171  adjustLPobjval(lp, set, messagehdlr);
12172 
12174  }
12175  else if( SCIPlpiIsTimelimExc(lp->lpi) )
12176  {
12177  lp->lpobjval = -SCIPsetInfinity(set);
12179  }
12180  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12181  {
12182  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12183  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12184  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12185  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12186  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12187  goto SOLVEAGAIN;
12188  }
12189  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12190  {
12191  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12192  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12193  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12194  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12195  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12196  goto SOLVEAGAIN;
12197  }
12198  else
12199  {
12200  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12201  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12203  return SCIP_LPERROR;
12204  }
12205 
12206  lp->solved = TRUE;
12207 
12208  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12211 
12212  return SCIP_OKAY;
12213 }
12214 
12215 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12216 static
12218  SCIP_LP* lp, /**< current LP data */
12219  BMS_BLKMEM* blkmem, /**< block memory */
12220  SCIP_SET* set, /**< global SCIP settings */
12221  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12222  SCIP_STAT* stat, /**< problem statistics */
12223  SCIP_PROB* prob, /**< problem data */
12224  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12225  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12226  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12227  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12228  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12229  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12230  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12231  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12232  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12233  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12234  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12235  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12236  )
12237 {
12238  SCIP_Bool resolve;
12239  char algo;
12240 
12241  assert(lp != NULL);
12242  assert(set != NULL);
12243  assert(lperror != NULL);
12244 
12245  /* flush changes to the LP solver */
12246  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12247  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12248 
12249  /* select LP algorithm to apply */
12250  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12251  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12252 
12253  switch( algo )
12254  {
12255  case 's':
12256  /* select simplex method */
12257  if( lp->dualfeasible || !lp->primalfeasible )
12258  {
12259  SCIPsetDebugMsg(set, "solving dual LP\n");
12260  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12261  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12262  }
12263  else
12264  {
12265  SCIPsetDebugMsg(set, "solving primal LP\n");
12266  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12267  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12268  }
12269  break;
12270 
12271  case 'p':
12272  SCIPsetDebugMsg(set, "solving primal LP\n");
12273  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12274  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12275  break;
12276 
12277  case 'd':
12278  SCIPsetDebugMsg(set, "solving dual LP\n");
12279  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12280  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12281  break;
12282 
12283  case 'b':
12284  SCIPsetDebugMsg(set, "solving barrier LP\n");
12285  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12286  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12287  break;
12288 
12289  case 'c':
12290  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12291  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12292  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12293  break;
12294 
12295  default:
12296  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12297  return SCIP_PARAMETERWRONGVAL;
12298  }
12299  assert(!(*lperror) || !lp->solved);
12300 
12301  return SCIP_OKAY;
12302 }
12303 
12304 #ifndef NDEBUG
12305 /** checks if the lazy bounds are valid */
12306 static
12308  SCIP_LP* lp, /**< LP data */
12309  SCIP_SET* set /**< global SCIP settings */
12310  )
12311 {
12312  SCIP_COL* col;
12313  int c;
12314 
12315  assert(lp->flushed);
12316 
12317  for( c = 0; c < lp->nlazycols; ++c )
12318  {
12319  col = lp->lazycols[c];
12320 
12321  /* in case lazy bounds are given, check that the primal solution satisfies them */
12322  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12323  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12324  }
12325 }
12326 #else
12327 #define checkLazyBounds(lp, set) /**/
12328 #endif
12329 
12330 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12331  * diving
12332  */
12333 static
12335  SCIP_LP* lp, /**< LP data */
12336  SCIP_SET* set /**< global SCIP settings */
12337  )
12338 {
12339  SCIP_COL* col;
12340  int c;
12341 
12342  assert(lp->nlazycols > 0);
12343 
12344  /* return, if we are in diving, and bounds were already applied
12345  * or if we are not in diving and bounds were not applied
12346  */
12347  if( lp->diving == lp->divinglazyapplied )
12348  return SCIP_OKAY;
12349 
12350  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12351  lp->diving, lp->divinglazyapplied);
12352 
12353  for( c = 0; c < lp->nlazycols; ++c )
12354  {
12355  col = lp->lazycols[c];
12356 
12357  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12358  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12359  {
12360  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12361  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12362  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12363 
12364  /* insert column in the chgcols list (if not already there) */
12365  SCIP_CALL( insertColChgcols(col, set, lp) );
12366 
12367  /* mark bound change in the column */
12368  col->lbchanged = TRUE;
12369  }
12370 
12371  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12372  if( !SCIPsetIsInfinity(set, col->lazyub) )
12373  {
12374  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12375  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12376  || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12377 
12378  /* insert column in the chgcols list (if not already there) */
12379  SCIP_CALL( insertColChgcols(col, set, lp) );
12380 
12381  /* mark bound change in the column */
12382  col->ubchanged = TRUE;
12383  }
12384  }
12385 
12386  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12387  * if not, we just removed them
12388  */
12389  lp->divinglazyapplied = lp->diving;
12390 
12391  return SCIP_OKAY;
12392 }
12393 
12394 /** returns the iteration limit for an LP resolving call */
12395 static
12397  SCIP_SET* set, /**< global SCIP settings */
12398  SCIP_STAT* stat, /**< dynamic problem statistics */
12399  int itlim /**< hard iteration limit */
12400  )
12401 {
12402  /* no limit set or average not yet reliable */
12403  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12404  return itlim;
12405  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12406  if( itlim == -1 )
12407  itlim = INT_MAX;
12408  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12409  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12410  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12411 }
12412 
12413 
12414 
12415 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12417  SCIP_LP* lp, /**< LP data */
12418  SCIP_SET* set, /**< global SCIP settings */
12419  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12420  BMS_BLKMEM* blkmem, /**< block memory buffers */
12421  SCIP_STAT* stat, /**< problem statistics */
12422  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12423  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12424  SCIP_PROB* prob, /**< problem data */
12425  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12426  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12427  * (limit is computed within the method w.r.t. the average LP iterations) */
12428  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12429  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12430  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12431  )
12432 {
12433  SCIP_RETCODE retcode;
12434  SCIP_Bool needprimalray;
12435  SCIP_Bool needdualray;
12436  int harditlim;
12437  int resolveitlim;
12438 
12439  assert(lp != NULL);
12440  assert(prob != NULL);
12441  assert(prob->nvars >= lp->ncols);
12442  assert(lperror != NULL);
12443 
12444  retcode = SCIP_OKAY;
12445  *lperror = FALSE;
12446 
12447  if( lp->flushed && lp->solved )
12448  {
12449  SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
12450  return SCIP_OKAY;
12451  }
12452 
12453  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12454  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12455 
12456  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12457  needprimalray = TRUE;
12458  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12459  || (set->conf_enable && set->conf_useinflp != 'o'));
12460 
12461  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12462  harditlim = (int) MIN(itlim, INT_MAX);
12463  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12464  assert(harditlim == -1 || (resolveitlim <= harditlim));
12465 
12466  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12467  * or removed from the LP (diving was ended)
12468  */
12469  if( lp->nlazycols > 0 )
12470  {
12471  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12472  * first resolve LP?
12473  */
12474  SCIP_CALL( updateLazyBounds(lp, set) );
12475  assert(lp->diving == lp->divinglazyapplied);
12476  }
12477 
12478  /* flush changes to the LP solver */
12479  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12480  assert(lp->flushed);
12481 
12482  /* 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
12483  * to run again anyway, since there seems to be some time left / the time limit was increased
12484  */
12485  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12486  {
12487  SCIP_Bool* primalfeaspointer;
12488  SCIP_Bool* dualfeaspointer;
12489  SCIP_Bool primalfeasible;
12490  SCIP_Bool dualfeasible;
12491  SCIP_Bool farkasvalid;
12492  SCIP_Bool rayfeasible;
12493  SCIP_Bool tightprimfeastol;
12494  SCIP_Bool tightdualfeastol;
12495  SCIP_Bool fromscratch;
12496  SCIP_Bool wasfromscratch;
12497  int scaling;
12498  SCIP_Longint oldnlps;
12499  int fastmip;
12500 
12501  /* set initial LP solver settings */
12502  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12503  tightprimfeastol = FALSE;
12504  tightdualfeastol = FALSE;
12505  fromscratch = FALSE;
12506  primalfeasible = FALSE;
12507  dualfeasible = FALSE;
12508  wasfromscratch = (stat->nlps == 0);
12509  scaling = set->lp_scaling;
12510 
12511  SOLVEAGAIN:
12512  /* solve the LP */
12513  oldnlps = stat->nlps;
12514  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12515  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12516  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12517  assert(!(*lperror) || !lp->solved);
12518 
12519  /* check for error */
12520  if( *lperror )
12521  {
12522  retcode = SCIP_OKAY;
12523  goto TERMINATE;
12524  }
12525 
12526  /* evaluate solution status */
12527  switch( SCIPlpGetSolstat(lp) )
12528  {
12530  /* get LP solution and possibly check the solution's feasibility again */
12531  if( set->lp_checkprimfeas )
12532  {
12533  primalfeaspointer = &primalfeasible;
12534  lp->primalchecked = TRUE;
12535  }
12536  else
12537  {
12538  /* believe in the primal feasibility of the LP solution */
12539  primalfeasible = TRUE;
12540  primalfeaspointer = NULL;
12541  lp->primalchecked = FALSE;
12542  }
12543  if( set->lp_checkdualfeas )
12544  {
12545  dualfeaspointer = &dualfeasible;
12546  lp->dualchecked = TRUE;
12547  }
12548  else
12549  {
12550  /* believe in the dual feasibility of the LP solution */
12551  dualfeasible = TRUE;
12552  dualfeaspointer = NULL;
12553  lp->dualchecked = FALSE;
12554  }
12555 
12556  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12557 
12558  /* in debug mode, check that lazy bounds (if present) are not violated */
12559  checkLazyBounds(lp, set);
12560 
12561  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12562  {
12563  /* update ages and remove obsolete columns and rows from LP */
12564  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12565  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12566  {
12567  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12568  }
12569 
12570  if( !lp->solved )
12571  {
12572  /* resolve LP after removing obsolete columns and rows */
12573  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12574  aging = FALSE; /* to prevent infinite loops */
12575  goto SOLVEAGAIN;
12576  }
12577  }
12578  if( !primalfeasible || !dualfeasible )
12579  {
12581 
12582  if( (fastmip > 0) && simplex )
12583  {
12584  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12585  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12586  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
12587  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12588  fastmip = 0;
12589  goto SOLVEAGAIN;
12590  }
12591  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12592  {
12593  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12594  * tolerance
12595  */
12596  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12597  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
12598  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12599  tightprimfeastol = tightprimfeastol || !primalfeasible;
12600  tightdualfeastol = tightdualfeastol || !dualfeasible;
12601  goto SOLVEAGAIN;
12602  }
12603  else if( !fromscratch && !wasfromscratch && simplex )
12604  {
12605  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12606  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12607  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
12608  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12609  fromscratch = TRUE;
12610  goto SOLVEAGAIN;
12611  }
12612  else
12613  {
12614  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12615  lp->solved = FALSE;
12617  *lperror = TRUE;
12618  }
12619  }
12620  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12621  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12622  lp->lpsolstat, lp->cutoffbound);
12623  break;
12624 
12626  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12627  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12628  {
12629  if( SCIPlpiHasDualRay(lp->lpi) )
12630  {
12631  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12632  }
12633  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12634  * with the primal simplex due to numerical problems) - treat this case like an LP error
12635  */
12636  else
12637  {
12638  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12639  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12640  lp->solved = FALSE;
12642  farkasvalid = FALSE;
12643  *lperror = TRUE;
12644  }
12645  }
12646  else
12647  farkasvalid = TRUE;
12648 
12649  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12650  if( !farkasvalid && !(*lperror) )
12651  {
12653 
12654  if( (fastmip > 0) && simplex )
12655  {
12656  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12657  * without FASTMIP
12658  */
12659  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12660  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12661  stat->nnodes, stat->nlps);
12662  fastmip = 0;
12663  goto SOLVEAGAIN;
12664  }
12665  else if( !tightdualfeastol )
12666  {
12667  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12668  * solve again with tighter feasibility tolerance
12669  */
12670  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12671  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12672  stat->nnodes, stat->nlps);
12673  tightdualfeastol = TRUE;
12674  goto SOLVEAGAIN;
12675  }
12676  else if( !fromscratch && simplex )
12677  {
12678  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12679  * from scratch
12680  */
12681  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12682  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12683  stat->nnodes, stat->nlps);
12684  fromscratch = TRUE;
12685  goto SOLVEAGAIN;
12686  }
12687  else
12688  {
12689  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12690  * helped forget about the LP at this node and mark it to be unsolved
12691  */
12692  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12693  lp->solved = FALSE;
12695  *lperror = TRUE;
12696  }
12697  }
12698 
12699  break;
12700 
12702  if( set->lp_checkprimfeas )
12703  {
12704  /* get unbounded LP solution and check the solution's feasibility again */
12705  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12706 
12707  lp->primalchecked = TRUE;
12708  }
12709  else
12710  {
12711  /* get unbounded LP solution believing in the feasibility of the LP solution */
12712  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12713 
12714  primalfeasible = TRUE;
12715  rayfeasible = TRUE;
12716  lp->primalchecked = FALSE;
12717  }
12718 
12719  /* in debug mode, check that lazy bounds (if present) are not violated */
12720  checkLazyBounds(lp, set);
12721 
12722  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12723  primalfeasible, rayfeasible);
12724 
12725  if( !primalfeasible || !rayfeasible )
12726  {
12728 
12729  if( (fastmip > 0) && simplex )
12730  {
12731  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12732  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12733  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
12734  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12735  fastmip = 0;
12736  goto SOLVEAGAIN;
12737  }
12738  else if( !tightprimfeastol )
12739  {
12740  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12741  * tolerance
12742  */
12743  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12744  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again with tighter primal feasibility tolerance\n",
12745  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12746  tightprimfeastol = TRUE;
12747  goto SOLVEAGAIN;
12748  }
12749  else if( !fromscratch && simplex )
12750  {
12751  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12752  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12753  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
12754  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12755  fromscratch = TRUE;
12756  goto SOLVEAGAIN;
12757  }
12758  else if( scaling > 0 )
12759  {
12760  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without scaling */
12761  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12762  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving without scaling\n",
12763  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12764  scaling = 0;
12765  goto SOLVEAGAIN;
12766  }
12767  else
12768  {
12769  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12770  * forget about the LP at this node and mark it to be unsolved
12771  */
12772  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12773  lp->solved = FALSE;
12775  *lperror = TRUE;
12776  }
12777  }
12778 
12779  break;
12780 
12782  assert(!lpCutoffDisabled(set, prob));
12783  /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
12784  * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
12785  * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
12786  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12787  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12788  * FASTMIP and solve again. */
12789  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12790  {
12791  SCIP_LPI* lpi;
12792  SCIP_Real objval;
12793 
12794  lpi = SCIPlpGetLPI(lp);
12795 
12796  assert(lpi != NULL);
12797  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12798  * the assert by using !SCIPsetIsFeasNegative()
12799  */
12800  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12801 
12802  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12803 
12804  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12805  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12806  {
12807  SCIP_Real tmpcutoff;
12808  char tmppricingchar;
12809  SCIP_LPSOLSTAT solstat;
12810 
12811  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12812 
12813  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12814  fromscratch = FALSE;
12815 
12816  /* temporarily disable cutoffbound, which also disables the objective limit */
12817  tmpcutoff = lp->cutoffbound;
12818  lp->cutoffbound = SCIPlpiInfinity(lpi);
12819 
12820  /* set lp pricing strategy to steepest edge */
12821  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12822  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12823 
12824  /* resolve LP with an iteration limit of 1 */
12825  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12826  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12827 
12828  /* reinstall old cutoff bound and lp pricing strategy */
12829  lp->cutoffbound = tmpcutoff;
12830  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12831 
12832  /* get objective value */
12833  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12834 
12835  /* get solution status for the lp */
12836  solstat = SCIPlpGetSolstat(lp);
12837  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12838 
12839  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12840 
12841  /* the solution is still not exceeding the objective limit and the solving process
12842  * was stopped due to time or iteration limit, solve again with fastmip turned off
12843  */
12844  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12845  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12846  {
12848  if( !(lperror) && (fastmip > 0) && simplex )
12849  {
12850  fastmip = 0;
12851  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12852  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12853 
12854  /* get objective value */
12855  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12856 
12857  /* get solution status for the lp */
12858  solstat = SCIPlpGetSolstat(lp);
12859 
12860  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12861  }
12862  }/*lint !e438*/
12863 
12864  /* check for lp errors */
12865  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12866  {
12867  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12868  lp->solved = FALSE;
12870 
12871  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12872  goto TERMINATE;
12873  }
12874 
12875  lp->solved = TRUE;
12876 
12877  /* optimal solution / objlimit / itlimit or timelimit, but objlimit exceeded */
12878  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12879  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12880  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12881  {
12882  /* get LP solution and possibly check the solution's feasibility again */
12883  if( set->lp_checkprimfeas )
12884  {
12885  primalfeaspointer = &primalfeasible;
12886  lp->primalchecked = TRUE;
12887  }
12888  else
12889  {
12890  /* believe in the primal feasibility of the LP solution */
12891  primalfeasible = TRUE;
12892  primalfeaspointer = NULL;
12893  lp->primalchecked = FALSE;
12894  }
12895  if( set->lp_checkdualfeas )
12896  {
12897  dualfeaspointer = &dualfeasible;
12898  lp->dualchecked = TRUE;
12899  }
12900  else
12901  {
12902  /* believe in the dual feasibility of the LP solution */
12903  dualfeasible = TRUE;
12904  dualfeaspointer = NULL;
12905  lp->dualchecked = FALSE;
12906  }
12907 
12908  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12909 
12910  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12911  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12912  {
12913  checkLazyBounds(lp, set);
12914  }
12915 
12916  /* if objective value is larger than the cutoff bound, set solution status to objective
12917  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12918  * this was already done in the lpSolve() method
12919  */
12920  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12921  {
12923  lp->lpobjval = SCIPsetInfinity(set);
12924  }
12925 
12926  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12927  * the cutoffbound; mark the LP to be unsolved
12928  */
12929  if( !primalfeasible || !dualfeasible
12930  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12931  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12932  {
12933  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12934  lp->solved = FALSE;
12936  *lperror = TRUE;
12937  }
12938 
12939  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12940  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12941  lp->lpsolstat, lp->cutoffbound);
12942  }
12943  /* infeasible solution */
12944  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12945  {
12946  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12947 
12948  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12949  {
12950  if( SCIPlpiHasDualRay(lp->lpi) )
12951  {
12952  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12953  }
12954  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12955  * with the primal simplex due to numerical problems) - treat this case like an LP error
12956  */
12957  else
12958  {
12959  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12960  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12961  lp->solved = FALSE;
12963  farkasvalid = FALSE;
12964  *lperror = TRUE;
12965  }
12966  }
12967  else
12968  farkasvalid = TRUE;
12969 
12970  if( !farkasvalid )
12971  {
12973 
12974  if( !tightprimfeastol )
12975  {
12976  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12977  * solve again with tighter feasibility tolerance
12978  */
12979  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12980  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12981  stat->nnodes, stat->nlps);
12982  tightprimfeastol = TRUE;
12983  goto SOLVEAGAIN;
12984  }
12985  else if( simplex )
12986  {
12987  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12988  * from scratch
12989  */
12990  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12991  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12992  stat->nnodes, stat->nlps);
12993  fromscratch = TRUE;
12994  goto SOLVEAGAIN;
12995  }
12996  else
12997  {
12998  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12999  * helped forget about the LP at this node and mark it to be unsolved
13000  */
13001  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
13002  lp->solved = FALSE;
13004  *lperror = TRUE;
13005  }
13006  }
13007  }
13008  /* unbounded solution */
13009  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
13010  {
13011  if( set->lp_checkprimfeas )
13012  {
13013  /* get unbounded LP solution and check the solution's feasibility again */
13014  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
13015 
13016  lp->primalchecked = TRUE;
13017  }
13018  else
13019  {
13020  /* get unbounded LP solution believing in its feasibility */
13021  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
13022 
13023  primalfeasible = TRUE;
13024  rayfeasible = TRUE;
13025  lp->primalchecked = FALSE;
13026  }
13027 
13028  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
13029 
13030  /* in debug mode, check that lazy bounds (if present) are not violated */
13031  checkLazyBounds(lp, set);
13032 
13033  if( !primalfeasible || !rayfeasible )
13034  {
13035  /* unbounded solution is infeasible (this can happen due to numerical problems):
13036  * forget about the LP at this node and mark it to be unsolved
13037  *
13038  * @todo: like in the default LP solving evaluation, solve without fastmip,
13039  * with tighter feasibility tolerance and from scratch
13040  */
13041  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
13042  lp->solved = FALSE;
13044  *lperror = TRUE;
13045  }
13046  }
13047 
13048  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
13049  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
13051  }
13052  else
13053  {
13054  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
13055  }
13056  }
13057  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
13058  break;
13059 
13061  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13062  break;
13063 
13065  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13066 
13067  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13068  stat->nclockskipsleft = 0;
13069  if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
13070  {
13071  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13072  "you might consider switching the clock type of SCIP\n");
13073  stat->status = SCIP_STATUS_TIMELIMIT;
13074  }
13075  break;
13076 
13077  case SCIP_LPSOLSTAT_ERROR:
13079  SCIPerrorMessage("error in LP solver\n");
13080  retcode = SCIP_LPERROR;
13081  goto TERMINATE;
13082 
13083  default:
13084  SCIPerrorMessage("unknown LP solution status\n");
13085  retcode = SCIP_ERROR;
13086  goto TERMINATE;
13087  }
13088  }
13089  assert(!(*lperror) || !lp->solved);
13090 
13091  TERMINATE:
13092  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13093  * may happen that we continue to solve from scratch during strong branching */
13094  if( lp->lpifromscratch )
13095  {
13096  SCIP_Bool success;
13097  (void) lpSetFromscratch(lp, FALSE, &success);
13098  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13099  SCIP_UNUSED(success);
13100  }
13101 
13102  return retcode;
13103 }
13104 
13105 /** gets solution status of current LP */
13107  SCIP_LP* lp /**< current LP data */
13108  )
13109 {
13110  assert(lp != NULL);
13111  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
13112 
13113  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13114 }
13115 
13116 /** gets objective value of current LP
13117  *
13118  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13119  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13120  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13121  */
13123  SCIP_LP* lp, /**< current LP data */
13124  SCIP_SET* set, /**< global SCIP settings */
13125  SCIP_PROB* prob /**< problem data */
13126  )
13127 {
13128  assert(lp != NULL);
13129  assert(lp->solved);
13130  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13131  assert(set != NULL);
13132 
13133  if( !lp->flushed )
13134  return SCIP_INVALID;
13135  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
13136  return lp->lpobjval;
13137  else if( lp->looseobjvalinf > 0 )
13138  return -SCIPsetInfinity(set);
13139  else
13140  {
13141  /* recalculate the loose objective value, if needed */
13142  if( !lp->looseobjvalid )
13143  recomputeLooseObjectiveValue(lp, set, prob);
13144 
13145  return lp->lpobjval + lp->looseobjval;
13146  }
13147 }
13148 
13149 /** gets part of objective value of current LP that results from COLUMN variables only */
13151  SCIP_LP* lp /**< current LP data */
13152  )
13153 {
13154  assert(lp != NULL);
13155  assert(lp->solved);
13156 
13157  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13158 }
13159 
13160 /** gets part of objective value of current LP that results from LOOSE variables only */
13162  SCIP_LP* lp, /**< current LP data */
13163  SCIP_SET* set, /**< global SCIP settings */
13164  SCIP_PROB* prob /**< problem data */
13165  )
13166 {
13167  assert(lp != NULL);
13168  assert(lp->solved);
13169  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13170  assert(set != NULL);
13171 
13172  if( !lp->flushed )
13173  return SCIP_INVALID;
13174  else if( lp->looseobjvalinf > 0 )
13175  return -SCIPsetInfinity(set);
13176  else
13177  return getFiniteLooseObjval(lp, set, prob);
13178 }
13179 
13180 /** remembers the current LP objective value as root solution value */
13182  SCIP_LP* lp, /**< current LP data */
13183  SCIP_SET* set, /**< global SCIP settings */
13184  SCIP_PROB* prob /**< problem data */
13185  )
13186 {
13187  assert(lp != NULL);
13188 
13190  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13191 }
13192 
13193 /** invalidates the root LP solution value */
13195  SCIP_LP* lp /**< current LP data */
13196  )
13197 {
13198  assert(lp != NULL);
13199 
13200  lp->rootlpobjval = SCIP_INVALID;
13202 }
13203 
13204 /** recomputes local and global pseudo objective values */
13206  SCIP_LP* lp, /**< current LP data */
13207  SCIP_SET* set, /**< global SCIP settings */
13208  SCIP_PROB* prob /**< problem data */
13209  )
13210 {
13211  SCIP_VAR** vars;
13212  int nvars;
13213  int v;
13214 
13215  assert(lp != NULL);
13216  assert(set != NULL);
13217  assert(prob != NULL);
13218 
13219  vars = prob->vars;
13220  nvars = prob->nvars;
13221 
13222  lp->glbpseudoobjvalinf = 0;
13223  lp->glbpseudoobjval = 0.0;
13224 
13225  lp->pseudoobjvalinf = 0;
13226  lp->pseudoobjval = 0.0;
13227 
13228  for( v = 0; v < nvars; ++v )
13229  {
13230  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13231 
13232  if( SCIPsetIsPositive(set, obj) )
13233  {
13234  /* update the global pseudo objective value */
13235  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13236  ++(lp->glbpseudoobjvalinf);
13237  else
13238  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13239 
13240  /* update the local pseudo objective value */
13241  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13242  ++(lp->pseudoobjvalinf);
13243  else
13244  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13245  }
13246 
13247  if( SCIPsetIsNegative(set, obj) )
13248  {
13249  /* update the global pseudo objective value */
13250  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13251  ++(lp->glbpseudoobjvalinf);
13252  else
13253  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13254 
13255  /* update the local pseudo objective value */
13256  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13257  ++(lp->pseudoobjvalinf);
13258  else
13259  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13260  }
13261  }
13262 
13263  /* the recomputed values are reliable */
13265  lp->glbpseudoobjvalid = TRUE;
13266  lp->relpseudoobjval = lp->pseudoobjval;
13267  lp->pseudoobjvalid = TRUE;
13268 }
13269 
13270 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13271  * global bound
13272  */
13274  SCIP_LP* lp, /**< current LP data */
13275  SCIP_SET* set, /**< global SCIP settings */
13276  SCIP_PROB* prob /**< problem data */
13277  )
13278 {
13279  assert(lp != NULL);
13280  assert(lp->glbpseudoobjvalinf >= 0);
13281  assert(set != NULL);
13282 
13283  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13284  return -SCIPsetInfinity(set);
13285  else
13286  {
13287  /* recalculate the global pseudo solution value, if needed */
13288  if( !lp->glbpseudoobjvalid )
13289  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13290 
13291  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13292  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13293  return -SCIPsetInfinity(set);
13294 
13295  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13296  return SCIPsetInfinity(set);
13297 
13298  return lp->glbpseudoobjval;
13299  }
13300 }
13301 
13302 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13303  * objective function) local bound
13304  */
13306  SCIP_LP* lp, /**< current LP data */
13307  SCIP_SET* set, /**< global SCIP settings */
13308  SCIP_PROB* prob /**< problem data */
13309  )
13310 {
13311  assert(lp != NULL);
13312  assert(lp->pseudoobjvalinf >= 0);
13313  assert(set != NULL);
13314 
13315  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13316  return -SCIPsetInfinity(set);
13317  else
13318  {
13319  /* recalculate the pseudo solution value, if needed */
13320  if( !lp->pseudoobjvalid )
13321  recomputePseudoObjectiveValue(lp, set, prob);
13322 
13323  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13324  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13325  return -SCIPsetInfinity(set);
13326 
13327  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13328  return SCIPsetInfinity(set);
13329 
13330  return lp->pseudoobjval;
13331  }
13332 }
13333 
13334 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13336  SCIP_LP* lp, /**< current LP data */
13337  SCIP_SET* set, /**< global SCIP settings */
13338  SCIP_PROB* prob, /**< problem data */
13339  SCIP_VAR* var, /**< problem variable */
13340  SCIP_Real oldbound, /**< old value for bound */
13341  SCIP_Real newbound, /**< new value for bound */
13342  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13343  )
13344 {
13345  SCIP_Real pseudoobjval;
13346  int pseudoobjvalinf;
13347  SCIP_Real obj;
13348 
13349  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13350  pseudoobjvalinf = lp->pseudoobjvalinf;
13351  obj = SCIPvarGetObj(var);
13352  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13353  {
13354  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13355  pseudoobjvalinf--;
13356  else
13357  pseudoobjval -= oldbound * obj;
13358  assert(pseudoobjvalinf >= 0);
13359  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13360  pseudoobjvalinf++;
13361  else
13362  pseudoobjval += newbound * obj;
13363  }
13364  assert(pseudoobjvalinf >= 0);
13365 
13366  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13367  return -SCIPsetInfinity(set);
13368  else
13369  return pseudoobjval;
13370 }
13371 
13372 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13373  * perform calculations with interval arithmetic to get an exact lower bound
13374  */
13376  SCIP_LP* lp, /**< current LP data */
13377  SCIP_SET* set, /**< global SCIP settings */
13378  SCIP_VAR* var, /**< problem variable */
13379  SCIP_Real oldbound, /**< old value for bound */
13380  SCIP_Real newbound, /**< new value for bound */
13381  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13382  )
13383 {
13384  SCIP_Real pseudoobjval;
13385  int pseudoobjvalinf;
13386  SCIP_Real obj;
13387 
13388  assert(lp->pseudoobjvalid);
13389 
13390  pseudoobjval = lp->pseudoobjval;
13391  pseudoobjvalinf = lp->pseudoobjvalinf;
13392  obj = SCIPvarGetObj(var);
13393  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13394  {
13395  SCIP_INTERVAL objint;
13396  SCIP_INTERVAL bd;
13397  SCIP_INTERVAL prod;
13398  SCIP_INTERVAL psval;
13399 
13400  SCIPintervalSet(&psval, pseudoobjval);
13401  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13402 
13403  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13404  pseudoobjvalinf--;
13405  else
13406  {
13407  SCIPintervalSet(&bd, oldbound);
13408  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13409  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13410  }
13411  assert(pseudoobjvalinf >= 0);
13412  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13413  pseudoobjvalinf++;
13414  else
13415  {
13416  SCIPintervalSet(&bd, newbound);
13417  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13418  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13419  }
13420 
13421  pseudoobjval = SCIPintervalGetInf(psval);
13422  }
13423  assert(pseudoobjvalinf >= 0);
13424 
13425  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13426  return -SCIPsetInfinity(set);
13427  else
13428  return pseudoobjval;
13429 }
13430 
13431 /** compute the objective delta due the new objective coefficient */
13432 static
13434  SCIP_SET* set, /**< global SCIP settings */
13435  SCIP_Real oldobj, /**< old objective value of variable */
13436  SCIP_Real newobj, /**< new objective value of variable */
13437  SCIP_Real lb, /**< lower bound of variable */
13438  SCIP_Real ub, /**< upper bound of variable */
13439  SCIP_Real* deltaval, /**< pointer to store the delta value */
13440  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13441  )
13442 {
13443  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13444  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13445  assert(!SCIPsetIsInfinity(set, lb));
13446  assert(!SCIPsetIsInfinity(set, -ub));
13447  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13448 
13449  (*deltaval) = 0.0;
13450  (*deltainf) = 0;
13451 
13452  if( SCIPsetIsPositive(set, oldobj) )
13453  {
13454  /* sign of objective did not change */
13455  if( SCIPsetIsPositive(set, newobj) )
13456  {
13457  /* if the bound is finite, calculate the deltaval */
13458  if( !SCIPsetIsInfinity(set, -lb) )
13459  (*deltaval) = lb * (newobj - oldobj);
13460  }
13461  /* sign of objective did change, so the best bound does change */
13462  else if( SCIPsetIsNegative(set, newobj) )
13463  {
13464  if( SCIPsetIsInfinity(set, -lb) )
13465  {
13466  /* old best bound was infinite while new one is not */
13467  if( !SCIPsetIsInfinity(set, ub) )
13468  {
13469  (*deltainf) = -1;
13470  (*deltaval) = ub * newobj;
13471  }
13472  }
13473  else
13474  {
13475  /* new best bound is infinite while old one was not */
13476  if( SCIPsetIsInfinity(set, ub) )
13477  {
13478  (*deltainf) = 1;
13479  (*deltaval) = -lb * oldobj;
13480  }
13481  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13482  else
13483  {
13484  (*deltaval) = (ub * newobj) - (lb * oldobj);
13485  }
13486  }
13487  }
13488  /* new objective is 0.0 */
13489  else
13490  {
13491  if( SCIPsetIsInfinity(set, -lb) )
13492  (*deltainf) = -1;
13493  else
13494  (*deltaval) = -lb * oldobj;
13495  }
13496  }
13497  else if( SCIPsetIsNegative(set, oldobj) )
13498  {
13499  /* sign of objective did not change */
13500  if( SCIPsetIsNegative(set, newobj) )
13501  {
13502  /* if the bound is finite, calculate the deltaval */
13503  if( !SCIPsetIsInfinity(set, ub) )
13504  (*deltaval) = ub * (newobj - oldobj);
13505  }
13506  /* sign of objective did change, so the best bound does change */
13507  else if( SCIPsetIsPositive(set, newobj) )
13508  {
13509  if( SCIPsetIsInfinity(set, ub) )
13510  {
13511  /* old best bound was infinite while new one is not */
13512  if( !SCIPsetIsInfinity(set, -lb) )
13513  {
13514  (*deltainf) = -1;
13515  (*deltaval) = lb * newobj;
13516  }
13517  }
13518  else
13519  {
13520  /* new best bound is infinite while old one was not */
13521  if( SCIPsetIsInfinity(set, -lb) )
13522  {
13523  (*deltainf) = 1;
13524  (*deltaval) = -ub * oldobj;
13525  }
13526  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13527  else
13528  {
13529  (*deltaval) = (lb * newobj) - (ub * oldobj);
13530  }
13531  }
13532  }
13533  /* new objective is 0.0 */
13534  else
13535  {
13536  if( SCIPsetIsInfinity(set, ub) )
13537  (*deltainf) = -1;
13538  else
13539  (*deltaval) = -ub * oldobj;
13540  }
13541  }
13542  /* old objective was 0.0 */
13543  else
13544  {
13545  if( SCIPsetIsNegative(set, newobj) )
13546  {
13547  if( SCIPsetIsInfinity(set, ub) )
13548  (*deltainf) = 1;
13549  else
13550  (*deltaval) = ub * newobj;
13551  }
13552  else if( SCIPsetIsPositive(set, newobj) )
13553  {
13554  if( SCIPsetIsInfinity(set, -lb) )
13555  (*deltainf) = 1;
13556  else
13557  (*deltaval) = lb * newobj;
13558  }
13559  }
13560 }
13561 
13562 /** compute the objective delta due the new lower bound */
13563 static
13565  SCIP_SET* set, /**< global SCIP settings */
13566  SCIP_Real obj, /**< objective value of variable */
13567  SCIP_Real oldlb, /**< old lower bound of variable */
13568  SCIP_Real newlb, /**< new lower bound of variable */
13569  SCIP_Real* deltaval, /**< pointer to store the delta value */
13570  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13571  )
13572 {
13573  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13574  assert(!SCIPsetIsInfinity(set, oldlb));
13575  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13576  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13577 
13578  if( SCIPsetIsInfinity(set, -oldlb) )
13579  {
13580  if( !SCIPsetIsInfinity(set, newlb) )
13581  {
13582  (*deltainf) = -1;
13583  (*deltaval) = newlb * obj;
13584  }
13585  else
13586  {
13587  (*deltainf) = 0;
13588  (*deltaval) = 0.0;
13589  }
13590  }
13591  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13592  {
13593  (*deltainf) = 1;
13594  (*deltaval) = -oldlb * obj;
13595  }
13596  else
13597  {
13598  (*deltainf) = 0;
13599  (*deltaval) = obj * (newlb - oldlb);
13600  }
13601 }
13602 
13603 /** compute the objective delta due the new upper bound */
13604 static
13606  SCIP_SET* set, /**< global SCIP settings */
13607  SCIP_Real obj, /**< objective value of variable */
13608  SCIP_Real oldub, /**< old upper bound of variable */
13609  SCIP_Real newub, /**< new upper bound of variable */
13610  SCIP_Real* deltaval, /**< pointer to store the delta value */
13611  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13612  )
13613 {
13614  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13615  assert(!SCIPsetIsInfinity(set, -oldub));
13616  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13617  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13618 
13619  if( SCIPsetIsInfinity(set, oldub) )
13620  {
13621  if( !SCIPsetIsInfinity(set, -newub) )
13622  {
13623  (*deltainf) = -1;
13624  (*deltaval) = newub * obj;
13625  }
13626  else
13627  {
13628  (*deltainf) = 0;
13629  (*deltaval) = 0.0;
13630  }
13631  }
13632  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13633  {
13634  (*deltainf) = 1;
13635  (*deltaval) = -oldub * obj;
13636  }
13637  else
13638  {
13639  (*deltainf) = 0;
13640  (*deltaval) = obj * (newub - oldub);
13641  }
13642 }
13643 
13644 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13645 static
13647  SCIP_LP* lp, /**< current LP data */
13648  SCIP_SET* set, /**< global SCIP settings */
13649  SCIP_VAR* var, /**< problem variable that changed */
13650  SCIP_Real deltaval, /**< delta value in the objective function */
13651  int deltainf, /**< delta value for the number of variables with infinite best bound */
13652  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13653  SCIP_Bool loose, /**< should the loose objective value be updated? */
13654  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13655  )
13656 {
13657  assert(lp != NULL);
13658  assert(lp->looseobjvalinf >= 0);
13659  assert(lp->pseudoobjvalinf >= 0);
13660  assert(lp->glbpseudoobjvalinf >= 0);
13661 
13662  /* update the pseudo objective value */
13663  if( local )
13664  {
13665  lp->pseudoobjvalinf += deltainf;
13666  if( lp->pseudoobjvalid )
13667  {
13668  lp->pseudoobjval += deltaval;
13669 
13670  /* if the absolute value was increased, this is regarded as reliable,
13671  * otherwise, we check whether we can still trust the updated value
13672  */
13673  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13674  lp->relpseudoobjval = lp->pseudoobjval;
13675  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13676  lp->pseudoobjvalid = FALSE;
13677  }
13678 
13679  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13681  loose = TRUE;
13682  }
13683  /* update the loose objective value */
13684  if( loose )
13685  {
13686  lp->looseobjvalinf += deltainf;
13687 
13688  if( deltaval != 0.0 && lp->looseobjvalid )
13689  {
13690  lp->looseobjval += deltaval;
13691 
13692  /* if the absolute value was increased, this is regarded as reliable,
13693  * otherwise, we check whether we can still trust the updated value
13694  */
13695  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13696  lp->rellooseobjval = lp->looseobjval;
13697  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13698  lp->looseobjvalid = FALSE;
13699  }
13700  }
13701  /* update the root pseudo objective values */
13702  if( global )
13703  {
13704  lp->glbpseudoobjvalinf += deltainf;
13705  if( lp->glbpseudoobjvalid )
13706  {
13707  lp->glbpseudoobjval += deltaval;
13708 
13709  /* if the absolute value was increased, this is regarded as reliable,
13710  * otherwise, we check whether we can still trust the updated value
13711  */
13715  lp->glbpseudoobjvalid = FALSE;
13716  }
13717  }
13718 
13719  assert(lp->looseobjvalinf >= 0);
13720  assert(lp->pseudoobjvalinf >= 0);
13721  assert(lp->glbpseudoobjvalinf >= 0);
13722 }
13723 
13724 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13725  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13726  */
13727 static
13729  SCIP_LP* lp, /**< current LP data */
13730  SCIP_SET* set, /**< global SCIP settings */
13731  SCIP_VAR* var, /**< problem variable that changed */
13732  SCIP_Real oldobj, /**< old objective value of variable */
13733  SCIP_Real oldlb, /**< old objective value of variable */
13734  SCIP_Real oldub, /**< old objective value of variable */
13735  SCIP_Real newobj, /**< new objective value of variable */
13736  SCIP_Real newlb, /**< new objective value of variable */
13737  SCIP_Real newub /**< new objective value of variable */
13738  )
13739 {
13740  SCIP_INTERVAL deltaval;
13741  SCIP_INTERVAL bd;
13742  SCIP_INTERVAL obj;
13743  SCIP_INTERVAL prod;
13744  SCIP_INTERVAL psval;
13745  int deltainf;
13746 
13747  assert(lp != NULL);
13748  assert(lp->pseudoobjvalinf >= 0);
13749  assert(lp->looseobjvalinf >= 0);
13750  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13751  assert(!SCIPsetIsInfinity(set, oldlb));
13752  assert(!SCIPsetIsInfinity(set, -oldub));
13753  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13754  assert(!SCIPsetIsInfinity(set, newlb));
13755  assert(!SCIPsetIsInfinity(set, -newub));
13756  assert(var != NULL);
13757 
13759  {
13760  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13761  return SCIP_INVALIDDATA;
13762  }
13763 
13764  assert(SCIPvarGetProbindex(var) >= 0);
13765 
13766  SCIPintervalSet(&deltaval, 0.0);
13767  deltainf = 0;
13768 
13769  /* subtract old pseudo objective value */
13770  if( oldobj > 0.0 )
13771  {
13772  if( SCIPsetIsInfinity(set, -oldlb) )
13773  deltainf--;
13774  else
13775  {
13776  SCIPintervalSet(&bd, oldlb);
13777  SCIPintervalSet(&obj, oldobj);
13778  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13779  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13780  }
13781  }
13782  else if( oldobj < 0.0 )
13783  {
13784  if( SCIPsetIsInfinity(set, oldub) )
13785  deltainf--;
13786  else
13787  {
13788  SCIPintervalSet(&bd, oldub);
13789  SCIPintervalSet(&obj, oldobj);
13790  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13791  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13792  }
13793  }
13794 
13795  /* add new pseudo objective value */
13796  if( newobj > 0.0 )
13797  {
13798  if( SCIPsetIsInfinity(set, -newlb) )
13799  deltainf++;
13800  else
13801  {
13802  SCIPintervalSet(&bd, newlb);
13803  SCIPintervalSet(&obj, newobj);
13804  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13805  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13806  }
13807  }
13808  else if( newobj < 0.0 )
13809  {
13810  if( SCIPsetIsInfinity(set, newub) )
13811  deltainf++;
13812  else
13813  {
13814  SCIPintervalSet(&bd, newub);
13815  SCIPintervalSet(&obj, newobj);
13816  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13817  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13818  }
13819  }
13820 
13821  /* update the pseudo and loose objective values */
13822  SCIPintervalSet(&psval, lp->pseudoobjval);
13823  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13824  lp->pseudoobjval = SCIPintervalGetInf(psval);
13825  lp->pseudoobjvalinf += deltainf;
13827  {
13828  SCIPintervalSet(&psval, lp->looseobjval);
13829  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13830  lp->looseobjval = SCIPintervalGetInf(psval);
13831  lp->looseobjvalinf += deltainf;
13832  }
13833 
13834  assert(lp->pseudoobjvalinf >= 0);
13835  assert(lp->looseobjvalinf >= 0);
13836 
13837  return SCIP_OKAY;
13838 }
13839 
13840 /** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
13842  SCIP_LP* lp, /**< current LP data */
13843  SCIP_SET* set, /**< global SCIP settings */
13844  SCIP_VAR* var, /**< problem variable that changed */
13845  SCIP_Real oldobj, /**< old objective coefficient of variable */
13846  SCIP_Real newobj /**< new objective coefficient of variable */
13847  )
13848 {
13849  assert(set != NULL);
13850  assert(var != NULL);
13851 
13852  if( set->misc_exactsolve )
13853  {
13854  if( oldobj != newobj ) /*lint !e777*/
13855  {
13856  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13857  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13858  }
13859  }
13860  else
13861  {
13862  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13863  {
13864  SCIP_Real deltaval;
13865  int deltainf;
13866 
13868  assert(SCIPvarGetProbindex(var) >= 0);
13869 
13870  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13871  * domain of the variable are the same
13872  */
13873  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13874  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13875 
13876  /* compute the pseudo objective delta due the new objective coefficient */
13877  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13878 
13879  /* update the local pseudo objective value */
13880  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13881 
13882  /* compute the pseudo objective delta due the new objective coefficient */
13883  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13884 
13885  /* update the global pseudo objective value */
13886  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13887  }
13888  }
13889 
13890  return SCIP_OKAY;
13891 }
13892 
13893 
13894 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13896  SCIP_LP* lp, /**< current LP data */
13897  SCIP_SET* set, /**< global SCIP settings */
13898  SCIP_VAR* var, /**< problem variable that changed */
13899  SCIP_Real oldlb, /**< old lower bound of variable */
13900  SCIP_Real newlb /**< new lower bound of variable */
13901  )
13902 {
13903  assert(set != NULL);
13904  assert(var != NULL);
13905 
13906  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13907  {
13908  SCIP_Real deltaval;
13909  int deltainf;
13910 
13911  /* compute the pseudo objective delta due the new lower bound */
13912  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13913 
13914  /* update the root pseudo objective values */
13915  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13916  }
13917 
13918  return SCIP_OKAY;
13919 }
13920 
13921 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13923  SCIP_LP* lp, /**< current LP data */
13924  SCIP_SET* set, /**< global SCIP settings */
13925  SCIP_VAR* var, /**< problem variable that changed */
13926  SCIP_Real oldlb, /**< old lower bound of variable */
13927  SCIP_Real newlb /**< new lower bound of variable */
13928  )
13929 {
13930  assert(set != NULL);
13931  assert(var != NULL);
13932 
13933  if( set->misc_exactsolve )
13934  {
13935  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13936  {
13937  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13938  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13939  }
13940  }
13941  else
13942  {
13943  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13944  {
13945  SCIP_Real deltaval;
13946  int deltainf;
13947 
13949  assert(SCIPvarGetProbindex(var) >= 0);
13950 
13951  /* compute the pseudo objective delta due the new lower bound */
13952  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13953 
13954  /* update the pseudo and loose objective values */
13955  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13956  }
13957  }
13958 
13959  return SCIP_OKAY;
13960 }
13961 
13962 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13964  SCIP_LP* lp, /**< current LP data */
13965  SCIP_SET* set, /**< global SCIP settings */
13966  SCIP_VAR* var, /**< problem variable that changed */
13967  SCIP_Real oldub, /**< old upper bound of variable */
13968  SCIP_Real newub /**< new upper bound of variable */
13969  )
13970 {
13971  assert(set != NULL);
13972  assert(var != NULL);
13973 
13974  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13975  {
13976  SCIP_Real deltaval;
13977  int deltainf;
13978 
13979  /* compute the pseudo objective delta due the new upper bound */
13980  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13981 
13982  /* update the root pseudo objective values */
13983  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13984  }
13985 
13986  return SCIP_OKAY;
13987 }
13988 
13989 /** updates current pseudo objective value for a change in a variable's upper bound */
13991  SCIP_LP* lp, /**< current LP data */
13992  SCIP_SET* set, /**< global SCIP settings */
13993  SCIP_VAR* var, /**< problem variable that changed */
13994  SCIP_Real oldub, /**< old upper bound of variable */
13995  SCIP_Real newub /**< new upper bound of variable */
13996  )
13997 {
13998  assert(set != NULL);
13999  assert(var != NULL);
14000 
14001  if( set->misc_exactsolve )
14002  {
14003  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
14004  {
14005  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
14006  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
14007  }
14008  }
14009  else
14010  {
14011  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
14012  {
14013  SCIP_Real deltaval;
14014  int deltainf;
14015 
14017  assert(SCIPvarGetProbindex(var) >= 0);
14018 
14019  /* compute the pseudo objective delta due the new upper bound */
14020  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
14021 
14022  /* update the pseudo and loose objective values */
14023  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14024  }
14025  }
14026 
14027  return SCIP_OKAY;
14028 }
14029 
14030 /** informs LP, that given variable was added to the problem */
14032  SCIP_LP* lp, /**< current LP data */
14033  SCIP_SET* set, /**< global SCIP settings */
14034  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
14035  )
14036 {
14037  assert(lp != NULL);
14039  assert(SCIPvarGetProbindex(var) >= 0);
14040 
14041  /* add the variable to the loose objective value sum */
14042  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
14043 
14044  /* update the loose variables counter */
14046  lp->nloosevars++;
14047 
14048  return SCIP_OKAY;
14049 }
14050 
14051 /** informs LP, that given variable is to be deleted from the problem */
14053  SCIP_LP* lp, /**< current LP data */
14054  SCIP_SET* set, /**< global SCIP settings */
14055  SCIP_VAR* var /**< variable that will be deleted from the problem */
14056  )
14057 {
14058  assert(lp != NULL);
14060  assert(SCIPvarGetProbindex(var) >= 0);
14061 
14062  /* subtract the variable from the loose objective value sum */
14063  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
14064 
14065  /* update the loose variables counter */
14067  {
14068  SCIPlpDecNLoosevars(lp);
14069  }
14070 
14071  return SCIP_OKAY;
14072 }
14073 
14074 /** informs LP, that given formerly loose problem variable is now a column variable */
14075 static
14077  SCIP_LP* lp, /**< current LP data */
14078  SCIP_SET* set, /**< global SCIP settings */
14079  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14080  )
14081 {
14082  SCIP_Real obj;
14083  SCIP_Real lb;
14084  SCIP_Real ub;
14085 
14086  assert(lp != NULL);
14087  assert(lp->nloosevars > 0);
14088  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14089  assert(SCIPvarGetProbindex(var) >= 0);
14090  assert(lp->looseobjvalinf >= 0);
14091 
14092  obj = SCIPvarGetObj(var);
14093 
14094  /* update loose objective value */
14095  if( SCIPsetIsPositive(set, obj) )
14096  {
14097  lb = SCIPvarGetLbLocal(var);
14098  if( SCIPsetIsInfinity(set, -lb) )
14099  lp->looseobjvalinf--;
14100  else
14101  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14102  }
14103  else if( SCIPsetIsNegative(set, obj) )
14104  {
14105  ub = SCIPvarGetUbLocal(var);
14106  if( SCIPsetIsInfinity(set, ub) )
14107  lp->looseobjvalinf--;
14108  else
14109  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14110  }
14111 
14112  SCIPlpDecNLoosevars(lp);
14113 
14114  assert(lp->looseobjvalinf >= 0);
14115 
14116  return SCIP_OKAY;
14117 }
14118 
14119 /** informs LP, that given formerly loose problem variable is now a column variable
14120  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14121  */
14122 static
14124  SCIP_LP* lp, /**< current LP data */
14125  SCIP_SET* set, /**< global SCIP settings */
14126  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14127  )
14128 {
14129  SCIP_INTERVAL bd;
14130  SCIP_INTERVAL ob;
14131  SCIP_INTERVAL prod;
14132  SCIP_INTERVAL loose;
14133  SCIP_Real obj;
14134  SCIP_Real lb;
14135  SCIP_Real ub;
14136 
14137  assert(lp != NULL);
14138  assert(lp->nloosevars > 0);
14139  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14140  assert(SCIPvarGetProbindex(var) >= 0);
14141 
14142  obj = SCIPvarGetObj(var);
14143 
14144  SCIPintervalSet(&loose, lp->looseobjval);
14145 
14146  /* update loose objective value corresponding to the deletion of variable */
14147  if( obj > 0.0 )
14148  {
14149  lb = SCIPvarGetLbLocal(var);
14150  if( SCIPsetIsInfinity(set, -lb) )
14151  lp->looseobjvalinf--;
14152  else
14153  {
14154  SCIPintervalSet(&bd, lb);
14155  SCIPintervalSet(&ob, obj);
14156  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14157  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14158  }
14159  }
14160  else if( SCIPsetIsNegative(set, obj) )
14161  {
14162  ub = SCIPvarGetUbLocal(var);
14163  if( SCIPsetIsInfinity(set, ub) )
14164  lp->looseobjvalinf--;
14165  else
14166  {
14167  SCIPintervalSet(&bd, ub);
14168  SCIPintervalSet(&ob, obj);
14169  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14170  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14171  }
14172  }
14173  lp->nloosevars--;
14174 
14175  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14176  if( lp->nloosevars == 0 )
14177  {
14178  assert(lp->looseobjvalinf == 0);
14179  lp->looseobjval = 0.0;
14180  }
14181  else
14182  lp->looseobjval = SCIPintervalGetInf(loose);
14183 
14184  return SCIP_OKAY;
14185 }
14186 
14187 /** informs LP, that given formerly loose problem variable is now a column variable */
14189  SCIP_LP* lp, /**< current LP data */
14190  SCIP_SET* set, /**< global SCIP settings */
14191  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14192  )
14193 {
14194  assert(set != NULL);
14195 
14196  if( set->misc_exactsolve )
14197  {
14198  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
14199  }
14200  else
14201  {
14202  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
14203  }
14204 
14205  return SCIP_OKAY;
14206 }
14207 
14208 /** informs LP, that given formerly column problem variable is now again a loose variable */
14209 static
14211  SCIP_LP* lp, /**< current LP data */
14212  SCIP_SET* set, /**< global SCIP settings */
14213  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14214  )
14215 {
14216  SCIP_Real obj;
14217  SCIP_Real lb;
14218  SCIP_Real ub;
14219 
14220  assert(lp != NULL);
14221  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14222  assert(SCIPvarGetProbindex(var) >= 0);
14223  assert(lp->looseobjvalinf >= 0);
14224 
14225  obj = SCIPvarGetObj(var);
14226 
14227  /* update loose objective value corresponding to the addition of variable */
14228  if( SCIPsetIsPositive(set, obj) )
14229  {
14230  lb = SCIPvarGetLbLocal(var);
14231  if( SCIPsetIsInfinity(set, -lb) )
14232  lp->looseobjvalinf++;
14233  else
14234  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14235  }
14236  else if( SCIPsetIsNegative(set, obj) )
14237  {
14238  ub = SCIPvarGetUbLocal(var);
14239  if( SCIPsetIsInfinity(set, ub) )
14240  lp->looseobjvalinf++;
14241  else
14242  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14243  }
14244  lp->nloosevars++;
14245 
14246  assert(lp->looseobjvalinf >= 0);
14247 
14248  return SCIP_OKAY;
14249 }
14250 
14251 /** informs LP, that given formerly column problem variable is now again a loose variable
14252  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14253  */
14254 static
14256  SCIP_LP* lp, /**< current LP data */
14257  SCIP_SET* set, /**< global SCIP settings */
14258  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14259  )
14260 {
14261  SCIP_INTERVAL bd;
14262  SCIP_INTERVAL ob;
14263  SCIP_INTERVAL prod;
14264  SCIP_INTERVAL loose;
14265  SCIP_Real obj;
14266  SCIP_Real lb;
14267  SCIP_Real ub;
14268 
14269  assert(lp != NULL);
14270  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14271  assert(SCIPvarGetProbindex(var) >= 0);
14272 
14273  obj = SCIPvarGetObj(var);
14274 
14275  SCIPintervalSet(&loose, lp->looseobjval);
14276 
14277  /* update loose objective value corresponding to the deletion of variable */
14278  if( obj > 0.0 )
14279  {
14280  lb = SCIPvarGetLbLocal(var);
14281  if( SCIPsetIsInfinity(set, -lb) )
14282  lp->looseobjvalinf++;
14283  else
14284  {
14285  SCIPintervalSet(&bd, lb);
14286  SCIPintervalSet(&ob, obj);
14287  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14288  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14289  }
14290  }
14291  else if( SCIPsetIsNegative(set, obj) )
14292  {
14293  ub = SCIPvarGetUbLocal(var);
14294  if( SCIPsetIsInfinity(set, ub) )
14295  lp->looseobjvalinf++;
14296  else
14297  {
14298  SCIPintervalSet(&bd, ub);
14299  SCIPintervalSet(&ob, obj);
14300  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14301  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14302  }
14303  }
14304  lp->nloosevars++;
14305 
14306  lp->looseobjval = SCIPintervalGetInf(loose);
14307 
14308  return SCIP_OKAY;
14309 }
14310 
14311 /** informs LP, that given formerly column problem variable is now again a loose variable */
14313  SCIP_LP* lp, /**< current LP data */
14314  SCIP_SET* set, /**< global SCIP settings */
14315  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14316  )
14317 {
14318  assert(set != NULL);
14319 
14320  if( set->misc_exactsolve )
14321  {
14322  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14323  }
14324  else
14325  {
14326  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14327  }
14328 
14329  return SCIP_OKAY;
14330 }
14331 
14332 /** decrease the number of loose variables by one */
14334  SCIP_LP* lp /**< current LP data */
14335  )
14336 {
14337  assert(lp != NULL);
14338  assert(lp->nloosevars > 0);
14339 
14340  lp->nloosevars--;
14341 
14342  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14343  if( lp->nloosevars == 0 )
14344  {
14345  assert(lp->looseobjvalinf == 0);
14346  lp->looseobjval = 0.0;
14347  }
14348 }
14349 
14350 /** stores the LP solution in the columns and rows */
14352  SCIP_LP* lp, /**< current LP data */
14353  SCIP_SET* set, /**< global SCIP settings */
14354  SCIP_STAT* stat, /**< problem statistics */
14355  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14356  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14357  )
14358 {
14359  SCIP_COL** lpicols;
14360  SCIP_ROW** lpirows;
14361  SCIP_Real* primsol;
14362  SCIP_Real* dualsol;
14363  SCIP_Real* activity = NULL;
14364  SCIP_Real* redcost;
14365  SCIP_Real primalbound;
14366  SCIP_Real dualbound;
14367  SCIP_Bool stillprimalfeasible;
14368  SCIP_Bool stilldualfeasible;
14369  int* cstat;
14370  int* rstat;
14371  SCIP_Longint lpcount;
14372  int nlpicols;
14373  int nlpirows;
14374  int c;
14375  int r;
14376 
14377  assert(lp != NULL);
14378  assert(lp->flushed);
14379  assert(lp->solved);
14380  assert(set != NULL);
14381  assert(stat != NULL);
14382  assert(lp->validsollp <= stat->lpcount);
14383 
14384  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
14385 
14386  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14387  * corresponding flag immediately to FALSE to skip all checks
14388  */
14389  if( primalfeasible == NULL )
14390  stillprimalfeasible = FALSE;
14391  else
14392  {
14393  *primalfeasible = TRUE;
14394  stillprimalfeasible = TRUE;
14395  }
14396  if( dualfeasible == NULL )
14397  stilldualfeasible = FALSE;
14398  else
14399  {
14400  *dualfeasible = TRUE;
14401  stilldualfeasible = TRUE;
14402  }
14403 
14404  /* check if the values are already calculated */
14405  if( lp->validsollp == stat->lpcount )
14406  return SCIP_OKAY;
14407  lp->validsollp = stat->lpcount;
14408 
14409  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14410  stat->lpcount, SCIPlpGetSolstat(lp));
14411 
14412  lpicols = lp->lpicols;
14413  lpirows = lp->lpirows;
14414  nlpicols = lp->nlpicols;
14415  nlpirows = lp->nlpirows;
14416  lpcount = stat->lpcount;
14417 
14418  /* get temporary memory */
14419  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14420  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14421 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14422  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14423 #endif
14424  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14425  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14426  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14427 
14428  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14429  if( lp->solisbasic )
14430  {
14431  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14432  }
14433  else
14434  {
14435  BMSclearMemoryArray(cstat, nlpicols);
14436  BMSclearMemoryArray(rstat, nlpirows);
14437  }
14438 
14439  primalbound = 0.0;
14440  dualbound = 0.0;
14441 
14442  /* copy primal solution and reduced costs into columns */
14443  for( c = 0; c < nlpicols; ++c )
14444  {
14445  assert( 0 <= cstat[c] && cstat[c] < 4 );
14446  lpicols[c]->primsol = primsol[c];
14447  if( !SCIPisFinite(lpicols[c]->primsol) )
14448  {
14449  /* calculating with nan or +/-inf can have many unexpected effects
14450  * thus change the solution here to a reasonable value (0.0) and declare it as neither primal nor dual feasible
14451  * this should trigger a resolve of the LP, or a stop with an LP error
14452  */
14453  stillprimalfeasible = FALSE;
14454  stilldualfeasible = FALSE;
14455  lpicols[c]->primsol = 0.0;
14456  SCIPsetDebugMsg(set, " col <%s>: primsol=%.9f is not finite\n", SCIPvarGetName(lpicols[c]->var), primsol[c]);
14457  }
14458  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14459  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14460  lpicols[c]->redcost = redcost[c];
14461  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14462  lpicols[c]->validredcostlp = lpcount;
14463  if( stillprimalfeasible )
14464  {
14465  stillprimalfeasible =
14466  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
14467  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
14468  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14469  }
14470  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14471  {
14472  double compslack;
14473 
14474  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14475  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14476  * variables, which would magnify even the tiniest violation in the dual multiplier
14477  */
14478  if( stilldualfeasible )
14479  {
14480  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14481  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14482  }
14483  if( stilldualfeasible )
14484  {
14485  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14486  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14487  }
14488 
14489  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14490  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14491  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14492  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14493  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14494  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14495  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14496  dualfeasible != NULL ? stilldualfeasible : TRUE);
14497  }
14498  else
14499  {
14500  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14501  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14502  {
14503  lpicols[c]->redcost = 0.0;
14504  }
14505 
14506  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14507  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14508  * bounds, its reduced cost must be zero
14509  */
14510  if( stilldualfeasible
14511  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
14512  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14513  if( stilldualfeasible
14514  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
14515  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14516 
14517  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14518  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14519  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14520  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14521  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14522  !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14523  !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14524  dualfeasible != NULL ? stilldualfeasible : TRUE);
14525  }
14526 
14527  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14528  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14529  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14530  */
14531  if( stilldualfeasible )
14532  {
14533  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14534  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14535  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14536  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14537  }
14538  }
14539 
14540  /* copy dual solution and activities into rows */
14541  for( r = 0; r < nlpirows; ++r )
14542  {
14543  assert( 0 <= rstat[r] && rstat[r] < 4 );
14544  lpirows[r]->dualsol = dualsol[r];
14545 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14546  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14547 #else
14548  /* calculate row activity if invalid */
14549  if( lpirows[r]->validactivitylp != stat->lpcount )
14550  SCIProwRecalcLPActivity(lpirows[r], stat);
14551 #endif
14552  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14553  lpirows[r]->validactivitylp = lpcount;
14554  if( stillprimalfeasible )
14555  {
14556  stillprimalfeasible =
14557  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14558  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14559  }
14560  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14561  {
14562  double compslack;
14563 
14564  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14565  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14566  * variables, which would magnify even the tiniest violation in the dual multiplier
14567  */
14568  if( stilldualfeasible )
14569  {
14570  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14571  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14572  }
14573  if( stilldualfeasible )
14574  {
14575  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14576  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14577  }
14578 
14579  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14580  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14581  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14582  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14583  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14584  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14585  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14586  dualfeasible != NULL ? stilldualfeasible : TRUE);
14587  }
14588  else
14589  {
14590  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14591  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14592  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14593  */
14594  if( stilldualfeasible &&
14595  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
14596  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14597  if( stilldualfeasible &&
14598  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
14599  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14600 
14601  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14602  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14603  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14604  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14605  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14606  !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14607  !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14608  dualfeasible != NULL ? stilldualfeasible : TRUE);
14609  }
14610 
14611  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14612  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14613  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14614  */
14615  if( stilldualfeasible )
14616  {
14617  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14618  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14619  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14620  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14621  }
14622  }
14623 
14624  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14625  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14626  * infinity
14627  */
14628  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14629  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14630  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14631  {
14632  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14633  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14634  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14635  }
14636 
14637  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14638  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14639  */
14640  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14641  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14642  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14643  {
14644  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14645  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14646  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14647  }
14648 
14649  if( primalfeasible != NULL )
14650  *primalfeasible = stillprimalfeasible;
14651  if( dualfeasible != NULL )
14652  *dualfeasible = stilldualfeasible;
14653 
14654  /* free temporary memory */
14655  SCIPsetFreeBufferArray(set, &rstat);
14656  SCIPsetFreeBufferArray(set, &cstat);
14657  SCIPsetFreeBufferArray(set, &redcost);
14658 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14659  SCIPsetFreeBufferArray(set, &activity);
14660 #endif
14661  SCIPsetFreeBufferArray(set, &dualsol);
14662  SCIPsetFreeBufferArray(set, &primsol);
14663 
14664  return SCIP_OKAY;
14665 }
14666 
14667 /** stores LP solution with infinite objective value in the columns and rows */
14669  SCIP_LP* lp, /**< current LP data */
14670  SCIP_SET* set, /**< global SCIP settings */
14671  SCIP_STAT* stat, /**< problem statistics */
14672  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14673  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14674  )
14675 {
14676  SCIP_COL** lpicols;
14677  SCIP_ROW** lpirows;
14678  SCIP_Real* primsol;
14679  SCIP_Real* activity;
14680  SCIP_Real* ray;
14681  SCIP_Real rayobjval;
14682  SCIP_Real rayscale;
14683  SCIP_Longint lpcount;
14684  SCIP_COL* col;
14685  int nlpicols;
14686  int nlpirows;
14687  int c;
14688  int r;
14689 
14690  assert(lp != NULL);
14691  assert(lp->flushed);
14692  assert(lp->solved);
14693  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14694  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14695  assert(set != NULL);
14696  assert(stat != NULL);
14697  assert(lp->validsollp <= stat->lpcount);
14698 
14699  if( primalfeasible != NULL )
14700  *primalfeasible = TRUE;
14701  if( rayfeasible != NULL )
14702  *rayfeasible = TRUE;
14703 
14704  /* check if the values are already calculated */
14705  if( lp->validsollp == stat->lpcount )
14706  return SCIP_OKAY;
14707  lp->validsollp = stat->lpcount;
14708 
14709  /* check if the LP solver is able to provide a primal unbounded ray */
14710  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14711  {
14712  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness.\n");
14713  return SCIP_LPERROR;
14714  }
14715 
14716  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14717 
14718  /* get temporary memory */
14719  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14720  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14721  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14722 
14723  /* get primal unbounded ray */
14724  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14725 
14726  lpicols = lp->lpicols;
14727  lpirows = lp->lpirows;
14728  nlpicols = lp->nlpicols;
14729  nlpirows = lp->nlpirows;
14730  lpcount = stat->lpcount;
14731 
14732  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14733  rayobjval = 0.0;
14734  for( c = 0; c < nlpicols; ++c )
14735  {
14736  assert(lpicols[c] != NULL);
14737  assert(lpicols[c]->var != NULL);
14738 
14739  col = lpicols[c];
14740 
14741  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14742  if( rayfeasible != NULL )
14743  {
14744  *rayfeasible = *rayfeasible
14745  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14746  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14747  }
14748 
14749  if( ! SCIPsetIsZero(set, ray[c]) )
14750  rayobjval += ray[c] * col->obj;
14751 
14752  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14753  * heuristically try to construct a primal solution.
14754  */
14755  primsol[c] = 0.0;
14756  if( SCIPsetIsFeasZero(set, ray[c]) )
14757  {
14758  /* if the ray component is 0, we try to satisfy as many rows as possible */
14759  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14760  primsol[c] = col->lb;
14761  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14762  primsol[c] = col->ub;
14763  }
14764 
14765  /* make sure we respect the bounds */
14766  primsol[c] = MAX(primsol[c], col->lb);
14767  primsol[c] = MIN(primsol[c], col->ub);
14768 
14769  assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
14770  }
14771 
14772  /* check feasibility of heuristic primal solution */
14773  for( r = 0; r < nlpirows; ++r )
14774  {
14775  SCIP_Real act;
14776  SCIP_ROW* row;
14777 
14778  row = lpirows[r];
14779  assert( row != NULL );
14780  act = row->constant;
14781 
14782  for( c = 0; c < row->nlpcols; ++c )
14783  {
14784  col = row->cols[c];
14785 
14786  assert( col != NULL );
14787  assert( col->lppos >= 0 );
14788  assert( row->linkpos[c] >= 0 );
14789  assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
14790 
14791  act += row->vals[c] * primsol[col->lppos];
14792  }
14793 
14794  if( row->nunlinked > 0 )
14795  {
14796  for( c = row->nlpcols; c < row->len; ++c )
14797  {
14798  col = row->cols[c];
14799  assert( col != NULL );
14800 
14801  if( col->lppos >= 0 )
14802  act += row->vals[c] * primsol[col->lppos];
14803  }
14804  }
14805 
14806  /* check feasibility */
14807  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
14808  (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
14809  break;
14810  }
14811 
14812  /* if heuristic primal solution is not feasible, try to obtain solution from LPI */
14813  if( r < nlpirows )
14814  {
14815  /* get primal feasible point */
14816  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
14817 
14818  /* check bounds of primal solution */
14819  if( primalfeasible != NULL )
14820  {
14821  assert( *primalfeasible );
14822  for( c = 0; c < nlpicols; ++c )
14823  {
14824  assert( lpicols[c] != NULL );
14825  assert( lpicols[c]->var != NULL );
14826 
14827  /* check whether primal solution satisfies the bounds; note that we also ensure that the primal
14828  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined */
14829  if( SCIPsetIsInfinity(set, REALABS(primsol[c])) || SCIPlpIsFeasLT(set, lp, primsol[c], lpicols[c]->lb) ||
14830  SCIPlpIsFeasGT(set, lp, primsol[c], lpicols[c]->ub) )
14831  {
14832  *primalfeasible = FALSE;
14833  break;
14834  }
14835  }
14836  }
14837  }
14838 
14839  /* compute activity and check feasibility of primal solution and ray */
14840  for( r = 0; r < nlpirows; ++r )
14841  {
14842  SCIP_Real primact;
14843  SCIP_Real rayact = 0.0;
14844  SCIP_ROW* row;
14845 
14846  row = lpirows[r];
14847  assert( row != NULL );
14848 
14849  primact = row->constant;
14850 
14851  for( c = 0; c < row->nlpcols; ++c )
14852  {
14853  col = row->cols[c];
14854 
14855  assert( col != NULL );
14856  assert( col->lppos >= 0 );
14857  assert( row->linkpos[c] >= 0 );
14858  assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
14859 
14860  primact += row->vals[c] * primsol[col->lppos];
14861  rayact += row->vals[c] * ray[col->lppos];
14862  }
14863 
14864  if( row->nunlinked > 0 )
14865  {
14866  for( c = row->nlpcols; c < row->len; ++c )
14867  {
14868  col = row->cols[c];
14869  assert( col != NULL );
14870 
14871  if( col->lppos >= 0 )
14872  {
14873  primact += row->vals[c] * primsol[col->lppos];
14874  rayact += row->vals[c] * ray[col->lppos];
14875  }
14876  }
14877  }
14878 
14879  /* check feasibility of primal solution */
14880  if( primalfeasible != NULL && *primalfeasible )
14881  {
14882  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, primact, row->lhs) ) ||
14883  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, primact, row->rhs) ) )
14884  *primalfeasible = FALSE;
14885  }
14886 
14887  /* check feasibility of ray */
14888  if( rayfeasible != NULL && *rayfeasible )
14889  {
14890  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, rayact, 0.0) ) ||
14891  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, rayact, 0.0) ) )
14892  *rayfeasible = FALSE;
14893  }
14894 
14895  /* store activity of primal solution */
14896  activity[r] = primact;
14897  }
14898 
14899  if( primalfeasible != NULL && !(*primalfeasible) )
14900  {
14901  /* if the finite point is already infeasible, we do not have to add the ray */
14902  rayscale = 0.0;
14903  }
14904  else if( rayfeasible != NULL && !(*rayfeasible) )
14905  {
14906  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14907  rayscale = 0.0;
14908  }
14909  else if( !SCIPsetIsNegative(set, rayobjval) )
14910  {
14911  /* due to numerical problems, the objective of the ray might be nonnegative
14912  *
14913  * @todo How to check for negative objective value here?
14914  */
14915  if( rayfeasible != NULL )
14916  *rayfeasible = FALSE;
14917 
14918  rayscale = 0.0;
14919  }
14920  else
14921  {
14922  assert(rayobjval != 0.0);
14923 
14924  /* scale the ray, such that the resulting point has infinite objective value */
14925  rayscale = -2.0 * SCIPsetInfinity(set) / rayobjval;
14926  assert(SCIPsetIsFeasPositive(set, rayscale));
14927 
14928  /* ensure that unbounded point does not violate the bounds of the variables */
14929  for( c = 0; c < nlpicols; ++c )
14930  {
14931  if( SCIPsetIsPositive(set, ray[c]) )
14932  {
14933  if( !SCIPsetIsInfinity(set, primsol[c]) )
14934  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c]) / ray[c]);
14935  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14936  else
14937  {
14938  assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
14939  rayscale = MIN(rayscale, 1.0 / ray[c]);
14940  }
14941  }
14942  else if( SCIPsetIsNegative(set, ray[c]) )
14943  {
14944  if( !SCIPsetIsInfinity(set, -primsol[c]) )
14945  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c]) / ray[c]);
14946  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14947  else
14948  {
14949  assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
14950  rayscale = MIN(rayscale, -1.0 / ray[c]);
14951  }
14952  }
14953 
14954  assert(SCIPsetIsFeasPositive(set, rayscale));
14955  }
14956  }
14957 
14958  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14959 
14960  /* calculate the unbounded point: x' = x + rayscale * ray */
14961  /* Note: We do not check the feasibility of the unbounded solution, because it will likely be infeasible due to the
14962  * typically large values in scaling. */
14963  for( c = 0; c < nlpicols; ++c )
14964  {
14965  if( SCIPsetIsZero(set, ray[c]) )
14966  lpicols[c]->primsol = primsol[c];
14967  else
14968  {
14969  SCIP_Real primsolval;
14970  primsolval = primsol[c] + rayscale * ray[c];
14971  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14972  }
14973  lpicols[c]->redcost = SCIP_INVALID;
14974  lpicols[c]->validredcostlp = -1;
14975  }
14976 
14977  /* transfer solution */
14978  for( r = 0; r < nlpirows; ++r )
14979  {
14980  lpirows[r]->dualsol = SCIP_INVALID;
14981  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14982  lpirows[r]->validactivitylp = lpcount;
14983  }
14984 
14985  /* free temporary memory */
14986  SCIPsetFreeBufferArray(set, &ray);
14987  SCIPsetFreeBufferArray(set, &activity);
14988  SCIPsetFreeBufferArray(set, &primsol);
14989 
14990  return SCIP_OKAY;
14991 }
14992 
14993 /** returns primal ray proving the unboundedness of the current LP */
14995  SCIP_LP* lp, /**< current LP data */
14996  SCIP_SET* set, /**< global SCIP settings */
14997  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14998  * so the size of this array should be at least number of active variables
14999  * (all entries have to be initialized to 0 before) */
15000  )
15001 {
15002  SCIP_COL** lpicols;
15003  SCIP_Real* lpiray;
15004  SCIP_VAR* var;
15005  int nlpicols;
15006  int c;
15007 
15008  assert(lp != NULL);
15009  assert(set != NULL);
15010  assert(ray != NULL);
15011  assert(lp->flushed);
15012  assert(lp->solved);
15013  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
15014  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
15015 
15016  /* check if the LP solver is able to provide a primal unbounded ray */
15017  if( !SCIPlpiHasPrimalRay(lp->lpi) )
15018  {
15019  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
15020  return SCIP_LPERROR;
15021  }
15022 
15023  /* get temporary memory */
15024  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
15025 
15026  SCIPsetDebugMsg(set, "getting primal ray values\n");
15027 
15028  /* get primal unbounded ray */
15029  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
15030 
15031  lpicols = lp->lpicols;
15032  nlpicols = lp->nlpicols;
15033 
15034  /* store the ray values of active problem variables */
15035  for( c = 0; c < nlpicols; c++ )
15036  {
15037  assert(lpicols[c] != NULL);
15038 
15039  var = lpicols[c]->var;
15040  assert(var != NULL);
15041  assert(SCIPvarGetProbindex(var) != -1);
15042  ray[SCIPvarGetProbindex(var)] = lpiray[c];
15043  }
15044 
15045  SCIPsetFreeBufferArray(set, &lpiray);
15046 
15047  return SCIP_OKAY;
15048 }
15049 
15050 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
15051  * lp/checkfarkas = TRUE.
15052  *
15053  * @note the check will not be performed if @p valid is NULL.
15054  */
15056  SCIP_LP* lp, /**< current LP data */
15057  SCIP_SET* set, /**< global SCIP settings */
15058  SCIP_STAT* stat, /**< problem statistics */
15059  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
15060  )
15061 {
15062  SCIP_COL** lpicols;
15063  SCIP_ROW** lpirows;
15064  SCIP_Real* dualfarkas;
15065  SCIP_Real* farkascoefs;
15066  SCIP_Real farkaslhs;
15067  SCIP_Real maxactivity;
15068  SCIP_Bool checkfarkas;
15069  int nlpicols;
15070  int nlpirows;
15071  int c;
15072  int r;
15073 
15074  assert(lp != NULL);
15075  assert(lp->flushed);
15076  assert(lp->solved);
15077  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
15078  assert(set != NULL);
15079  assert(stat != NULL);
15080  assert(lp->validfarkaslp <= stat->lpcount);
15081 
15082  if( valid != NULL )
15083  *valid = TRUE;
15084 
15085  /* check if the values are already calculated */
15086  if( lp->validfarkaslp == stat->lpcount )
15087  return SCIP_OKAY;
15088  lp->validfarkaslp = stat->lpcount;
15089 
15090  farkascoefs = NULL;
15091  maxactivity = 0.0;
15092  farkaslhs = 0.0;
15093 
15094  checkfarkas = (set->lp_checkfarkas && valid != NULL);
15095 
15096  /* get temporary memory */
15097  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
15098 
15099  if( checkfarkas )
15100  {
15101  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
15102  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
15103  }
15104 
15105  /* get dual Farkas infeasibility proof */
15106  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
15107 
15108  lpicols = lp->lpicols;
15109  lpirows = lp->lpirows;
15110  nlpicols = lp->nlpicols;
15111  nlpirows = lp->nlpirows;
15112 
15113  /* store infeasibility proof in rows */
15114  SCIPsetDebugMsg(set, "LP is infeasible:\n");
15115  for( r = 0; r < nlpirows; ++r )
15116  {
15117  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
15118  lpirows[r]->dualfarkas = dualfarkas[r];
15119  lpirows[r]->dualsol = SCIP_INVALID;
15120  lpirows[r]->activity = 0.0;
15121  lpirows[r]->validactivitylp = -1L;
15122  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
15123 
15124  if( checkfarkas )
15125  {
15126  assert(farkascoefs != NULL);
15127 
15128  /* the infeasibility proof would be invalid if
15129  * (i) dualfarkas[r] > 0 and lhs = -inf
15130  * (ii) dualfarkas[r] < 0 and rhs = inf
15131  * however, due to numerics we accept slightly negative / positive values
15132  */
15133  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15134  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15135  {
15136  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15137  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15138 
15139  if( valid != NULL )
15140  *valid = FALSE;
15141 
15142  goto TERMINATE;
15143  }
15144 
15145  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15146  * within tolerances (see above) but slighty positive / negative
15147  */
15148  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15149  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15150  continue;
15151 
15152  /* iterate over all columns and scale with dual solution */
15153  for( c = 0; c < lpirows[r]->len; c++ )
15154  {
15155  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15156 
15157  if( pos == -1 )
15158  continue;
15159 
15160  assert(pos >= 0 && pos < nlpicols);
15161 
15162  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15163  }
15164 
15165  /* the row contributes with its left-hand side to the proof */
15166  if( dualfarkas[r] > 0.0 )
15167  {
15168  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15169 
15170  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
15171  }
15172  /* the row contributes with its right-hand side to the proof */
15173  else if( dualfarkas[r] < 0.0 )
15174  {
15175  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15176 
15177  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
15178  }
15179  }
15180  }
15181 
15182  /* set columns as invalid */
15183  for( c = 0; c < nlpicols; ++c )
15184  {
15185  lpicols[c]->primsol = SCIP_INVALID;
15186  lpicols[c]->redcost = SCIP_INVALID;
15187  lpicols[c]->validredcostlp = -1L;
15188  lpicols[c]->validfarkaslp = -1L;
15189 
15190  if( checkfarkas )
15191  {
15192  assert(farkascoefs != NULL);
15193  assert(SCIPcolGetLPPos(lpicols[c]) == c);
15194 
15195  /* skip coefficients that are too close to zero */
15196  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
15197  continue;
15198 
15199  /* calculate the maximal activity */
15200  if( farkascoefs[c] > 0.0 )
15201  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
15202  else
15203  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
15204  }
15205  }
15206 
15207  /* check whether the farkasproof is valid
15208  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
15209  * in that case, we declare the Farkas proof to be invalid.
15210  */
15211  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
15212  {
15213  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15214 
15215  if( valid != NULL )
15216  *valid = FALSE;
15217  }
15218 
15219  TERMINATE:
15220  /* free temporary memory */
15221  if( checkfarkas )
15222  SCIPsetFreeBufferArray(set, &farkascoefs);
15223 
15224  SCIPsetFreeBufferArray(set, &dualfarkas);
15225 
15226  return SCIP_OKAY;
15227 }
15228 
15229 /** get number of iterations used in last LP solve */
15231  SCIP_LP* lp, /**< current LP data */
15232  int* iterations /**< pointer to store the iteration count */
15233  )
15234 {
15235  assert(lp != NULL);
15236 
15237  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15238 
15239  return SCIP_OKAY;
15240 }
15241 
15242 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15243  * resets age of non-zero columns and sharp rows
15244  */
15246  SCIP_LP* lp, /**< current LP data */
15247  SCIP_STAT* stat /**< problem statistics */
15248  )
15249 {
15250  SCIP_COL** lpicols;
15251  SCIP_ROW** lpirows;
15252  int nlpicols;
15253  int nlpirows;
15254  int c;
15255  int r;
15256 
15257  assert(lp != NULL);
15258  assert(lp->flushed);
15259  assert(lp->solved);
15260  assert(lp->nlpicols == lp->ncols);
15261  assert(lp->nlpirows == lp->nrows);
15262  assert(stat != NULL);
15263  assert(lp->validsollp == stat->lpcount);
15264 
15265  SCIPdebugMessage("updating LP ages\n");
15266 
15267  lpicols = lp->lpicols;
15268  lpirows = lp->lpirows;
15269  nlpicols = lp->nlpicols;
15270  nlpirows = lp->nlpirows;
15271 
15272  for( c = 0; c < nlpicols; ++c )
15273  {
15274  assert(lpicols[c] == lp->cols[c]);
15275  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15276  lpicols[c]->age++;
15277  else
15278  lpicols[c]->age = 0;
15279  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15280  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15281  }
15282 
15283  for( r = 0; r < nlpirows; ++r )
15284  {
15285  lpirows[r]->nlpsaftercreation++;
15286  assert(lpirows[r] == lp->rows[r]);
15287 
15288  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15289  {
15290  lpirows[r]->age++;
15291  }
15292  else
15293  {
15294  lpirows[r]->activeinlpcounter++;
15295  lpirows[r]->age = 0;
15296  }
15297  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15298  }
15299 
15300  return SCIP_OKAY;
15301 }
15302 
15303 /* deletes the marked columns from the LP and the LP interface */
15304 static
15306  SCIP_LP* lp, /**< current LP data */
15307  SCIP_SET* set, /**< global SCIP settings */
15308  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15309  )
15310 {
15311  SCIP_COL* col;
15312  int ncols;
15313  int c;
15314 
15315  assert(lp != NULL);
15316  assert(lp->flushed);
15317  assert(lp->ncols == lp->nlpicols);
15318  assert(!lp->diving);
15319  assert(coldstat != NULL);
15320  assert(lp->nlazycols <= lp->ncols);
15321 
15322  ncols = lp->ncols;
15323 
15324  /* delete columns in LP solver */
15325  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15326 
15327  /* update LP data respectively */
15328  for( c = 0; c < ncols; ++c )
15329  {
15330  col = lp->cols[c];
15331  assert(col != NULL);
15332  assert(col == lp->lpicols[c]);
15333  assert(coldstat[c] <= c);
15334  col->lppos = coldstat[c];
15335  if( coldstat[c] == -1 )
15336  {
15337  assert(col->removable);
15338 
15339  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15340  * function vector norms
15341  */
15342  markColDeleted(col);
15343  colUpdateDelLP(col, set);
15344  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15345  col->lpdepth = -1;
15346 
15347  lp->cols[c] = NULL;
15348  lp->lpicols[c] = NULL;
15349  lp->ncols--;
15350  lp->nremovablecols--;
15351  lp->nlpicols--;
15352  }
15353  else if( coldstat[c] < c )
15354  {
15355  assert(lp->cols[coldstat[c]] == NULL);
15356  assert(lp->lpicols[coldstat[c]] == NULL);
15357  lp->cols[coldstat[c]] = col;
15358  lp->lpicols[coldstat[c]] = col;
15359  lp->cols[coldstat[c]]->lppos = coldstat[c];
15360  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15361  lp->cols[c] = NULL;
15362  lp->lpicols[c] = NULL;
15363  }
15364  }
15365 
15366  /* remove columns which are deleted from the lazy column array */
15367  c = 0;
15368  while( c < lp->nlazycols )
15369  {
15370  if( lp->lazycols[c]->lpipos < 0 )
15371  {
15372  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15373  lp->nlazycols--;
15374  }
15375  else
15376  c++;
15377  }
15378 
15379  /* mark LP to be unsolved */
15380  if( lp->ncols < ncols )
15381  {
15382  assert(lp->ncols == lp->nlpicols);
15383  assert(lp->nchgcols == 0);
15384  assert(lp->flushed);
15385 
15386  lp->lpifirstchgcol = lp->nlpicols;
15387 
15388  /* mark the current solution invalid */
15389  lp->solved = FALSE;
15390  lp->primalfeasible = FALSE;
15391  lp->primalchecked = FALSE;
15392  lp->lpobjval = SCIP_INVALID;
15394  }
15395 
15396  checkLazyColArray(lp, set);
15397  checkLinks(lp);
15398 
15399  return SCIP_OKAY;
15400 }
15401 
15402 /* deletes the marked rows from the LP and the LP interface */
15403 static
15405  SCIP_LP* lp, /**< current LP data */
15406  BMS_BLKMEM* blkmem, /**< block memory buffers */
15407  SCIP_SET* set, /**< global SCIP settings */
15408  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15409  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15410  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15411  )
15412 {
15413  SCIP_ROW* row;
15414  int nrows;
15415  int r;
15416 
15417  assert(lp != NULL);
15418  assert(lp->flushed);
15419  assert(lp->nrows == lp->nlpirows);
15420  assert(!lp->diving);
15421  assert(rowdstat != NULL);
15422 
15423  nrows = lp->nrows;
15424 
15425  /* delete rows in LP solver */
15426  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15427 
15428  /* update LP data respectively */
15429  for( r = 0; r < nrows; ++r )
15430  {
15431  row = lp->rows[r];
15432  assert(row == lp->lpirows[r]);
15433  assert(rowdstat[r] <= r);
15434  assert(row != NULL);
15435  row->lppos = rowdstat[r];
15436  if( rowdstat[r] == -1 )
15437  {
15438  if( row->removable )
15439  lp->nremovablerows--;
15440 
15441  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15442  markRowDeleted(row);
15443  rowUpdateDelLP(row);
15444  row->lpdepth = -1;
15445 
15446  /* check, if row deletion events are tracked
15447  * if so, issue ROWDELETEDLP event
15448  */
15449  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15450  {
15451  SCIP_EVENT* event;
15452 
15453  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15454  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15455  }
15456 
15457  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15458  SCIProwUnlock(lp->rows[r]);
15459  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15460  assert(lp->lpirows[r] == NULL);
15461  assert(lp->rows[r] == NULL);
15462  lp->nrows--;
15463  lp->nlpirows--;
15464  }
15465  else if( rowdstat[r] < r )
15466  {
15467  assert(lp->rows[rowdstat[r]] == NULL);
15468  assert(lp->lpirows[rowdstat[r]] == NULL);
15469  lp->rows[rowdstat[r]] = row;
15470  lp->lpirows[rowdstat[r]] = row;
15471  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15472  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15473  lp->rows[r] = NULL;
15474  lp->lpirows[r] = NULL;
15475  }
15476  }
15477 
15478  /* mark LP to be unsolved */
15479  if( lp->nrows < nrows )
15480  {
15481  assert(lp->nrows == lp->nlpirows);
15482  assert(lp->nchgrows == 0);
15483  assert(lp->flushed);
15484 
15485  lp->lpifirstchgrow = lp->nlpirows;
15486 
15487  /* mark the current solution invalid */
15488  lp->solved = FALSE;
15489  lp->dualfeasible = FALSE;
15490  lp->dualchecked = FALSE;
15491  lp->lpobjval = SCIP_INVALID;
15493  }
15494 
15495  checkLinks(lp);
15496 
15497  return SCIP_OKAY;
15498 }
15499 
15500 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15501 static
15503  SCIP_LP* lp, /**< current LP data */
15504  SCIP_SET* set, /**< global SCIP settings */
15505  SCIP_STAT* stat, /**< problem statistics */
15506  int firstcol /**< first column to check for clean up */
15507  )
15508 {
15509  SCIP_COL** cols;
15510 #ifndef NDEBUG
15511  SCIP_COL** lpicols;
15512 #endif
15513  int* coldstat;
15514  int ncols;
15515  int ndelcols;
15516  int c;
15517 
15518  assert(lp != NULL);
15519  assert(lp->flushed);
15520  assert(lp->ncols == lp->nlpicols);
15521  assert(lp->nremovablecols <= lp->ncols);
15522  assert(!lp->diving);
15523  assert(set != NULL);
15524  assert(stat != NULL);
15525 
15526  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15527  return SCIP_OKAY;
15528 
15529  ncols = lp->ncols;
15530  cols = lp->cols;
15531 #ifndef NDEBUG
15532  lpicols = lp->lpicols;
15533 #endif
15534 
15535  /* get temporary memory */
15536  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15537 
15538  /* mark obsolete columns to be deleted */
15539  ndelcols = 0;
15540  BMSclearMemoryArray(coldstat, ncols);
15541  for( c = firstcol; c < ncols; ++c )
15542  {
15543  assert(cols[c] == lpicols[c]);
15544  assert(cols[c]->lppos == c);
15545  assert(cols[c]->lpipos == c);
15546  if( cols[c]->removable
15547  && 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 */
15548  && cols[c]->age > set->lp_colagelimit
15550  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15551  {
15552  assert(cols[c]->primsol == 0.0);
15553  coldstat[c] = 1;
15554  ndelcols++;
15555  cols[c]->obsoletenode = stat->nnodes;
15556  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15557  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15558  }
15559  }
15560 
15561  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15562 
15563  /* delete the marked columns in the LP solver interface, update the LP respectively */
15564  if( ndelcols > 0 )
15565  {
15566  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15567  }
15568  assert(lp->ncols == ncols - ndelcols);
15569 
15570  /* release temporary memory */
15571  SCIPsetFreeBufferArray(set, &coldstat);
15572 
15573  return SCIP_OKAY;
15574 }
15575 
15576 /** removes all basic rows, that are too old, beginning with the given firstrow */
15577 static
15579  SCIP_LP* lp, /**< current LP data */
15580  BMS_BLKMEM* blkmem, /**< block memory buffers */
15581  SCIP_SET* set, /**< global SCIP settings */
15582  SCIP_STAT* stat, /**< problem statistics */
15583  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15584  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15585  int firstrow /**< first row to check for clean up */
15586  )
15587 {
15588  SCIP_ROW** rows;
15589 #ifndef NDEBUG
15590  SCIP_ROW** lpirows;
15591 #endif
15592  int* rowdstat;
15593  int nrows;
15594  int ndelrows;
15595  int r;
15596 
15597  assert(lp != NULL);
15598  assert(lp->flushed);
15599  assert(lp->nrows == lp->nlpirows);
15600  assert(lp->nremovablerows <= lp->nrows);
15601  assert(!lp->diving);
15602  assert(set != NULL);
15603  assert(stat != NULL);
15604 
15605  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15606  return SCIP_OKAY;
15607 
15608  nrows = lp->nrows;
15609  rows = lp->rows;
15610 #ifndef NDEBUG
15611  lpirows = lp->lpirows;
15612 #endif
15613 
15614  /* get temporary memory */
15615  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15616 
15617  /* mark obsolete rows to be deleted */
15618  ndelrows = 0;
15619  BMSclearMemoryArray(rowdstat, nrows);
15620  for( r = firstrow; r < nrows; ++r )
15621  {
15622  assert(rows[r] == lpirows[r]);
15623  assert(rows[r]->lppos == r);
15624  assert(rows[r]->lpipos == r);
15625  if( rows[r]->removable
15626  && 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 */
15627  && rows[r]->age > set->lp_rowagelimit
15629  {
15630  rowdstat[r] = 1;
15631  ndelrows++;
15632  rows[r]->obsoletenode = stat->nnodes;
15633  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15634  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15635  }
15636  }
15637 
15638  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15639 
15640  /* delete the marked rows in the LP solver interface, update the LP respectively */
15641  if( ndelrows > 0 )
15642  {
15643  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15644  }
15645  assert(lp->nrows == nrows - ndelrows);
15646 
15647  /* release temporary memory */
15648  SCIPsetFreeBufferArray(set, &rowdstat);
15649 
15650  return SCIP_OKAY;
15651 }
15652 
15653 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15655  SCIP_LP* lp, /**< current LP data */
15656  BMS_BLKMEM* blkmem, /**< block memory buffers */
15657  SCIP_SET* set, /**< global SCIP settings */
15658  SCIP_STAT* stat, /**< problem statistics */
15659  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15660  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15661  )
15662 {
15663  assert(lp != NULL);
15664  assert(lp->solved);
15665  assert(!lp->diving);
15667  assert(set != NULL);
15668 
15669  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15670  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15671 
15672  if( lp->firstnewcol < lp->ncols )
15673  {
15674  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15675  }
15676  if( lp->firstnewrow < lp->nrows )
15677  {
15678  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15679  }
15680 
15681  return SCIP_OKAY;
15682 }
15683 
15684 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15686  SCIP_LP* lp, /**< current LP data */
15687  BMS_BLKMEM* blkmem, /**< block memory buffers */
15688  SCIP_SET* set, /**< global SCIP settings */
15689  SCIP_STAT* stat, /**< problem statistics */
15690  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15691  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15692  )
15693 {
15694  assert(lp != NULL);
15695  assert(lp->solved);
15696  assert(!lp->diving);
15698  assert(set != NULL);
15699 
15700  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15701 
15702  if( 0 < lp->ncols )
15703  {
15704  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15705  }
15706  if( 0 < lp->nrows )
15707  {
15708  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15709  }
15710 
15711  return SCIP_OKAY;
15712 }
15713 
15714 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15715 static
15717  SCIP_LP* lp, /**< current LP data */
15718  SCIP_SET* set, /**< global SCIP settings */
15719  SCIP_STAT* stat, /**< problem statistics */
15720  int firstcol /**< first column to check for clean up */
15721  )
15722 {
15723  SCIP_COL** cols;
15724  SCIP_COL** lpicols;
15725  int* coldstat;
15726  int ncols;
15727  int ndelcols;
15728  int c;
15729 
15730  assert(lp != NULL);
15731  assert(lp->flushed);
15732  assert(lp->ncols == lp->nlpicols);
15733  assert(!lp->diving);
15734  assert(stat != NULL);
15735  assert(lp->validsollp == stat->lpcount);
15736  assert(0 <= firstcol && firstcol < lp->ncols);
15737 
15738  if( lp->nremovablecols == 0 || !lp->solisbasic )
15739  return SCIP_OKAY;
15740 
15741  ncols = lp->ncols;
15742  cols = lp->cols;
15743  lpicols = lp->lpicols;
15744 
15745  /* get temporary memory */
15746  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15747 
15748  /* mark unused columns to be deleted */
15749  ndelcols = 0;
15750  BMSclearMemoryArray(coldstat, ncols);
15751  for( c = firstcol; c < ncols; ++c )
15752  {
15753  assert(cols[c] == lpicols[c]);
15754  assert(cols[c]->lppos == c);
15755  assert(cols[c]->lpipos == c);
15756  if( lpicols[c]->removable
15757  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15758  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15759  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15760  {
15761  coldstat[c] = 1;
15762  ndelcols++;
15763  }
15764  }
15765 
15766  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15767 
15768  /* delete the marked columns in the LP solver interface, update the LP respectively */
15769  if( ndelcols > 0 )
15770  {
15771  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15772  }
15773  assert(lp->ncols == ncols - ndelcols);
15774 
15775  /* release temporary memory */
15776  SCIPsetFreeBufferArray(set, &coldstat);
15777 
15778  return SCIP_OKAY;
15779 }
15780 
15781 /** removes all basic rows beginning with the given firstrow */
15782 static
15784  SCIP_LP* lp, /**< current LP data */
15785  BMS_BLKMEM* blkmem, /**< block memory buffers */
15786  SCIP_SET* set, /**< global SCIP settings */
15787  SCIP_STAT* stat, /**< problem statistics */
15788  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15789  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15790  int firstrow /**< first row to check for clean up */
15791  )
15792 {
15793 #ifndef NDEBUG
15794  SCIP_ROW** rows;
15795 #endif
15796  SCIP_ROW** lpirows;
15797  int* rowdstat;
15798  int nrows;
15799  int ndelrows;
15800  int r;
15801 
15802  assert(lp != NULL);
15803  assert(lp->flushed);
15804  assert(lp->ncols == lp->nlpicols);
15805  assert(lp->nrows == lp->nlpirows);
15806  assert(!lp->diving);
15807  assert(stat != NULL);
15808  assert(lp->validsollp == stat->lpcount);
15809  assert(0 <= firstrow && firstrow < lp->nrows);
15810 
15811  if( lp->nremovablerows == 0 || !lp->solisbasic )
15812  return SCIP_OKAY;
15813 
15814 #ifndef NDEBUG
15815  rows = lp->rows;
15816 #endif
15817  nrows = lp->nrows;
15818  lpirows = lp->lpirows;
15819 
15820  /* get temporary memory */
15821  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15822 
15823  /* mark unused rows to be deleted */
15824  ndelrows = 0;
15825  BMSclearMemoryArray(rowdstat, nrows);
15826  for( r = firstrow; r < nrows; ++r )
15827  {
15828  assert(rows[r] == lpirows[r]);
15829  assert(rows[r]->lppos == r);
15830  assert(rows[r]->lpipos == r);
15831  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15832  {
15833  rowdstat[r] = 1;
15834  ndelrows++;
15835  }
15836  }
15837 
15838  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15839 
15840  /* delete the marked rows in the LP solver interface, update the LP respectively */
15841  if( ndelrows > 0 )
15842  {
15843  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15844  }
15845  assert(lp->nrows == nrows - ndelrows);
15846 
15847  /* release temporary memory */
15848  SCIPsetFreeBufferArray(set, &rowdstat);
15849 
15850  return SCIP_OKAY;
15851 }
15852 
15853 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15855  SCIP_LP* lp, /**< current LP data */
15856  BMS_BLKMEM* blkmem, /**< block memory buffers */
15857  SCIP_SET* set, /**< global SCIP settings */
15858  SCIP_STAT* stat, /**< problem statistics */
15859  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15860  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15861  SCIP_Bool root /**< are we at the root node? */
15862  )
15863 {
15864  SCIP_Bool cleanupcols;
15865  SCIP_Bool cleanuprows;
15866 
15867  assert(lp != NULL);
15868  assert(lp->solved);
15869  assert(!lp->diving);
15871  assert(set != NULL);
15872 
15873  /* check, if we want to clean up the columns and rows */
15874  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15875  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15876 
15877  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15878  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15879 
15880  if( cleanupcols && lp->firstnewcol < lp->ncols )
15881  {
15882  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15883  }
15884  if( cleanuprows && lp->firstnewrow < lp->nrows )
15885  {
15886  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15887  }
15888 
15889  return SCIP_OKAY;
15890 }
15891 
15892 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15894  SCIP_LP* lp, /**< current LP data */
15895  BMS_BLKMEM* blkmem, /**< block memory buffers */
15896  SCIP_SET* set, /**< global SCIP settings */
15897  SCIP_STAT* stat, /**< problem statistics */
15898  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15899  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15900  SCIP_Bool root /**< are we at the root node? */
15901  )
15902 {
15903  SCIP_Bool cleanupcols;
15904  SCIP_Bool cleanuprows;
15905 
15906  assert(lp != NULL);
15907  assert(lp->solved);
15908  assert(!lp->diving);
15910  assert(set != NULL);
15911 
15912  /* check, if we want to clean up the columns and rows */
15913  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15914  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15915 
15916  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15917  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15918 
15919  if( cleanupcols && 0 < lp->ncols )
15920  {
15921  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15922  }
15923  if( cleanuprows && 0 < lp->nrows )
15924  {
15925  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15926  }
15927 
15928  return SCIP_OKAY;
15929 }
15930 
15931 /** removes all redundant rows that were added at the current node */
15933  SCIP_LP* lp, /**< current LP data */
15934  BMS_BLKMEM* blkmem, /**< block memory buffers */
15935  SCIP_SET* set, /**< global SCIP settings */
15936  SCIP_STAT* stat, /**< problem statistics */
15937  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15938  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15939  )
15940 {
15941 #ifndef NDEBUG
15942  SCIP_ROW** rows;
15943 #endif
15944  SCIP_ROW** lpirows;
15945  int* rowdstat;
15946  int nrows;
15947  int ndelrows;
15948  int r;
15949 
15950  assert(lp != NULL);
15951  assert(lp->flushed);
15952  assert(lp->ncols == lp->nlpicols);
15953  assert(lp->nrows == lp->nlpirows);
15954  assert(!lp->diving);
15955  assert(stat != NULL);
15956  assert(lp->validsollp == stat->lpcount);
15957  assert(lp->firstnewrow <= lp->nrows);
15958 
15959  if( lp->firstnewrow == lp->nrows )
15960  return SCIP_OKAY;
15961 
15962 #ifndef NDEBUG
15963  rows = lp->rows;
15964 #endif
15965  nrows = lp->nrows;
15966  lpirows = lp->lpirows;
15967 
15968  /* get temporary memory */
15969  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15970 
15971  /* mark redundant rows to be deleted (only delete basic rows!) */
15972  ndelrows = 0;
15973  BMSclearMemoryArray(rowdstat, nrows);
15974  for( r = lp->firstnewrow; r < nrows; ++r )
15975  {
15976  assert(rows[r] == lpirows[r]);
15977  assert(rows[r]->lppos == r);
15978  assert(rows[r]->lpipos == r);
15979  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15980  && SCIProwIsRedundant(lpirows[r], set, stat) )
15981  {
15982  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15983  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15984  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15985  rowdstat[r] = 1;
15986  ndelrows++;
15987  }
15988  }
15989 
15990  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15991 
15992  /* delete the marked rows in the LP solver interface, update the LP respectively */
15993  if( ndelrows > 0 )
15994  {
15995  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15996  }
15997  assert(lp->nrows == nrows - ndelrows);
15998 
15999  /* release temporary memory */
16000  SCIPsetFreeBufferArray(set, &rowdstat);
16001 
16002  return SCIP_OKAY;
16003 }
16004 
16005 /** initiates LP diving */
16007  SCIP_LP* lp, /**< current LP data */
16008  BMS_BLKMEM* blkmem, /**< block memory */
16009  SCIP_SET* set, /**< global SCIP settings */
16010  SCIP_STAT* stat /**< problem statistics */
16011  )
16012 {
16013  int c;
16014  int r;
16015 
16016  assert(lp != NULL);
16017  assert(lp->flushed || !lp->solved);
16018  assert(!lp->diving);
16019  assert(!lp->probing);
16020  assert(lp->divelpistate == NULL);
16021  assert(lp->divelpwasprimfeas);
16022  assert(lp->divelpwasdualfeas);
16023  assert(lp->validsollp <= stat->lpcount);
16024  assert(blkmem != NULL);
16025  assert(set != NULL);
16026  assert(lp->ndivechgsides == 0);
16027 
16028  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
16029  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
16030 
16031 #ifndef NDEBUG
16032  for( c = 0; c < lp->ncols; ++c )
16033  {
16034  assert(lp->cols[c] != NULL);
16035  assert(lp->cols[c]->var != NULL);
16036  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16037  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16038  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16039  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16040  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16041  }
16042 #endif
16043 
16044  /* save current LPI state (basis information) */
16045  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
16047  lp->divelpwasdualfeas = lp->dualfeasible;
16050 
16051  /* save current LP values dependent on the solution */
16052  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
16053  assert(lp->storedsolvals != NULL);
16054  if( !set->lp_resolverestore && lp->solved )
16055  {
16056  SCIP_Bool store = TRUE;
16057 
16058  switch ( lp->lpsolstat )
16059  {
16061  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16062  assert(lp->validsollp == stat->lpcount);
16063  break;
16065  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
16066  assert(lp->validsollp == stat->lpcount);
16067  break;
16071  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16072  assert(lp->validsollp == stat->lpcount);
16073  break;
16075  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
16076  break;
16078  case SCIP_LPSOLSTAT_ERROR:
16079  default:
16080  store = FALSE;
16081  }
16082 
16083  if ( store )
16084  {
16085  for( c = 0; c < lp->ncols; ++c )
16086  {
16087  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
16088  }
16089  for( r = 0; r < lp->nrows; ++r )
16090  {
16092  }
16093  }
16094  }
16095 
16096  /* store LPI iteration limit */
16098 
16099  /* remember the number of domain changes */
16100  lp->divenolddomchgs = stat->domchgcount;
16101 
16102  /* store current number of rows */
16103  lp->ndivingrows = lp->nrows;
16104 
16105  /* switch to diving mode */
16106  lp->diving = TRUE;
16107 
16108  return SCIP_OKAY;
16109 }
16110 
16111 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
16113  SCIP_LP* lp, /**< current LP data */
16114  BMS_BLKMEM* blkmem, /**< block memory */
16115  SCIP_SET* set, /**< global SCIP settings */
16116  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16117  SCIP_STAT* stat, /**< problem statistics */
16118  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16119  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16120  SCIP_PROB* prob, /**< problem data */
16121  SCIP_VAR** vars, /**< array with all active variables */
16122  int nvars /**< number of active variables */
16123  )
16124 {
16125  SCIP_VAR* var;
16126  int v;
16127 
16128  assert(lp != NULL);
16129  assert(lp->diving);
16130  assert(blkmem != NULL);
16131  assert(nvars == 0 || vars != NULL);
16132 
16133  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16134 
16135  /* reset all columns' objective values and bounds to its original values */
16136  for( v = 0; v < nvars; ++v )
16137  {
16138  var = vars[v];
16139  assert(var != NULL);
16141  {
16142  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
16143  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
16144  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
16145  }
16146  }
16147 
16148  /* remove rows which were added in diving mode */
16149  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16150 
16151  /* undo changes to left hand sides and right hand sides */
16152  while( lp->ndivechgsides > 0 )
16153  {
16154  SCIP_Real oldside;
16155  SCIP_SIDETYPE sidetype;
16156  SCIP_ROW* row;
16157 
16158  lp->ndivechgsides--;
16159  oldside = lp->divechgsides[lp->ndivechgsides];
16160  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16161  row = lp->divechgrows[lp->ndivechgsides];
16162 
16163  if( sidetype == SCIP_SIDETYPE_LEFT )
16164  {
16165  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16166  }
16167  else
16168  {
16169  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16170  }
16171  }
16172 
16173  /* restore LPI iteration limit */
16175 
16176  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16177  * happens
16178  */
16179  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lp->divelpistate,
16181  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16182  lp->divelpwasprimfeas = TRUE;
16183  lp->divelpwasdualfeas = TRUE;
16184  lp->divelpwasprimchecked = TRUE;
16185  lp->divelpwasdualchecked = TRUE;
16186  assert(lp->divelpistate == NULL);
16187 
16188  /* switch to standard (non-diving) mode */
16189  lp->diving = FALSE;
16190  lp->divingobjchg = FALSE;
16191 
16192  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16193  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16194  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16195  * the parameter resolverestore to TRUE
16196  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16197  */
16198  assert(lp->storedsolvals != NULL);
16199  if( lp->storedsolvals->lpissolved
16200  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16201  {
16202  SCIP_Bool lperror;
16203 
16204  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
16205  if( lperror )
16206  {
16207  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16208  lp->resolvelperror = TRUE;
16209  }
16214  {
16215  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16216  "LP was not resolved to a sufficient status after diving\n");
16217  lp->resolvelperror = TRUE;
16218  }
16219  }
16220  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16221  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16222  * re-solve as above can lead to a different LP status
16223  */
16224  else
16225  {
16226  int c;
16227  int r;
16228 
16229  /* if there are lazy bounds, remove them from the LP */
16230  if( lp->nlazycols > 0 )
16231  {
16232  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16233  * first resolve LP?
16234  */
16235  SCIP_CALL( updateLazyBounds(lp, set) );
16236  assert(lp->diving == lp->divinglazyapplied);
16237 
16238  /* flush changes to the LP solver */
16239  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
16240  }
16241 
16242  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
16243  SCIPstatIncrement(stat, set, lpcount);
16244 
16245  /* restore LP solution values in lp data, columns and rows */
16246  if( lp->storedsolvals->lpissolved &&
16253  )
16254  {
16255  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16256 
16257  for( c = 0; c < lp->ncols; ++c )
16258  {
16259  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16260  }
16261  for( r = 0; r < lp->nrows; ++r )
16262  {
16263  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16264  }
16265  }
16266  else
16267  {
16268  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16269  }
16270  }
16271 
16272 #ifndef NDEBUG
16273  {
16274  int c;
16275  for( c = 0; c < lp->ncols; ++c )
16276  {
16277  assert(lp->cols[c] != NULL);
16278  assert(lp->cols[c]->var != NULL);
16279  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16280  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16281  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16282  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16283  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16284  }
16285  }
16286 #endif
16287 
16288  return SCIP_OKAY;
16289 }
16290 
16291 #define DIVESTACKGROWFACT 1.5
16292 
16293 /** records a current row side such that any change will be undone after diving */
16295  SCIP_LP* lp, /**< LP data object */
16296  SCIP_ROW* row, /**< row affected by the change */
16297  SCIP_SIDETYPE sidetype /**< side type */
16298  )
16299 {
16300  assert(lp != NULL);
16301  assert(row != NULL);
16302 
16303  if( lp->ndivechgsides == lp->divechgsidessize )
16304  {
16306  }
16307  assert(lp->ndivechgsides < lp->divechgsidessize);
16308 
16309  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16310  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16311  lp->divechgrows[lp->ndivechgsides] = row;
16312  lp->ndivechgsides++;
16313 
16314  return SCIP_OKAY;
16315 }
16316 
16317 /** informs the LP that probing mode was initiated */
16319  SCIP_LP* lp /**< current LP data */
16320  )
16321 {
16322  assert(lp != NULL);
16323  assert(!lp->probing);
16324  assert(!lp->strongbranching);
16325  assert(!lp->strongbranchprobing);
16326 
16327  lp->probing = TRUE;
16328 
16329  return SCIP_OKAY;
16330 }
16331 
16332 /** informs the LP that probing mode was finished */
16334  SCIP_LP* lp /**< current LP data */
16335  )
16336 {
16337  assert(lp != NULL);
16338  assert(lp->probing);
16339  assert(!lp->strongbranching);
16340  assert(!lp->strongbranchprobing);
16341 
16342  lp->probing = FALSE;
16343 
16344  return SCIP_OKAY;
16345 }
16346 
16347 /** informs the LP that the probing mode is now used for strongbranching */
16349  SCIP_LP* lp /**< current LP data */
16350  )
16351 {
16352  assert(lp != NULL);
16353  assert(lp->probing);
16354  assert(!lp->strongbranching);
16355  assert(!lp->strongbranchprobing);
16356 
16357  lp->strongbranchprobing = TRUE;
16358 }
16359 
16360 /** informs the LP that the probing mode is not used for strongbranching anymore */
16362  SCIP_LP* lp /**< current LP data */
16363  )
16364 {
16365  assert(lp != NULL);
16366  assert(lp->probing);
16367  assert(!lp->strongbranching);
16368  assert(lp->strongbranchprobing);
16369 
16370  lp->strongbranchprobing = FALSE;
16371 }
16372 
16373 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16374  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16375  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16376  * we have only left hand sides):
16377  * min{cx | b <= Ax, lb <= x <= ub}
16378  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16379  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16380  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16381  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16382  */
16383 static
16385  SCIP_LP* lp, /**< current LP data */
16386  SCIP_SET* set, /**< global SCIP settings */
16387  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16388  SCIP_Real* bound /**< result of interval arithmetic minimization */
16389  )
16390 {
16391  SCIP_INTERVAL* yinter;
16392  SCIP_INTERVAL b;
16393  SCIP_INTERVAL ytb;
16394  SCIP_INTERVAL prod;
16395  SCIP_INTERVAL diff;
16396  SCIP_INTERVAL x;
16397  SCIP_INTERVAL minprod;
16398  SCIP_INTERVAL a;
16399  SCIP_ROW* row;
16400  SCIP_COL* col;
16401  SCIP_Real y;
16402  SCIP_Real c;
16403  int i;
16404  int j;
16405 
16406  assert(lp != NULL);
16407  assert(lp->solved);
16408  assert(set != NULL);
16409  assert(bound != NULL);
16410 
16411  /* allocate buffer for storing y in interval arithmetic */
16412  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16413 
16414  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16415  SCIPintervalSet(&ytb, 0.0);
16416  for( j = 0; j < lp->nrows; ++j )
16417  {
16418  row = lp->rows[j];
16419  assert(row != NULL);
16420 
16421  y = (usefarkas ? row->dualfarkas : row->dualsol);
16422 
16423  if( SCIPsetIsFeasPositive(set, y) )
16424  {
16425  SCIPintervalSet(&yinter[j], y);
16426  SCIPintervalSet(&b, row->lhs - row->constant);
16427  }
16428  else if( SCIPsetIsFeasNegative(set, y) )
16429  {
16430  SCIPintervalSet(&yinter[j], y);
16431  SCIPintervalSet(&b, row->rhs - row->constant);
16432  }
16433  else
16434  {
16435  SCIPintervalSet(&yinter[j], 0.0);
16436  SCIPintervalSet(&b, 0.0);
16437  }
16438 
16439  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16440  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16441  }
16442 
16443  /* calculate min{(c^T - y^TA)x} */
16444  SCIPintervalSet(&minprod, 0.0);
16445  for( j = 0; j < lp->ncols; ++j )
16446  {
16447  col = lp->cols[j];
16448  assert(col != NULL);
16449  assert(col->nunlinked == 0);
16450 
16452 
16453  c = usefarkas ? 0.0 : col->obj;
16454  SCIPintervalSet(&diff, c);
16455 
16456  for( i = 0; i < col->nlprows; ++i )
16457  {
16458  assert(col->rows[i] != NULL);
16459  assert(col->rows[i]->lppos >= 0);
16460  assert(col->linkpos[i] >= 0);
16461  SCIPintervalSet(&a, col->vals[i]);
16462  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16463  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16464  }
16465 
16466 #ifndef NDEBUG
16467  for( i = col->nlprows; i < col->len; ++i )
16468  {
16469  assert(col->rows[i] != NULL);
16470  assert(col->rows[i]->lppos == -1);
16471  assert(col->rows[i]->dualsol == 0.0);
16472  assert(col->rows[i]->dualfarkas == 0.0);
16473  assert(col->linkpos[i] >= 0);
16474  }
16475 #endif
16476 
16477  SCIPintervalSetBounds(&x, col->lb, col->ub);
16478  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16479  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16480  }
16481 
16482  /* add y^Tb */
16483  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16484 
16485  /* free buffer for storing y in interval arithmetic */
16486  SCIPsetFreeBufferArray(set, &yinter);
16487 
16488  *bound = SCIPintervalGetInf(minprod);
16489 
16490  return SCIP_OKAY;
16491 }
16492 
16493 /** gets proven lower (dual) bound of last LP solution */
16495  SCIP_LP* lp, /**< current LP data */
16496  SCIP_SET* set, /**< global SCIP settings */
16497  SCIP_Real* bound /**< pointer to store proven dual bound */
16498  )
16499 {
16500  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16501 
16502  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16503 
16504  return SCIP_OKAY;
16505 }
16506 
16507 /** gets proven dual bound of last LP solution */
16509  SCIP_LP* lp, /**< current LP data */
16510  SCIP_SET* set, /**< global SCIP settings */
16511  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16512  )
16513 {
16514  SCIP_Real bound;
16515 
16516  assert(proved != NULL);
16517 
16518  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16519 
16520  *proved = (bound > 0.0);
16521 
16522  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16523 
16524  return SCIP_OKAY;
16525 }
16526 
16527 
16528 
16529 /** writes LP to a file */
16531  SCIP_LP* lp, /**< current LP data */
16532  const char* fname /**< file name */
16533  )
16534 {
16535  assert(lp != NULL);
16536  assert(lp->flushed);
16537  assert(fname != NULL);
16538 
16539  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16540 
16541  return SCIP_OKAY;
16542 }
16543 
16544 /** writes MIP relaxation of the current B&B node to a file */
16546  SCIP_LP* lp, /**< current LP data */
16547  SCIP_SET* set, /**< global SCIP settings */
16548  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16549  const char* fname, /**< file name */
16550  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16551  * troubles with reserved symbols? */
16552  SCIP_Bool origobj, /**< should the original objective function be used? */
16553  SCIP_OBJSENSE objsense, /**< objective sense */
16554  SCIP_Real objscale, /**< objective scaling factor */
16555  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16556  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16557  )
16558 {
16559  FILE* file;
16560  int i;
16561  int j;
16562  char rowname[SCIP_MAXSTRLEN];
16563  SCIP_Real coeff;
16564 
16565  assert(lp != NULL);
16566  assert(lp->flushed);
16567  assert(fname != NULL);
16568 
16569  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16570  file = fopen(fname, "w");
16571  if( file == NULL )
16572  {
16573  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16574  SCIPprintSysError(fname);
16575  return SCIP_FILECREATEERROR;
16576  }
16577 
16578  /* print comments */
16579  if( genericnames )
16580  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16581  else
16582  {
16583  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16584  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16585  }
16586 
16587  if( origobj && objoffset != 0.0 )
16588  {
16589  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16590  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16591  }
16592 
16593  /* print objective function */
16594  /**@note the transformed problem in SCIP is always a minimization problem */
16595  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16596  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16597  else
16598  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16599 
16600  /* print objective */
16601  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16602  j = 0;
16603  for( i = 0; i < lp->ncols; ++i )
16604  {
16605  if( lp->cols[i]->obj != 0.0 )
16606  {
16607  coeff = lp->cols[i]->obj;
16608  if( origobj )
16609  {
16610  coeff *= (SCIP_Real) objsense;
16611  coeff *= objscale;
16612  }
16613 
16614  if( genericnames )
16615  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16616  else
16617  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16618 
16619  ++j;
16620  if( j % 10 == 0 )
16621  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16622  }
16623  }
16624  /* add artificial variable 'objoffset' to transfer objective offset */
16625  if( origobj && objoffset != 0.0 )
16626  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16627 
16628  /* print constraint section */
16629  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16630  for( i = 0; i < lp->nrows; i++ )
16631  {
16632  char type = 'i';
16633 
16634  /* skip removable rows if we want to write them as lazy constraints */
16635  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16636  continue;
16637 
16638  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16639  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16640  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16641  * type 'i' means: lhs and rhs are both infinite */
16642  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16643  type = 'r';
16644  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16645  type = 'l';
16646  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16647  type = 'e';
16648  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16649  type = 'b';
16650 
16651  /* print name of row */
16652  if( genericnames )
16653  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16654  else
16655  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16656 
16657  WRITEROW:
16658  switch( type )
16659  {
16660  case 'r':
16661  case 'l':
16662  case 'e':
16663  if( strlen(rowname) > 0 )
16664  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16665  break;
16666  case 'i':
16667  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16668  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16669  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16670  type = 'b';
16671  /*lint -fallthrough*/
16672  case 'b':
16673  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16674  break;
16675  default:
16676  assert(type == 'B');
16677  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16678  break;
16679  }
16680 
16681  /* print coefficients and variables */
16682  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16683  {
16684  if( genericnames )
16685  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16686  else
16687  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16688 
16689  if( (j+1) % 10 == 0 )
16690  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16691  }
16692 
16693  /* print right hand side */
16694  switch( type )
16695  {
16696  case 'b':
16697  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16698  type = 'B';
16699  goto WRITEROW;
16700  case 'l':
16701  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16702  break;
16703  case 'B':
16704  case 'r':
16705  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16706  break;
16707  case 'e':
16708  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16709  break;
16710  default:
16711  SCIPerrorMessage("Undefined row type!\n");
16712  fclose(file);
16713  return SCIP_ERROR;
16714  }
16715  }
16716 
16717  if ( lazyconss )
16718  {
16719  /* print lazy constraint section */
16720  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16721  for( i = 0; i < lp->nrows; i++ )
16722  {
16723  char type = 'i';
16724 
16725  /* skip non-removable rows if we want to write lazy constraints */
16726  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16727  continue;
16728 
16729  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16730  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16731  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16732  * type 'i' means: lhs and rhs are both infinite */
16733  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16734  type = 'r';
16735  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16736  type = 'l';
16737  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16738  type = 'e';
16739  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16740  type = 'b';
16741 
16742  /* print name of row */
16743  if( genericnames )
16744  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16745  else
16746  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16747 
16748  WRITELAZYROW:
16749  switch( type )
16750  {
16751  case 'r':
16752  case 'l':
16753  case 'e':
16754  if( strlen(rowname) > 0 )
16755  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16756  break;
16757  case 'i':
16758  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16759  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16760  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16761  type = 'b';
16762  /*lint -fallthrough*/
16763  case 'b':
16764  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16765  break;
16766  default:
16767  assert(type == 'B');
16768  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16769  break;
16770  }
16771 
16772  /* print coefficients and variables */
16773  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16774  {
16775  if( genericnames )
16776  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16777  else
16778  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16779 
16780  if( (j+1) % 10 == 0 )
16781  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16782  }
16783 
16784  /* print right hand side */
16785  switch( type )
16786  {
16787  case 'b':
16788  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16789  type = 'B';
16790  goto WRITELAZYROW;
16791  case 'l':
16792  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16793  break;
16794  case 'B':
16795  case 'r':
16796  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16797  break;
16798  case 'e':
16799  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16800  break;
16801  default:
16802  SCIPerrorMessage("Undefined row type!\n");
16803  fclose(file);
16804  return SCIP_ERROR;
16805  }
16806  }
16807  }
16808 
16809  /* print variable bounds */
16810  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16811  for( i = 0; i < lp->ncols; ++i )
16812  {
16813  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16814  {
16815  /* print lower bound as far this one is not infinity */
16816  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16817  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16818 
16819  /* print variable name */
16820  if( genericnames )
16821  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16822  else
16823  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16824 
16825  /* print upper bound as far this one is not infinity */
16826  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16827  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16828  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16829  }
16830  }
16831  if( origobj && objoffset != 0.0 )
16832  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16833 
16834  /* print integer variables */
16835  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16836  j = 0;
16837  for( i = 0; i < lp->ncols; ++i )
16838  {
16839  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16840  {
16841  /* print variable name */
16842  if( genericnames )
16843  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16844  else
16845  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16846 
16847  j++;
16848  if( j % 10 == 0 )
16849  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16850  }
16851  }
16852 
16853  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16854  fclose(file);
16855 
16856  return SCIP_OKAY;
16857 }
16858 
16859 /*
16860  * simple functions implemented as defines
16861  */
16862 
16863 /* In debug mode, the following methods are implemented as function calls to ensure
16864  * type validity.
16865  * In optimized mode, the methods are implemented as defines to improve performance.
16866  * However, we want to have them in the library anyways, so we have to undef the defines.
16867  */
16868 
16869 #undef SCIPcolGetObj
16870 #undef SCIPcolGetLb
16871 #undef SCIPcolGetUb
16872 #undef SCIPcolGetBestBound
16873 #undef SCIPcolGetPrimsol
16874 #undef SCIPcolGetMinPrimsol
16875 #undef SCIPcolGetMaxPrimsol
16876 #undef SCIPcolGetBasisStatus
16877 #undef SCIPcolGetVar
16878 #undef SCIPcolGetIndex
16879 #undef SCIPcolGetVarProbindex
16880 #undef SCIPcolIsIntegral
16881 #undef SCIPcolIsRemovable
16882 #undef SCIPcolGetLPPos
16883 #undef SCIPcolGetLPDepth
16884 #undef SCIPcolIsInLP
16885 #undef SCIPcolGetNNonz
16886 #undef SCIPcolGetNLPNonz
16887 #undef SCIPcolGetRows
16888 #undef SCIPcolGetVals
16889 #undef SCIPcolGetStrongbranchNode
16890 #undef SCIPcolGetNStrongbranchs
16891 #undef SCIPcolGetAge
16892 #undef SCIPboundtypeOpposite
16893 #undef SCIProwGetNNonz
16894 #undef SCIProwGetNLPNonz
16895 #undef SCIProwGetCols
16896 #undef SCIProwGetVals
16897 #undef SCIProwGetConstant
16898 #undef SCIProwGetNorm
16899 #undef SCIProwGetSumNorm
16900 #undef SCIProwGetLhs
16901 #undef SCIProwGetRhs
16902 #undef SCIProwGetDualsol
16903 #undef SCIProwGetDualfarkas
16904 #undef SCIProwGetBasisStatus
16905 #undef SCIProwGetName
16906 #undef SCIProwGetIndex
16907 #undef SCIProwGetAge
16908 #undef SCIProwGetRank
16909 #undef SCIProwIsIntegral
16910 #undef SCIProwIsLocal
16911 #undef SCIProwIsModifiable
16912 #undef SCIProwIsRemovable
16913 #undef SCIProwGetOrigintype
16914 #undef SCIProwGetOriginCons
16915 #undef SCIProwGetOriginConshdlr
16916 #undef SCIProwGetOriginSepa
16917 #undef SCIProwIsInGlobalCutpool
16918 #undef SCIProwGetLPPos
16919 #undef SCIProwGetLPDepth
16920 #undef SCIProwIsInLP
16921 #undef SCIProwGetActiveLPCount
16922 #undef SCIProwGetNLPsAfterCreation
16923 #undef SCIProwChgRank
16924 #undef SCIPlpGetCols
16925 #undef SCIPlpGetNCols
16926 #undef SCIPlpGetRows
16927 #undef SCIPlpGetNRows
16928 #undef SCIPlpGetNewcols
16929 #undef SCIPlpGetNNewcols
16930 #undef SCIPlpGetNewrows
16931 #undef SCIPlpGetNNewrows
16932 #undef SCIPlpGetObjNorm
16933 #undef SCIPlpGetRootObjval
16934 #undef SCIPlpGetRootColumnObjval
16935 #undef SCIPlpGetRootLooseObjval
16936 #undef SCIPlpGetLPI
16937 #undef SCIPlpSetIsRelax
16938 #undef SCIPlpIsRelax
16939 #undef SCIPlpIsSolved
16940 #undef SCIPlpIsSolBasic
16941 #undef SCIPlpDiving
16942 #undef SCIPlpDivingObjChanged
16943 #undef SCIPlpMarkDivingObjChanged
16944 #undef SCIPlpUnmarkDivingObjChanged
16945 #undef SCIPlpDivingRowsChanged
16946 #undef SCIPlpIsFeasEQ
16947 #undef SCIPlpIsFeasLT
16948 #undef SCIPlpIsFeasLE
16949 #undef SCIPlpIsFeasGT
16950 #undef SCIPlpIsFeasGE
16951 #undef SCIPlpIsFeasZero
16952 #undef SCIPlpIsFeasPositive
16953 #undef SCIPlpIsFeasNegative
16954 
16955 /** gets objective value of column */
16957  SCIP_COL* col /**< LP column */
16958  )
16959 {
16960  assert(col != NULL);
16961 
16962  return col->obj;
16963 }
16964 
16965 /** gets lower bound of column */
16967  SCIP_COL* col /**< LP column */
16968  )
16969 {
16970  assert(col != NULL);
16971 
16972  return col->lb;
16973 }
16974 
16975 /** gets upper bound of column */
16977  SCIP_COL* col /**< LP column */
16978  )
16979 {
16980  assert(col != NULL);
16981 
16982  return col->ub;
16983 }
16984 
16985 /** gets best bound of column with respect to the objective function */
16987  SCIP_COL* col /**< LP column */
16988  )
16989 {
16990  assert(col != NULL);
16991 
16992  if( col->obj >= 0.0 )
16993  return col->lb;
16994  else
16995  return col->ub;
16996 }
16997 
16998 /** gets the primal LP solution of a column */
17000  SCIP_COL* col /**< LP column */
17001  )
17002 {
17003  assert(col != NULL);
17004 
17005  if( col->lppos >= 0 )
17006  return col->primsol;
17007  else
17008  return 0.0;
17009 }
17010 
17011 /** gets the minimal LP solution value, this column ever assumed */
17013  SCIP_COL* col /**< LP column */
17014  )
17015 {
17016  assert(col != NULL);
17017 
17018  return col->minprimsol;
17019 }
17020 
17021 /** gets the maximal LP solution value, this column ever assumed */
17023  SCIP_COL* col /**< LP column */
17024  )
17025 {
17026  assert(col != NULL);
17027 
17028  return col->maxprimsol;
17029 }
17030 
17031 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17032  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
17033  */
17035  SCIP_COL* col /**< LP column */
17036  )
17037 {
17038  assert(col != NULL);
17039  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
17040 
17041  return (SCIP_BASESTAT)col->basisstatus;
17042 }
17043 
17044 /** gets variable this column represents */
17046  SCIP_COL* col /**< LP column */
17047  )
17048 {
17049  assert(col != NULL);
17050 
17051  return col->var;
17052 }
17053 
17054 /** gets unique index of col */
17056  SCIP_COL* col /**< LP col */
17057  )
17058 {
17059  assert(col != NULL);
17060 
17061  return col->index;
17062 }
17063 
17064 /** gets probindex of corresponding variable */
17066  SCIP_COL* col /**< LP col */
17067  )
17068 {
17069  assert(col != NULL);
17070 
17071  return col->var_probindex;
17072 }
17073 
17074 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
17076  SCIP_COL* col /**< LP column */
17077  )
17078 {
17079  assert(col != NULL);
17080  assert(SCIPvarIsIntegral(col->var) == col->integral);
17081 
17082  return col->integral;
17083 }
17084 
17085 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
17087  SCIP_COL* col /**< LP column */
17088  )
17089 {
17090  assert(col != NULL);
17091 
17092  return col->removable;
17093 }
17094 
17095 /** gets position of column in current LP, or -1 if it is not in LP */
17097  SCIP_COL* col /**< LP column */
17098  )
17099 {
17100  assert(col != NULL);
17101  assert((col->lppos == -1) == (col->lpdepth == -1));
17102 
17103  return col->lppos;
17104 }
17105 
17106 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
17108  SCIP_COL* col /**< LP column */
17109  )
17110 {
17111  assert(col != NULL);
17112  assert((col->lppos == -1) == (col->lpdepth == -1));
17113 
17114  return col->lpdepth;
17115 }
17116 
17117 /** returns TRUE iff column is member of current LP */
17119  SCIP_COL* col /**< LP column */
17120  )
17121 {
17122  assert(col != NULL);
17123  assert((col->lppos == -1) == (col->lpdepth == -1));
17124 
17125  return (col->lppos >= 0);
17126 }
17127 
17128 /** get number of nonzero entries in column vector */
17130  SCIP_COL* col /**< LP column */
17131  )
17132 {
17133  assert(col != NULL);
17134 
17135  return col->len;
17136 }
17137 
17138 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
17139  *
17140  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17141  * 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
17142  */
17144  SCIP_COL* col /**< LP column */
17145  )
17146 {
17147  assert(col != NULL);
17148  assert(col->nunlinked == 0);
17149 
17150  return col->nlprows;
17151 }
17152 
17153 /** gets array with rows of nonzero entries */
17155  SCIP_COL* col /**< LP column */
17156  )
17157 {
17158  assert(col != NULL);
17159 
17160  return col->rows;
17161 }
17162 
17163 /** gets array with coefficients of nonzero entries */
17165  SCIP_COL* col /**< LP column */
17166  )
17167 {
17168  assert(col != NULL);
17169 
17170  return col->vals;
17171 }
17172 
17173 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
17174  * given column, or -1 if strong branching was never applied to the column in current run
17175  */
17177  SCIP_COL* col /**< LP column */
17178  )
17179 {
17180  assert(col != NULL);
17181 
17182  return col->sbnode;
17183 }
17184 
17185 /** gets number of times, strong branching was applied in current run on the given column */
17187  SCIP_COL* col /**< LP column */
17188  )
17189 {
17190  assert(col != NULL);
17191 
17192  return col->nsbcalls;
17193 }
17194 
17195 /** gets the age of a column, i.e., the total number of successive times a column was in the LP and was 0.0 in the solution */
17197  SCIP_COL* col /**< LP column */
17198  )
17199 {
17200  assert(col != NULL);
17201 
17202  return col->age;
17203 }
17204 
17205 /** gets opposite bound type of given bound type */
17207  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17208  )
17209 {
17210  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17211 
17213 }
17214 
17215 /** get number of nonzero entries in row vector */
17217  SCIP_ROW* row /**< LP row */
17218  )
17219 {
17220  assert(row != NULL);
17221 
17222  return row->len;
17223 }
17224 
17225 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17226  *
17227  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17228  * 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
17229  */
17231  SCIP_ROW* row /**< LP row */
17232  )
17233 {
17234  assert(row != NULL);
17235  assert(row->nunlinked == 0);
17236 
17237  return row->nlpcols;
17238 }
17239 
17240 /** gets array with columns of nonzero entries */
17242  SCIP_ROW* row /**< LP row */
17243  )
17244 {
17245  assert(row != NULL);
17246 
17247  return row->cols;
17248 }
17249 
17250 /** gets array with coefficients of nonzero entries */
17252  SCIP_ROW* row /**< LP row */
17253  )
17254 {
17255  assert(row != NULL);
17256 
17257  return row->vals;
17258 }
17259 
17260 /** gets constant shift of row */
17262  SCIP_ROW* row /**< LP row */
17263  )
17264 {
17265  assert(row != NULL);
17266 
17267  return row->constant;
17268 }
17269 
17270 /** gets Euclidean norm of row vector */
17272  SCIP_ROW* row /**< LP row */
17273  )
17274 {
17275  assert(row != NULL);
17276 
17277  checkRowSqrnorm(row);
17278 
17279  return sqrt(row->sqrnorm);
17280 }
17281 
17282 /** gets sum norm of row vector (sum of absolute values of coefficients) */
17284  SCIP_ROW* row /**< LP row */
17285  )
17286 {
17287  assert(row != NULL);
17288 
17289  checkRowSumnorm(row);
17290 
17291  return row->sumnorm;
17292 }
17293 
17294 /** returns the left hand side of the row */
17296  SCIP_ROW* row /**< LP row */
17297  )
17298 {
17299  assert(row != NULL);
17300 
17301  return row->lhs;
17302 }
17303 
17304 /** returns the right hand side of the row */
17306  SCIP_ROW* row /**< LP row */
17307  )
17308 {
17309  assert(row != NULL);
17310 
17311  return row->rhs;
17312 }
17313 
17314 /** gets the dual LP solution of a row */
17316  SCIP_ROW* row /**< LP row */
17317  )
17318 {
17319  assert(row != NULL);
17320 
17321  if( row->lppos >= 0 )
17322  return row->dualsol;
17323  else
17324  return 0.0;
17325 }
17326 
17327 /** gets the dual Farkas coefficient of a row in an infeasible LP */
17329  SCIP_ROW* row /**< LP row */
17330  )
17331 {
17332  assert(row != NULL);
17333 
17334  if( row->lppos >= 0 )
17335  return row->dualfarkas;
17336  else
17337  return 0.0;
17338 }
17339 
17340 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17341  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17342  */
17344  SCIP_ROW* row /**< LP row */
17345  )
17346 {
17347  assert(row != NULL);
17348  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17349 
17350  return (SCIP_BASESTAT)row->basisstatus;
17351 }
17352 
17353 /** returns the name of the row */
17354 const char* SCIProwGetName(
17355  SCIP_ROW* row /**< LP row */
17356  )
17357 {
17358  assert(row != NULL);
17359 
17360  return row->name;
17361 }
17362 
17363 /** gets unique index of row */
17365  SCIP_ROW* row /**< LP row */
17366  )
17367 {
17368  assert(row != NULL);
17369 
17370  return row->index;
17371 }
17372 
17373 /** gets age of row */
17375  SCIP_ROW* row /**< LP row */
17376  )
17377 {
17378  assert(row != NULL);
17379 
17380  return row->age;
17381 }
17382 
17383 /** gets rank of row */
17385  SCIP_ROW* row /**< LP row */
17386  )
17387 {
17388  assert(row != NULL);
17389 
17390  return row->rank;
17391 }
17392 
17393 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17395  SCIP_ROW* row /**< LP row */
17396  )
17397 {
17398  assert(row != NULL);
17399 
17400  return row->integral;
17401 }
17402 
17403 /** returns TRUE iff row is only valid locally */
17405  SCIP_ROW* row /**< LP row */
17406  )
17407 {
17408  assert(row != NULL);
17409 
17410  return row->local;
17411 }
17412 
17413 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17415  SCIP_ROW* row /**< LP row */
17416  )
17417 {
17418  assert(row != NULL);
17419 
17420  return row->modifiable;
17421 }
17422 
17423 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17425  SCIP_ROW* row /**< LP row */
17426  )
17427 {
17428  assert(row != NULL);
17429 
17430  return row->removable;
17431 }
17432 
17433 /** returns type of origin that created the row */
17435  SCIP_ROW* row /**< LP row */
17436  )
17437 {
17438  assert( row != NULL );
17439 
17440  return (SCIP_ROWORIGINTYPE) row->origintype;
17441 }
17442 
17443 /** returns origin constraint that created the row (NULL if not available) */
17445  SCIP_ROW* row /**< LP row */
17446  )
17447 {
17448  assert( row != NULL );
17449 
17451  {
17452  assert( row->origin != NULL );
17453  return (SCIP_CONS*) row->origin;
17454  }
17455  return NULL;
17456 }
17457 
17458 /** returns origin constraint handler that created the row (NULL if not available) */
17460  SCIP_ROW* row /**< LP row */
17461  )
17462 {
17463  assert( row != NULL );
17464 
17466  {
17467  assert( row->origin != NULL );
17468  return (SCIP_CONSHDLR*) row->origin;
17469  }
17471  {
17472  assert(row->origin != NULL);
17473  return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17474  }
17475  return NULL;
17476 }
17477 
17478 /** returns origin separator that created the row (NULL if not available) */
17480  SCIP_ROW* row /**< LP row */
17481  )
17482 {
17483  assert( row != NULL );
17484 
17486  {
17487  assert( row->origin != NULL );
17488  return (SCIP_SEPA*) row->origin;
17489  }
17490  return NULL;
17491 }
17492 
17493 /** returns TRUE iff row is member of the global cut pool */
17495  SCIP_ROW* row /**< LP row */
17496  )
17497 {
17498  assert(row != NULL);
17499 
17500  return row->inglobalcutpool;
17501 }
17502 
17503 /** gets position of row in current LP, or -1 if it is not in LP */
17505  SCIP_ROW* row /**< LP row */
17506  )
17507 {
17508  assert(row != NULL);
17509  assert((row->lppos == -1) == (row->lpdepth == -1));
17510 
17511  return row->lppos;
17512 }
17513 
17514 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17516  SCIP_ROW* row /**< LP row */
17517  )
17518 {
17519  assert(row != NULL);
17520  assert((row->lppos == -1) == (row->lpdepth == -1));
17521 
17522  return row->lpdepth;
17523 }
17524 
17525 /** returns TRUE iff row is member of current LP */
17527  SCIP_ROW* row /**< LP row */
17528  )
17529 {
17530  assert(row != NULL);
17531  assert((row->lppos == -1) == (row->lpdepth == -1));
17532 
17533  return (row->lppos >= 0);
17534 }
17535 
17536 /** changes the rank of LP row */
17538  SCIP_ROW* row, /**< LP row */
17539  int rank /**< new value for rank */
17540  )
17541 {
17542  assert(row != NULL);
17543 
17544  row->rank = rank;
17545 }
17546 
17547 /** returns the number of times that this row has been sharp in an optimal LP solution */
17549  SCIP_ROW* row /**< row */
17550  )
17551 {
17552  assert(row != NULL);
17553 
17554  return row->activeinlpcounter;
17555 }
17556 
17557 /** returns the number of LPs since this row has been created */
17559  SCIP_ROW* row /**< row */
17560  )
17561 {
17562  assert(row != NULL);
17563 
17564  return row->nlpsaftercreation;
17565 }
17566 
17567 /** gets array with columns of the LP */
17569  SCIP_LP* lp /**< current LP data */
17570  )
17571 {
17572  assert(lp != NULL);
17573 
17574  return lp->cols;
17575 }
17576 
17577 /** gets current number of columns in LP */
17579  SCIP_LP* lp /**< current LP data */
17580  )
17581 {
17582  assert(lp != NULL);
17583 
17584  return lp->ncols;
17585 }
17586 
17587 /** gets current number of unfixed columns in LP */
17589  SCIP_LP* lp, /**< current LP data */
17590  SCIP_Real eps /**< numerical tolerance */
17591  )
17592 {
17593  SCIP_COL** lpcols;
17594  int nlpcols;
17595  int nunfixedcols;
17596  int c;
17597 
17598  assert(lp != NULL);
17599  assert(eps > 0.0);
17600 
17601  lpcols = lp->cols;
17602  nlpcols = lp->ncols;
17603 
17604  nunfixedcols = 0;
17605  for( c = 0; c < nlpcols; ++c )
17606  {
17607  if( lpcols[c]->ub - lpcols[c]->lb > eps )
17608  ++nunfixedcols;
17609  }
17610 
17611  return nunfixedcols;
17612 }
17613 
17614 /** gets array with rows of the LP */
17616  SCIP_LP* lp /**< current LP data */
17617  )
17618 {
17619  assert(lp != NULL);
17620 
17621  return lp->rows;
17622 }
17623 
17624 /** gets current number of rows in LP */
17626  SCIP_LP* lp /**< current LP data */
17627  )
17628 {
17629  assert(lp != NULL);
17630 
17631  return lp->nrows;
17632 }
17633 
17634 /** gets array with newly added columns after the last mark */
17636  SCIP_LP* lp /**< current LP data */
17637  )
17638 {
17639  assert(lp != NULL);
17640  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17641 
17642  return &(lp->cols[lp->firstnewcol]);
17643 }
17644 
17645 /** gets number of newly added columns after the last mark */
17647  SCIP_LP* lp /**< current LP data */
17648  )
17649 {
17650  assert(lp != NULL);
17651  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17652 
17653  return lp->ncols - lp->firstnewcol;
17654 }
17655 
17656 /** gets array with newly added rows after the last mark */
17658  SCIP_LP* lp /**< current LP data */
17659  )
17660 {
17661  assert(lp != NULL);
17662  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17663 
17664  return &(lp->rows[lp->firstnewrow]);
17665 }
17666 
17667 /** gets number of newly added rows after the last mark */
17669  SCIP_LP* lp /**< current LP data */
17670  )
17671 {
17672  assert(lp != NULL);
17673  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17674 
17675  return lp->nrows - lp->firstnewrow;
17676 }
17677 
17678 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17680  SCIP_SET* set, /**< global SCIP settings */
17681  SCIP_LP* lp /**< LP data */
17682  )
17683 {
17684  if( lp->objsqrnormunreliable )
17685  {
17686  SCIP_COL** cols;
17687  int c;
17688 
17689  cols = lp->cols;
17690  assert(cols != NULL || lp->ncols == 0);
17691 
17692  lp->objsqrnorm = 0.0;
17693 
17694  for( c = lp->ncols - 1; c >= 0; --c )
17695  {
17696  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17697  }
17698  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17699 
17700  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17701  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17702 
17704  }
17705  return;
17706 }
17707 
17708 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17709  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17711  SCIP_LP* lp /**< LP data */
17712  )
17713 {
17714  assert(lp != NULL);
17715  assert(!lp->objsqrnormunreliable);
17716  assert(lp->objsqrnorm >= 0.0);
17717 
17718  return SQRT(lp->objsqrnorm);
17719 }
17720 
17721 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17723  SCIP_LP* lp, /**< LP data */
17724  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17725  )
17726 {
17727  assert(lp != NULL);
17728 
17729  lp->rootlpisrelax = isrelax;
17730 }
17731 
17732 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17734  SCIP_LP* lp /**< LP data */
17735  )
17736 {
17737  assert(lp != NULL);
17738 
17739  return lp->rootlpisrelax;
17740 }
17741 
17742 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17744  SCIP_LP* lp /**< LP data */
17745  )
17746 {
17747  assert(lp != NULL);
17748 
17749  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17750 }
17751 
17752 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17753  * returns SCIP_INVALID if the root node LP was not (yet) solved
17754  */
17756  SCIP_LP* lp /**< LP data */
17757  )
17758 {
17759  assert(lp != NULL);
17760 
17761  return lp->rootlpobjval;
17762 }
17763 
17764 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17765  * returns SCIP_INVALID if the root node LP was not (yet) solved
17766  */
17768  SCIP_LP* lp /**< LP data */
17769  )
17770 {
17771  assert(lp != NULL);
17772 
17773  return lp->rootlooseobjval;
17774 }
17775 
17776 /** gets the LP solver interface */
17778  SCIP_LP* lp /**< current LP data */
17779  )
17780 {
17781  assert(lp != NULL);
17782 
17783  return lp->lpi;
17784 }
17785 
17786 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17788  SCIP_LP* lp, /**< LP data */
17789  SCIP_Bool relax /**< is the current lp a relaxation? */
17790  )
17791 {
17792  assert(lp != NULL);
17793 
17794  lp->isrelax = relax;
17795 }
17796 
17797 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17798  * solution value a valid local lower bound?
17799  */
17801  SCIP_LP* lp /**< LP data */
17802  )
17803 {
17804  assert(lp != NULL);
17805 
17806  return lp->isrelax;
17807 }
17808 
17809 /** returns whether the current LP is flushed and solved */
17811  SCIP_LP* lp /**< current LP data */
17812  )
17813 {
17814  assert(lp != NULL);
17815 
17816  return lp->flushed && lp->solved;
17817 }
17818 
17819 /** return whether the current LP solution passed the primal feasibility check */
17821  SCIP_LP* lp /**< current LP data */
17822  )
17823 {
17824  assert(lp != NULL);
17825 
17826  return (lp->primalchecked && lp->primalfeasible);
17827 }
17828 
17829 /** return whether the current LP solution passed the dual feasibility check */
17831  SCIP_LP* lp /**< current LP data */
17832  )
17833 {
17834  assert(lp != NULL);
17835 
17836  return (lp->dualchecked && lp->dualfeasible);
17837 }
17838 
17839 /** returns whether the current LP solution is a basic solution */
17841  SCIP_LP* lp /**< current LP data */
17842  )
17843 {
17844  assert(lp != NULL);
17845 
17846  return lp->solisbasic;
17847 }
17848 
17849 /** returns whether the LP is in diving mode */
17851  SCIP_LP* lp /**< current LP data */
17852  )
17853 {
17854  assert(lp != NULL);
17855 
17856  return lp->diving;
17857 }
17858 
17859 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17861  SCIP_LP* lp /**< current LP data */
17862  )
17863 {
17864  assert(lp != NULL);
17865 
17866  return lp->divingobjchg;
17867 }
17868 
17869 /** marks the diving LP to have a changed objective function */
17871  SCIP_LP* lp /**< current LP data */
17872  )
17873 {
17874  assert(lp != NULL);
17875  assert(lp->diving || lp->probing);
17876 
17877  lp->divingobjchg = TRUE;
17878 }
17879 
17880 /** marks the diving LP to not have a changed objective function anymore */
17882  SCIP_LP* lp /**< current LP data */
17883  )
17884 {
17885  assert(lp != NULL);
17886  assert(lp->diving || lp->probing);
17887 
17888  lp->divingobjchg = FALSE;
17889 }
17890 
17891 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17893  SCIP_LP* lp /**< current LP data */
17894  )
17895 {
17896  assert(lp != NULL);
17897  assert(lp->diving || lp->ndivechgsides == 0);
17898 
17899  return (lp->ndivechgsides > 0);
17900 }
17901 
17902 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17903 static
17905  SCIP_LPI* lpi, /**< auxiliary LP interface */
17906  SCIP_SET* set, /**< global SCIP settings */
17907  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17908  SCIP_LP* lp, /**< LP data */
17909  SCIP_PROB* prob, /**< problem data */
17910  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17911  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17912  SCIP_Real timelimit, /**< time limit for LP solver */
17913  int iterlimit, /**< iteration limit for LP solver */
17914  SCIP_Real* point, /**< array to store relative interior point on exit */
17915  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17916  )
17917 {
17918  SCIP_RETCODE retcode;
17919  SCIP_Real* primal;
17920  SCIP_Real* obj;
17921  SCIP_Real* lb;
17922  SCIP_Real* ub;
17923  SCIP_Real* matvals;
17924  SCIP_Real* matlhs;
17925  SCIP_Real* matrhs;
17926  SCIP_Real objval;
17927  SCIP_Real alpha;
17928  int* matinds;
17929  int* matbeg;
17930 #ifndef NDEBUG
17931  int nslacks;
17932 #endif
17933  int nnewcols;
17934  int ntotnonz = 0;
17935  int ntotrows = 0;
17936  int matrowidx;
17937  int matidx;
17938  int cnt;
17939  int j;
17940  int i;
17941 
17942  assert(lpi != NULL);
17943 
17944  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
17945  if( retcode != SCIP_OKAY )
17946  {
17947  /* stop execution on error, since result is likely to be unsuable */
17948  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17949  return SCIP_LPERROR;
17950  }
17951 
17953  if( retcode != SCIP_OKAY )
17954  {
17955  /* stop execution on error, since result is likely to be unsuable */
17956  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17957  return SCIP_LPERROR;
17958  }
17959 
17960  /* get storage */
17961  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17962  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17963  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17964  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17965 
17966  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17967  for( j = 0; j < lp->ncols; ++j )
17968  {
17969  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17970  obj[j] = 0.0;
17971  lb[j] = -SCIPlpiInfinity(lpi);
17972  ub[j] = SCIPlpiInfinity(lpi);
17973  /* note: we could also use the original bounds - free variables seem to be faster. */
17974  }
17975 
17976  /* add artificial alpha variable */
17977  nnewcols = lp->ncols;
17978  obj[nnewcols] = 0.0;
17979  lb[nnewcols] = 1.0;
17980  ub[nnewcols] = SCIPlpiInfinity(lpi);
17981  ++nnewcols;
17982 
17983  /* create slacks for rows */
17984  for( i = 0; i < lp->nrows; ++i )
17985  {
17986  SCIP_ROW* row;
17987 
17988  row = lp->rows[i];
17989  assert( row != NULL );
17990 
17991  if( SCIProwIsModifiable(row) )
17992  continue;
17993 
17994  /* make sure row is sorted */
17995  rowSortLP(row);
17996  assert( row->lpcolssorted );
17997 
17998  /* check whether we have an equation */
17999  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
18000  {
18001  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
18002  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
18003  ntotnonz += row->nlpcols + 1;
18004  ++ntotrows;
18005  }
18006  else
18007  {
18008  /* otherwise add slacks for each side if necessary */
18009  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
18010  {
18011  if ( relaxrows )
18012  {
18013  lb[nnewcols] = 0.0;
18014  ub[nnewcols] = 1.0;
18015  obj[nnewcols++] = 1.0;
18016  ntotnonz += row->nlpcols + 2;
18017  }
18018  else
18019  ntotnonz += row->nlpcols + 1;
18020  ++ntotrows;
18021  }
18022  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
18023  {
18024  if ( relaxrows )
18025  {
18026  lb[nnewcols] = 0.0;
18027  ub[nnewcols] = 1.0;
18028  obj[nnewcols++] = 1.0;
18029  ntotnonz += row->nlpcols + 2;
18030  }
18031  else
18032  ntotnonz += row->nlpcols + 1;
18033  ++ntotrows;
18034  }
18035  }
18036  }
18037 
18038  /* create slacks for objective cutoff row */
18039  if( inclobjcutoff && relaxrows )
18040  {
18041  /* add slacks for right hand side */
18042  lb[nnewcols] = 0.0;
18043  ub[nnewcols] = 1.0;
18044  obj[nnewcols++] = 1.0;
18045  ntotnonz += lp->ncols + 2;
18046  ++ntotrows;
18047  }
18048 
18049  /* create slacks for bounds */
18050  for( j = 0; j < lp->ncols; ++j )
18051  {
18052  SCIP_COL* col;
18053 
18054  col = lp->cols[j];
18055  assert( col != NULL );
18056 
18057  /* no slacks for fixed variables */
18058  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18059  {
18060  ++ntotrows;
18061  ntotnonz += 2;
18062  }
18063  else
18064  {
18065  /* add slacks for each bound if necessary */
18066  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
18067  {
18068  lb[nnewcols] = 0.0;
18069  ub[nnewcols] = 1.0;
18070  obj[nnewcols++] = 1.0;
18071  ntotnonz += 3;
18072  ++ntotrows;
18073  }
18074  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
18075  {
18076  lb[nnewcols] = 0.0;
18077  ub[nnewcols] = 1.0;
18078  obj[nnewcols++] = 1.0;
18079  ntotnonz += 3;
18080  ++ntotrows;
18081  }
18082  }
18083  }
18084 #ifndef NDEBUG
18085  nslacks = nnewcols - lp->ncols - 1;
18086  assert( nslacks >= 0 );
18087  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
18088 #endif
18089 
18090  /* add columns */
18091  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
18092 
18093  /* free storage */
18094  SCIPsetFreeBufferArray(set, &obj);
18095  SCIPsetFreeBufferArray(set, &ub);
18096  SCIPsetFreeBufferArray(set, &lb);
18097 
18098  /* prepare storage for rows */
18099  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
18100  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
18101  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
18102  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
18103  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
18104 
18105  /* create rows arising from original rows */
18106  cnt = 0;
18107  matrowidx = 0;
18108  matidx = 0;
18109  for( i = 0; i < lp->nrows; ++i )
18110  {
18111  SCIP_ROW* row;
18112  SCIP_COL** rowcols;
18113  SCIP_Real* rowvals;
18114  SCIP_Real lhs;
18115  SCIP_Real rhs;
18116  int nnonz;
18117 
18118  row = lp->rows[i];
18119  assert( row != NULL );
18120 
18121  if( SCIProwIsModifiable(row) )
18122  continue;
18123  assert( row->lpcolssorted );
18124 
18125  /* get row data */
18126  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18127  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18128  nnonz = row->nlpcols;
18129  assert( nnonz <= lp->ncols );
18130  rowcols = row->cols;
18131  rowvals = row->vals;
18132 
18133  /* if we have an equation */
18134  if( SCIPsetIsEQ(set, lhs, rhs) )
18135  {
18136  /* set up indices */
18137  matbeg[matrowidx] = matidx;
18138  for( j = 0; j < nnonz; ++j )
18139  {
18140  assert( rowcols[j] != NULL );
18141  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18142  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18143  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18144  matinds[matidx] = rowcols[j]->lppos;
18145  matvals[matidx++] = rowvals[j];
18146  assert( matidx <= ntotnonz );
18147  }
18148 
18149  /* add artificial variable */
18150  if ( ! SCIPsetIsZero(set, rhs) )
18151  {
18152  matinds[matidx] = lp->ncols;
18153  matvals[matidx++] = -rhs;
18154  assert( matidx <= ntotnonz );
18155  }
18156 
18157  matlhs[matrowidx] = 0.0;
18158  matrhs[matrowidx++] = 0.0;
18159  assert( matrowidx <= ntotrows );
18160  }
18161  else
18162  {
18163  SCIP_Real abslhs = REALABS(lhs);
18164  SCIP_Real absrhs = REALABS(rhs);
18165 
18166  assert(!SCIPsetIsEQ(set, lhs, rhs));
18167 
18168  /* treat lhs */
18169  if( !SCIPsetIsInfinity(set, abslhs) )
18170  {
18171  /* set up indices */
18172  matbeg[matrowidx] = matidx;
18173  for( j = 0; j < nnonz; ++j )
18174  {
18175  assert( rowcols[j] != NULL );
18176  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18177  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18178  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18179  matinds[matidx] = rowcols[j]->lppos;
18180  matvals[matidx++] = rowvals[j];
18181  assert( matidx <= ntotnonz );
18182  }
18183 
18184  /* add artificial variable */
18185  if ( ! SCIPsetIsZero(set, lhs) )
18186  {
18187  matinds[matidx] = lp->ncols;
18188  matvals[matidx++] = -lhs;
18189  assert( matidx <= ntotnonz );
18190  }
18191 
18192  if( relaxrows )
18193  {
18194  /* add slack variable */
18195  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18196  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18197  assert( matidx <= ntotnonz );
18198  ++cnt;
18199  }
18200 
18201  matlhs[matrowidx] = 0.0;
18202  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18203  assert( matrowidx <= ntotrows );
18204  }
18205 
18206  /* treat rhs */
18207  if( !SCIPsetIsInfinity(set, absrhs) )
18208  {
18209  /* set up indices */
18210  matbeg[matrowidx] = matidx;
18211  for( j = 0; j < nnonz; ++j )
18212  {
18213  assert( rowcols[j] != NULL );
18214  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18215  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18216  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18217  matinds[matidx] = rowcols[j]->lppos;
18218  matvals[matidx++] = rowvals[j];
18219  assert( matidx <= ntotnonz );
18220  }
18221 
18222  /* add artificial variable */
18223  if ( ! SCIPsetIsZero(set, rhs) )
18224  {
18225  matinds[matidx] = lp->ncols;
18226  matvals[matidx++] = -rhs;
18227  assert( matidx <= ntotnonz );
18228  }
18229 
18230  if( relaxrows )
18231  {
18232  /* add slack variable */
18233  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18234  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18235  ++cnt;
18236  }
18237 
18238  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18239  matrhs[matrowidx++] = 0.0;
18240  assert( matrowidx <= ntotrows );
18241  }
18242  }
18243  }
18244 
18245  /* create row arising from objective cutoff */
18246  if( inclobjcutoff )
18247  {
18248  SCIP_Real rhs;
18249 
18250  /* get row data */
18251  assert(lp->looseobjvalinf == 0);
18252  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18253 
18254  /* set up indices and coefficients */
18255  matbeg[matrowidx] = matidx;
18256  for( j = 0; j < lp->ncols; ++j )
18257  {
18258  assert( lp->cols[j] != NULL );
18259  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18260  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18261 
18262  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18263  {
18264  matinds[matidx] = lp->cols[j]->lppos;
18265  matvals[matidx++] = lp->cols[j]->obj;
18266  assert( matidx <= ntotnonz );
18267  }
18268  }
18269 
18270  /* treat rhs */
18271 
18272  /* add artificial variable */
18273  if ( ! SCIPsetIsZero(set, rhs) )
18274  {
18275  matinds[matidx] = lp->ncols;
18276  matvals[matidx++] = -rhs;
18277  assert( matidx <= ntotnonz );
18278  }
18279 
18280  if( relaxrows )
18281  {
18282  SCIP_Real absrhs = REALABS(rhs);
18283 
18284  /* add slack variable */
18285  matvals[matidx] = MAX(1.0, absrhs);
18286  matinds[matidx++] = lp->ncols + 1 + cnt;
18287  assert( matidx <= ntotnonz );
18288  ++cnt;
18289  }
18290  matlhs[matrowidx] = -SCIPsetInfinity(set);
18291  matrhs[matrowidx++] = 0.0;
18292  assert( matrowidx <= ntotrows );
18293  }
18294 
18295  /* create rows arising from bounds */
18296  for( j = 0; j < lp->ncols; ++j )
18297  {
18298  SCIP_COL* col;
18299  SCIP_Real abscollb;
18300  SCIP_Real abscolub;
18301 
18302  col = lp->cols[j];
18303  assert( col != NULL );
18304  assert( col->lppos == j );
18305 
18306  /* fixed variable */
18307  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18308  {
18309  /* set up index of column */
18310  matbeg[matrowidx] = matidx;
18311 
18312  matinds[matidx] = j;
18313  matvals[matidx++] = 1.0;
18314  assert( matidx <= ntotnonz );
18315 
18316  /* add artificial variable */
18317  if ( ! SCIPsetIsZero(set, col->ub) )
18318  {
18319  matinds[matidx] = lp->ncols;
18320  matvals[matidx++] = -col->ub;
18321  assert( matidx <= ntotnonz );
18322  }
18323 
18324  matlhs[matrowidx] = 0.0;
18325  matrhs[matrowidx++] = 0.0;
18326  assert( matrowidx <= ntotrows );
18327 
18328  continue;
18329  }
18330 
18331  abscollb = REALABS(col->lb);
18332  abscolub = REALABS(col->ub);
18333 
18334  /* lower bound */
18335  if ( ! SCIPsetIsInfinity(set, abscollb) )
18336  {
18337  /* set up index of column */
18338  matbeg[matrowidx] = matidx;
18339 
18340  matinds[matidx] = j;
18341  matvals[matidx++] = 1.0;
18342  assert( matidx <= ntotnonz );
18343 
18344  /* add artificial variable */
18345  if ( ! SCIPsetIsZero(set, col->lb) )
18346  {
18347  matinds[matidx] = lp->ncols;
18348  matvals[matidx++] = -col->lb;
18349  assert( matidx <= ntotnonz );
18350  }
18351 
18352  /* add slack variable */
18353  matvals[matidx] = -MAX(1.0, abscollb);
18354  matinds[matidx++] = lp->ncols + 1 + cnt;
18355  assert( matidx <= ntotnonz );
18356  ++cnt;
18357 
18358  matlhs[matrowidx] = 0.0;
18359  matrhs[matrowidx++] = SCIPsetInfinity(set);
18360  assert( matrowidx <= ntotrows );
18361  }
18362 
18363  /* upper bound */
18364  if ( ! SCIPsetIsInfinity(set, abscolub) )
18365  {
18366  /* set up index of column */
18367  matbeg[matrowidx] = matidx;
18368 
18369  matinds[matidx] = j;
18370  matvals[matidx++] = 1.0;
18371  assert( matidx <= ntotnonz );
18372 
18373  /* add artificial variable */
18374  if ( ! SCIPsetIsZero(set, col->ub) )
18375  {
18376  matinds[matidx] = lp->ncols;
18377  matvals[matidx++] = -col->ub;
18378  assert( matidx <= ntotnonz );
18379  }
18380 
18381  /* add slack variable */
18382  matvals[matidx] = MAX(1.0, abscolub);
18383  matinds[matidx++] = lp->ncols + 1 + cnt;
18384  assert( matidx <= ntotnonz );
18385  ++cnt;
18386 
18387  matlhs[matrowidx] = -SCIPsetInfinity(set);
18388  matrhs[matrowidx++] = 0.0;
18389  assert( matrowidx <= ntotrows );
18390  }
18391  }
18392  assert( cnt == nslacks );
18393  assert( matrowidx == ntotrows );
18394 
18395  /* add rows */
18396  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18397 
18398  SCIPsetFreeBufferArray(set, &matrhs);
18399  SCIPsetFreeBufferArray(set, &matlhs);
18400  SCIPsetFreeBufferArray(set, &matbeg);
18401  SCIPsetFreeBufferArray(set, &matvals);
18402  SCIPsetFreeBufferArray(set, &matinds);
18403 
18404 #ifdef SCIP_OUTPUT
18405  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18406 #endif
18407 
18408 #ifndef NDEBUG
18409  {
18410  int ncols;
18411  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18412  assert( ncols == nnewcols );
18413  }
18414 #endif
18415 
18416  /* set time limit */
18417  if( SCIPsetIsInfinity(set, timelimit) )
18418  timelimit = SCIPlpiInfinity(lpi);
18419  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18420 
18421  /* check, if parameter is unknown */
18422  if( retcode == SCIP_PARAMETERUNKNOWN )
18423  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18424  else if ( retcode != SCIP_OKAY )
18425  return retcode;
18426 
18427  /* set iteration limit */
18428  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18429 
18430  /* check, if parameter is unknown */
18431  if( retcode == SCIP_PARAMETERUNKNOWN )
18432  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18433  else if ( retcode != SCIP_OKAY )
18434  return retcode;
18435 
18436  /* solve and store point */
18437  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18438  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18439 
18440 #ifndef NDEBUG
18441  if ( SCIPlpiIsIterlimExc(lpi) )
18442  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18443  if ( SCIPlpiIsTimelimExc(lpi) )
18444  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18445 #endif
18446 
18447  if( SCIPlpiIsOptimal(lpi) )
18448  {
18449  /* get primal solution */
18450  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18451  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18452  alpha = primal[lp->ncols];
18453  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18454 
18455  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18456 
18457  /* construct relative interior point */
18458  for( j = 0; j < lp->ncols; ++j )
18459  point[j] = primal[j]/alpha;
18460 
18461 #ifdef SCIP_DEBUG
18462  /* check whether the point is a relative interior point */
18463  cnt = 0;
18464  if( relaxrows )
18465  {
18466  for( i = 0; i < lp->nrows; ++i )
18467  {
18468  SCIP_ROW* row;
18469  SCIP_COL** rowcols;
18470  SCIP_Real* rowvals;
18471  SCIP_Real lhs;
18472  SCIP_Real rhs;
18473  SCIP_Real sum;
18474  int nnonz;
18475 
18476  row = lp->rows[i];
18477  assert( row != NULL );
18478 
18479  /* get row data */
18480  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18481  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18482  nnonz = row->nlpcols;
18483  assert( nnonz <= lp->ncols );
18484  rowcols = row->cols;
18485  rowvals = row->vals;
18486 
18487  sum = 0.0;
18488  for( j = 0; j < nnonz; ++j )
18489  sum += rowvals[j] * primal[rowcols[j]->lppos];
18490  sum /= alpha;
18491 
18492  /* if we have an equation */
18493  if( SCIPsetIsEQ(set, lhs, rhs) )
18494  {
18495  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18496  }
18497  else
18498  {
18499  /* treat lhs */
18500  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18501  {
18502  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18503  ++cnt;
18504  }
18505  /* treat rhs */
18506  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18507  {
18508  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18509  ++cnt;
18510  }
18511  }
18512  }
18513  if( inclobjcutoff )
18514  {
18515  SCIP_Real sum;
18516 #ifndef NDEBUG
18517  SCIP_Real rhs;
18518 
18519  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18520 #endif
18521  sum = 0.0;
18522  for( j = 0; j < lp->ncols; ++j )
18523  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18524  sum /= alpha;
18525 
18526  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18527  ++cnt;
18528  }
18529  }
18530  /* check bounds */
18531  for( j = 0; j < lp->ncols; ++j )
18532  {
18533  SCIP_COL* col;
18534 #ifndef NDEBUG
18535  SCIP_Real val;
18536 #endif
18537 
18538  col = lp->cols[j];
18539  assert( col != NULL );
18540 #ifndef NDEBUG
18541  val = primal[col->lppos] / alpha;
18542 #endif
18543  /* if the variable is not fixed */
18544  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18545  {
18546  /* treat lb */
18547  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18548  {
18549  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18550  ++cnt;
18551  }
18552  /* treat rhs */
18553  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18554  {
18555  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18556  ++cnt;
18557  }
18558  }
18559  }
18560 #endif
18561 
18562  /* free */
18563  SCIPsetFreeBufferArray(set, &primal);
18564 
18565  *success = TRUE;
18566  }
18567 
18568  return SCIP_OKAY;
18569 }
18570 
18571 /** compute relative interior point
18572  *
18573  * We use the approach of@par
18574  * R. Freund, R. Roundy, M. J. Todd@par
18575  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18576  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18577  *
18578  * to compute a relative interior point for the current LP.
18579  *
18580  * Assume the original LP looks as follows:
18581  * \f[
18582  * \begin{array}{rrl}
18583  * \min & c^T x &\\
18584  * & A x & \geq a\\
18585  * & B x & \leq b\\
18586  * & D x & = d.
18587  * \end{array}
18588  * \f]
18589  * Note that bounds should be included in the system.
18590  *
18591  * To find an interior point the following LP does the job:
18592  * \f[
18593  * \begin{array}{rrl}
18594  * \max & 1^T y &\\
18595  * & A x - y - \alpha a & \geq 0\\
18596  * & B x + y - \alpha b & \leq 0\\
18597  * & D x - \alpha d & = 0\\
18598  * & 0 \leq y & \leq 1\\
18599  * & \alpha & \geq 1.
18600  * \end{array}
18601  * \f]
18602  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18603  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18604  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18605  */
18607  SCIP_SET* set, /**< global SCIP settings */
18608  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18609  SCIP_LP* lp, /**< LP data */
18610  SCIP_PROB* prob, /**< problem data */
18611  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18612  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18613  SCIP_Real timelimit, /**< time limit for LP solver */
18614  int iterlimit, /**< iteration limit for LP solver */
18615  SCIP_Real* point, /**< array to store relative interior point on exit */
18616  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18617  )
18618 {
18619  SCIP_LPI* lpi;
18620  SCIP_RETCODE retcode;
18621 
18622  assert(set != NULL);
18623  assert(lp != NULL);
18624  assert(point != NULL);
18625  assert(success != NULL);
18626 
18627  *success = FALSE;
18628 
18629  /* check time and iteration limits */
18630  if ( timelimit <= 0.0 || iterlimit <= 0 )
18631  return SCIP_OKAY;
18632 
18633  /* exit if there are no columns */
18634  assert(lp->nrows >= 0);
18635  assert(lp->ncols >= 0);
18636  if( lp->ncols == 0 )
18637  return SCIP_OKAY;
18638 
18639  /* disable objective cutoff if we have none */
18640  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18641  inclobjcutoff = FALSE;
18642 
18643  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18644 
18645  /* if there are no rows, we return the zero point */
18646  if( lp->nrows == 0 && !inclobjcutoff )
18647  {
18648  /* create zero point */
18649  BMSclearMemoryArray(point, lp->ncols);
18650  *success = TRUE;
18651 
18652  return SCIP_OKAY;
18653  }
18654 
18655  /* create auxiliary LP */
18656  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18657 
18658  /* catch return code and ensure that lpi is freed, anyway */
18659  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18660 
18661  SCIP_CALL( SCIPlpiFree(&lpi) );
18662 
18663  /* return error, unless we obtained an LP error */
18664  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18665  {
18666  SCIP_CALL( retcode );
18667  }
18668 
18669  return SCIP_OKAY;
18670 }
18671 
18672 /** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
18673  * based on the changes applied when reducing the problem to the optimal face
18674  *
18675  * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
18676  * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
18677  */
18679  SCIP_LP* lp, /**< LP data */
18680  SCIP_SET* set, /**< global SCIP settings */
18681  SCIP_STAT* stat, /**< problem statistics */
18682  SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
18683  SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
18684  )
18685 {
18686  assert(lp != NULL);
18687  assert(lp->solved);
18688  assert(lp->flushed);
18689 
18690  if( lp->validdegeneracylp != stat->nlps )
18691  {
18692  lp->validdegeneracylp = stat->nlps;
18693 
18694  /* if the LP was solved to optimality, we determine the dual degeneracy */
18696  {
18697  SCIP_COL** cols;
18698  SCIP_ROW** rows;
18699  SCIP_COL* col;
18700  int ncols;
18701  int nrows;
18702  int nfixedcols = 0;
18703  int nalreadyfixedcols = 0;
18704  int nfixedrows = 0;
18705 #ifndef NDEBUG
18706  int nimplicitfixedrows = 0;
18707 #endif
18708  int nineq = 0;
18709  int c;
18710  int r;
18711  int nbasicequalities = 0;
18712 
18713  cols = lp->cols;
18714  rows = lp->rows;
18715  ncols = lp->ncols;
18716  nrows = lp->nrows;
18717 
18718  /* count number of columns that will be fixed when reducing the LP to the optimal face */
18719  for( c = ncols - 1 ; c >= 0; --c )
18720  {
18721  col = cols[c];
18722  assert(SCIPcolIsInLP(col));
18723 
18724  /* column is not basic and not fixed already */
18726  {
18727  /* variable with nonzero reduced costs are fixed */
18728  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18729  if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
18730  ++nfixedcols;
18731  else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
18732  ++nalreadyfixedcols;
18733  }
18734  }
18735 
18736  /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
18737  for( r = nrows - 1; r >= 0; --r )
18738  {
18739  SCIP_ROW* row = rows[r];
18740 
18741  assert(SCIProwIsInLP(row));
18742 
18743  if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
18744  {
18745  SCIP_Real dualsol = SCIProwGetDualsol(row);
18746 
18747  ++nineq;
18748 
18750  {
18751  /* rows with nonzero dual solution are turned into equations */
18752  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18753  if( !SCIPsetIsZero(set, dualsol) )
18754  {
18755  if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18756  {
18757  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol));
18758  ++nfixedrows;
18759  }
18760  else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18761  {
18762  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol));
18763  ++nfixedrows;
18764  }
18765  }
18766 #ifndef NDEBUG
18767  else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
18768  || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
18769  {
18770  ++nimplicitfixedrows;
18771  }
18772 #endif
18773  }
18774  }
18775  else if( SCIProwGetBasisStatus(row) == SCIP_BASESTAT_BASIC )
18776  ++nbasicequalities;
18777  }
18778  assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
18779 
18780  if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
18781  lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
18782  else
18783  lp->degeneracy = 0.0;
18784 
18785  if( nrows > 0 )
18786  lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
18787  else
18788  lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
18789  assert(lp->degeneracy >= 0);
18790  assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
18791  assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
18792  }
18793  else
18794  {
18795  lp->degeneracy = 0.0;
18796  lp->varconsratio = 0.0;
18797  }
18798  }
18799 
18800  *degeneracy = lp->degeneracy;
18801  *varconsratio = lp->varconsratio;
18802 
18803  return SCIP_OKAY;
18804 }
18805 
18806 /** checks, if absolute difference of values is in range of LP primal feastol */
18808  SCIP_SET* set, /**< global SCIP settings */
18809  SCIP_LP* lp, /**< current LP data */
18810  SCIP_Real val1, /**< first value to be compared */
18811  SCIP_Real val2 /**< second value to be compared */
18812  )
18813 {
18814  assert(set != NULL);
18815  assert(lp != NULL);
18816 
18817  /* avoid to compare two different infinities; the reason for that is
18818  * that such a comparison can lead to unexpected results */
18819  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18820  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18821  || val1 == val2 ); /*lint !e777*/
18822 
18823  return EPSEQ(val1, val2, lp->feastol);
18824 }
18825 
18826 /** checks, if absolute difference of val1 and val2 is lower than LP primal feastol */
18828  SCIP_SET* set, /**< global SCIP settings */
18829  SCIP_LP* lp, /**< current LP data */
18830  SCIP_Real val1, /**< first value to be compared */
18831  SCIP_Real val2 /**< second value to be compared */
18832  )
18833 {
18834  assert(set != NULL);
18835  assert(lp != NULL);
18836 
18837  /* avoid to compare two different infinities; the reason for that is
18838  * that such a comparison can lead to unexpected results */
18839  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18840  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18841  || val1 == val2 ); /*lint !e777*/
18842 
18843  return EPSLT(val1, val2, lp->feastol);
18844 }
18845 
18846 /** checks, if absolute difference of val1 and val2 is not greater than LP primal feastol */
18848  SCIP_SET* set, /**< global SCIP settings */
18849  SCIP_LP* lp, /**< current LP data */
18850  SCIP_Real val1, /**< first value to be compared */
18851  SCIP_Real val2 /**< second value to be compared */
18852  )
18853 {
18854  assert(set != NULL);
18855  assert(lp != NULL);
18856 
18857  /* avoid to compare two different infinities; the reason for that is
18858  * that such a comparison can lead to unexpected results */
18859  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18860  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18861  || val1 == val2 ); /*lint !e777*/
18862 
18863  return EPSLE(val1, val2, lp->feastol);
18864 }
18865 
18866 /** checks, if absolute difference of val1 and val2 is greater than LP primal feastol */
18868  SCIP_SET* set, /**< global SCIP settings */
18869  SCIP_LP* lp, /**< current LP data */
18870  SCIP_Real val1, /**< first value to be compared */
18871  SCIP_Real val2 /**< second value to be compared */
18872  )
18873 {
18874  assert(set != NULL);
18875  assert(lp != NULL);
18876 
18877  /* avoid to compare two different infinities; the reason for that is
18878  * that such a comparison can lead to unexpected results */
18879  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18880  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18881  || val1 == val2 ); /*lint !e777*/
18882 
18883  return EPSGT(val1, val2, lp->feastol);
18884 }
18885 
18886 /** checks, if absolute difference of val1 and val2 is not lower than -LP primal feastol */
18888  SCIP_SET* set, /**< global SCIP settings */
18889  SCIP_LP* lp, /**< current LP data */
18890  SCIP_Real val1, /**< first value to be compared */
18891  SCIP_Real val2 /**< second value to be compared */
18892  )
18893 {
18894  assert(set != NULL);
18895  assert(lp != NULL);
18896 
18897  /* avoid to compare two different infinities; the reason for that is
18898  * that such a comparison can lead to unexpected results */
18899  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18900  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18901  || val1 == val2 ); /*lint !e777*/
18902 
18903  return EPSGE(val1, val2, lp->feastol);
18904 }
18905 
18906 /** checks, if value is in range LP primal feasibility tolerance of 0.0 */
18908  SCIP_LP* lp, /**< current LP data */
18909  SCIP_Real val /**< value to process */
18910  )
18911 {
18912  assert(lp != NULL);
18913 
18914  return EPSZ(val, lp->feastol);
18915 }
18916 
18917 /** checks, if value is greater than LP primal feasibility tolerance */
18919  SCIP_LP* lp, /**< current LP data */
18920  SCIP_Real val /**< value to process */
18921  )
18922 {
18923  assert(lp != NULL);
18924 
18925  return EPSP(val, lp->feastol);
18926 }
18927 
18928 /** checks, if value is lower than -LP primal feasibility tolerance */
18930  SCIP_LP* lp, /**< current LP data */
18931  SCIP_Real val /**< value to process */
18932  )
18933 {
18934  assert(lp != NULL);
18935 
18936  return EPSN(val, lp->feastol);
18937 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:410
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:7332
SCIP_Longint nprimallps
Definition: struct_stat.h:194
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17424
SCIP_Bool solisbasic
Definition: struct_lp.h:372
SCIP_Real lazyub
Definition: struct_lp.h:143
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1821
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:70
SCIP_Bool lpissolved
Definition: struct_lp.h:125
int nunlinked
Definition: struct_lp.h:237
static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition: lp.c:17904
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4755
int firstnewrow
Definition: struct_lp.h:336
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16494
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6512
SCIP_Real sbup
Definition: struct_lp.h:154
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13194
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:4711
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3276
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:102
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1417
void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:10285
int nsbcalls
Definition: struct_lp.h:176
SCIP_Bool primalchecked
Definition: struct_lp.h:121
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lp.c:376
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6215
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6518
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2545
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2864
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6707
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4303
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:470
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2752
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:13728
SCIP_Real maxactivity
Definition: struct_lp.h:218
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8941
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:894
internal methods for managing events
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10181
SCIP_Real obj
Definition: struct_lp.h:137
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17892
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:643
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2839
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7369
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6273
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17668
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6723
SCIP_Longint validdegeneracylp
Definition: struct_lp.h:314
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2970
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7012
void * origin
Definition: struct_lp.h:225
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:231
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:4944
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14031
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3429
SCIP_STATUS status
Definition: struct_stat.h:186
SCIP_Longint nlpiterations
Definition: struct_stat.h:62
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17850
SCIP_Real farkascoef
Definition: struct_lp.h:150
unsigned int ubchanged
Definition: struct_lp.h:184
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1864
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:150
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9709
int nummaxval
Definition: struct_lp.h:245
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17787
SCIP_Longint validactivitylp
Definition: struct_lp.h:232
int lpifirstchgrow
Definition: struct_lp.h:321
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2397
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6536
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3648
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:17374
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1401
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17479
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:110
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:210
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:6122
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6691
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:88
int * cols_index
Definition: struct_lp.h:228
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_clp.cpp:3610
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16361
int nremovablecols
Definition: struct_lp.h:331
char * name
Definition: struct_var.h:235
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition: set.c:7409
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15716
SCIP_Bool primalfeasible
Definition: struct_lp.h:368
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:18606
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:905
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3119
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:913
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2857
int nchgrows
Definition: struct_lp.h:325
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:237
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9876
char * name
Definition: struct_lp.h:226
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:18071
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6278
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:3517
int nlpicols
Definition: struct_lp.h:317
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6613
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2006
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:2788
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:544
enum SCIP_BaseStat SCIP_BASESTAT
Definition: type_lpi.h:96
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15685
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, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12030
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6426
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17722
SCIP_Longint nlps
Definition: struct_stat.h:192
SCIP_Longint activeinlpcounter
Definition: struct_lp.h:222
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:2240
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17923
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6644
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:354
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3692
#define SCIP_MAXSTRLEN
Definition: def.h:302
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8009
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:17034
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6176
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1805
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17679
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:78
internal methods for clocks and timing issues
SCIP_RETCODE SCIPlpInterrupt(SCIP_LP *lp, SCIP_Bool interrupt)
Definition: lp.c:10121
unsigned int origintype
Definition: struct_lp.h:265
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13605
int lpdepth
Definition: struct_lp.h:241
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17164
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17176
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6338
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:126
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17216
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2967
SCIP_Real objsumnorm
Definition: struct_lp.h:293
SCIP_Longint ndivinglps
Definition: struct_stat.h:207
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:1979
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17979
SCIP_ROW ** chgrows
Definition: struct_lp.h:300
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5343
SCIP_COL ** chgcols
Definition: struct_lp.h:299
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:5589
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:15305
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:15230
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1167
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11999
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17354
int rank
Definition: struct_lp.h:248
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3648
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:1033
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17444
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6080
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2921
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1268
int rowssize
Definition: struct_lp.h:333
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8906
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3702
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7901
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17548
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13273
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:15055
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13922
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14210
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:629
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11501
unsigned int nonlprowssorted
Definition: struct_lp.h:181
int nclockskipsleft
Definition: struct_stat.h:275
SCIP_COL ** cols
Definition: struct_lp.h:301
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10104
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1304
int nlpirows
Definition: struct_lp.h:320
#define lpCutoffDisabled(set, prob)
Definition: lp.c:2650
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:114
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:148
int soldirectionsize
Definition: struct_lp.h:327
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:17230
#define debugColPrint(x, y)
Definition: lp.c:159
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:3283
static const int nscalars
Definition: lp.c:5748
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10307
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:47
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13895
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17295
SCIP_ROW ** rows
Definition: struct_lp.h:161
#define FALSE
Definition: def.h:96
int lppos
Definition: struct_lp.h:172
SCIP_Real lazylb
Definition: struct_lp.h:141
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:16530
#define EPSEQ(x, y, eps)
Definition: def.h:211
#define EPSISINT(x, eps)
Definition: def.h:223
int pseudoobjvalinf
Definition: struct_lp.h:340
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17840
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:303
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13963
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6756
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:779
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:17075
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3623
int divinglpiitlim
Definition: struct_lp.h:344
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16976
SCIP_Bool solved
Definition: struct_lp.h:367
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:1698
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11096
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Longint nrootlps
Definition: struct_stat.h:193
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:17343
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16956
SCIP_Bool dualchecked
Definition: struct_lp.h:371
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6327
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16508
#define TRUE
Definition: def.h:95
#define SCIPdebug(x)
Definition: pub_message.h:93
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8232
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_Bool lpifromscratch
Definition: struct_lp.h:385
unsigned int basisstatus
Definition: struct_lp.h:250
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2795
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6812
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10037
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3833
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:17755
#define EPSP(x, eps)
Definition: def.h:217
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16348
SCIP_Real dualsol
Definition: struct_lp.h:107
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real objlim, SCIP_Bool *success)
Definition: lp.c:2657
SCIP_Real redcost
Definition: struct_lp.h:149
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1734
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:468
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2468
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2585
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:5480
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17613
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3592
SCIP_Bool SCIPlpIsFeasLE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18847
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:360
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:57
unsigned int sbdownvalid
Definition: struct_lp.h:188
unsigned int objchanged
Definition: struct_lp.h:182
#define DIVESTACKGROWFACT
Definition: lp.c:16291
unsigned int delaysort
Definition: struct_lp.h:253
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5794
#define SCIP_UNUSED(x)
Definition: def.h:448
unsigned int basisstatus
Definition: struct_lp.h:179
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:17107
SCIP_Real lpidualfeastol
Definition: struct_lp.h:288
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:73
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15654
SCIP_Real sbsolval
Definition: struct_lp.h:155
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6424
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3096
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:9062
SCIP_Real sumnorm
Definition: struct_lp.h:209
int lpifastmip
Definition: struct_lp.h:346
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1435
public methods for problem variables
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:125
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6968
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1908
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:16112
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:5985
int index
Definition: struct_lp.h:167
SCIP_Real relpseudoobjval
Definition: struct_lp.h:281
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2945
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real dualfarkas
Definition: struct_lp.h:215
#define EPSGE(x, y, eps)
Definition: def.h:215
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:12416
SCIP_Real minprimsol
Definition: struct_lp.h:151
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:167
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12334
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition: set.c:6194
SCIP_Real pseudoobjval
Definition: struct_lp.h:279
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17615
SCIP_Bool diving
Definition: struct_lp.h:380
#define SCIPdebugMessage
Definition: pub_message.h:96
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7923
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:13646
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13305
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6755
SCIP_Real rootlooseobjval
Definition: struct_lp.h:283
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1709
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:3568
int firstnewcol
Definition: struct_lp.h:332
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:15893
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17444
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3472
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10195
unsigned int coefchanged
Definition: struct_lp.h:185
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:15245
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
unsigned int integral
Definition: struct_lp.h:258
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:470
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:10161
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1137
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:111
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6349
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17434
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:3031
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1066
#define SCIP_LONGINT_MAX
Definition: def.h:172
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:168
int lpifirstchgcol
Definition: struct_lp.h:318
int index
Definition: struct_lp.h:233
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1741
unsigned int basisstatus
Definition: struct_lp.h:109
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
#define BMSfreeMemory(ptr)
Definition: memory.h:147
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16333
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:480
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2557
#define checkRow(row)
Definition: lp.c:695
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6569
int maxdepth
Definition: struct_stat.h:236
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:9036
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:86
int looseobjvalinf
Definition: struct_lp.h:337
SCIP_Real obj
Definition: struct_var.h:209
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:361
unsigned int rhschanged
Definition: struct_lp.h:256
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:5532
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17315
int nlpcols
Definition: struct_lp.h:236
SCIP_COL ** lpicols
Definition: struct_lp.h:297
unsigned int lprowssorted
Definition: struct_lp.h:180
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13106
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition: lp.c:283
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:260
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4743
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:63
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:531
int lazycolssize
Definition: struct_lp.h:329
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14123
Definition: heur_padm.c:132
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:863
SCIP_Real objprod
Definition: struct_lp.h:210
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3314
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:17733
int colssize
Definition: struct_lp.h:326
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:355
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:16294
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:391
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:401
SCIP_Bool lpipresolving
Definition: struct_lp.h:386
int nremovablerows
Definition: struct_lp.h:335
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:758
SCIP_Bool primalchecked
Definition: struct_lp.h:369
real eps
SCIP_Bool strongbranching
Definition: struct_lp.h:377
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1347
SCIP_Bool dualfeasible
Definition: struct_lp.h:122
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2488
#define checkLinks(lp)
Definition: lp.c:1624
int lpithreads
Definition: struct_lp.h:347
int ndivechgsides
Definition: struct_lp.h:342
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17578
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12307
int * linkpos
Definition: struct_lp.h:230
#define FEASTOLTIGHTFAC
Definition: lp.c:11580
#define SCIP_DEFAULT_EPSILON
Definition: def.h:192
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6309
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2752
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17526
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:7077
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2353
SCIP_Real * vals
Definition: struct_lp.h:229
unsigned int integral
Definition: struct_lp.h:186
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:9305
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4314
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1880
int nloosevars
Definition: struct_lp.h:338
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:1985
SCIP_Bool SCIPlpIsFeasEQ(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18807
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2647
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17743
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3851
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4834
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17933
int lppos
Definition: struct_lp.h:239
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6163
int divechgsidessize
Definition: struct_lp.h:343
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6255
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:15854
int * linkpos
Definition: struct_lp.h:166
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:373
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6482
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:914
SCIP_Real flushedlb
Definition: struct_lp.h:146
SCIP_Real inf
Definition: intervalarith.h:55
int lpiitlim
Definition: struct_lp.h:345
SCIP_Real lb
Definition: struct_lp.h:138
SCIP_Real dualsol
Definition: struct_lp.h:213
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:7837
int SCIPcolGetAge(SCIP_COL *col)
Definition: lp.c:17196
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:4001
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:289
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:3451
int glbpseudoobjvalinf
Definition: struct_lp.h:339
#define EPSN(x, eps)
Definition: def.h:218
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17646
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13990
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:17283
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:464
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2479
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14255
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:497
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:16006
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16999
SCIP_Real sbdown
Definition: struct_lp.h:153
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6723
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:16318
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5670
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6020
int lpirefactorinterval
Definition: struct_lp.h:351
SCIP_ROW ** divechgrows
Definition: struct_lp.h:308
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:397
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8675
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:8183
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:1886
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:16545
SCIP_Bool installing
Definition: struct_lp.h:376
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:402
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:17820
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17206
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:4904
#define SCIPerrorMessage
Definition: pub_message.h:64
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:678
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition: lp.c:3233
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14333
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17830
SCIP_Real sqrnorm
Definition: struct_lp.h:208
SCIP_Longint lpcount
Definition: struct_stat.h:190
SCIP_Bool lpilpinfo
Definition: struct_lp.h:387
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17154
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3189
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:2304
SCIP_Real pseudoactivity
Definition: struct_lp.h:216
SCIP_PRICING lpipricing
Definition: struct_lp.h:352
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9454
SCIP_Bool dualchecked
Definition: struct_lp.h:123
SCIP_COL ** cols
Definition: struct_lp.h:227
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:1002
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9637
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17568
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17404
SCIP_Bool adjustlpval
Definition: struct_lp.h:384
SCIP_Real minval
Definition: struct_lp.h:212
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:4086
SCIP_Real flushedub
Definition: struct_lp.h:147
SCIP_ROW ** lpirows
Definition: struct_lp.h:298
unsigned int sbupvalid
Definition: struct_lp.h:190
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3503
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:198
SCIP_Longint validsoldirlp
Definition: struct_lp.h:313
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:15783
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8627
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5734
SCIP_Longint validfarkaslp
Definition: struct_lp.h:312
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:9951
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:220
SCIP_Real lhs
Definition: struct_lp.h:204
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2502
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9794
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:6150
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16966
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:113
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:173
int nuses
Definition: struct_lp.h:238
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17264
int lpiscaling
Definition: struct_lp.h:350
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:2043
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:438
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:17394
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:2283
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:427
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6340
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14668
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition: lp.c:10061
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6152
SCIP_Real cutoffbound
Definition: struct_lp.h:284
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6454
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:9513
internal miscellaneous methods
#define NULL
Definition: lpi_spx1.cpp:164
SCIP_Bool isrelax
Definition: struct_lp.h:374
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17710
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:69
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6890
int numintcols
Definition: struct_lp.h:244
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:2350
SCIP_Bool userinterrupt
Definition: struct_stat.h:278
#define REALABS(x)
Definition: def.h:210
int maxidx
Definition: struct_lp.h:243
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:309
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2709
SCIP_Bool looseobjvalid
Definition: struct_lp.h:358
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:394
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition: lp.c:10260
SCIP_Real activity
Definition: struct_lp.h:108
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6701
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:18061
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6530
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2405
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17625
int lpirandomseed
Definition: struct_lp.h:349
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:594
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:223
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17870
SCIP_Longint nduallpiterations
Definition: struct_stat.h:66
SCIP_Bool flushaddedrows
Definition: struct_lp.h:364
SCIP_Bool resolvelperror
Definition: struct_lp.h:383
unsigned int removable
Definition: struct_lp.h:187
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:280
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17305
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8380
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11492
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3623
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:986
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6237
int lpicolssize
Definition: struct_lp.h:316
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17777
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13122
SCIP_LPI * lpi
Definition: struct_lp.h:296
SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18929
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5303
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2436
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17414
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1819
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:276
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6657
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17241
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6912
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:201
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:307
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2300
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4184
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6739
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:169
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:1524
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:9014
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8866
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5356
int var_probindex
Definition: struct_lp.h:178
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, int scaling, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12217
SCIP_Longint nduallps
Definition: struct_stat.h:196
SCIP_RETCODE SCIPlpGetDualDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
Definition: lp.c:18678
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9419
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6470
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:17055
SCIP_Real sblpobjval
Definition: struct_lp.h:156
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:467
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition: lp.c:10250
internal methods for problem variables
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2450
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7974
#define SCIP_UNKNOWN
Definition: def.h:207
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9820
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6360
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2766
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17251
int nchgcols
Definition: struct_lp.h:323
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:1018
public data structures and miscellaneous methods
SCIP_Bool SCIPlpIsFeasGT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18867
int len
Definition: struct_lp.h:169
SCIP_Real * soldirection
Definition: struct_lp.h:304
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17767
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9775
SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18887
#define SCIP_Bool
Definition: def.h:93
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13205
SCIP_Real redcost
Definition: struct_lp.h:96
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3522
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:837
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:6112
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:202
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:456
int numminval
Definition: struct_lp.h:246
int lpipos
Definition: struct_lp.h:240
int size
Definition: struct_lp.h:234
unsigned int modifiable
Definition: struct_lp.h:260
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:821
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3919
void SCIPprintSysError(const char *message)
Definition: misc.c:10680
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15404
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
SCIP_RETCODE SCIPlpFree(SCIP_LP **lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9374
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16986
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6053
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:112
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3903
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:980
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3389
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: cons.c:6208
int chgrowssize
Definition: struct_lp.h:324
int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
Definition: lp.c:17588
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17657
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18310
SCIP_Longint validfarkaslp
Definition: struct_lp.h:164
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:326
unsigned int lbchanged
Definition: struct_lp.h:183
SCIP_Bool divingobjchg
Definition: struct_lp.h:381
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9854
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:469
SCIP_Longint sbnode
Definition: struct_lp.h:157
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17860
SCIP_Real feastol
Definition: struct_lp.h:285
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3761
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3433
#define MAX(x, y)
Definition: tclique_def.h:92
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition: lp.c:1101
unsigned int basisstatus
Definition: struct_lp.h:97
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8110
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition: lp.c:3144
SCIP_Real degeneracy
Definition: struct_lp.h:294
SCIP_Bool updateintegrality
Definition: struct_lp.h:365
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17781
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:9079
#define SCIPsetDebugMsg
Definition: set.h:1770
SCIP_Real unchangedobj
Definition: struct_lp.h:140
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:395
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:4214
int minidx
Definition: struct_lp.h:242
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:17086
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2184
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2309
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:400
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17771
#define EPSLE(x, y, eps)
Definition: def.h:213
int nlprows
Definition: struct_lp.h:170
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition: lp.c:5434
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9082
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9837
unsigned int lpcolssorted
Definition: struct_lp.h:251
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:382
SCIP_Longint validsollp
Definition: struct_lp.h:311
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3469
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9806
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17328
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17634
SCIP_CLOCK * resolveinstablelptime
Definition: struct_stat.h:168
static void colSortLP(SCIP_COL *col)
Definition: lp.c:969
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13935
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6869
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6928
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:260
SCIP_Real ub
Definition: struct_lp.h:139
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15932
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6635
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2623
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6446
SCIP_ROW ** rows
Definition: struct_lp.h:303
SCIP_SOL * validsoldirsol
Definition: struct_lp.h:310
SCIP_Longint validredcostlp
Definition: struct_lp.h:163
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3806
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1215
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:305
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10137
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3224
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:7861
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3381
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3411
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12396
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1176
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:932
SCIP_Real flushedrhs
Definition: struct_lp.h:207
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition: lp.c:17459
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:17384
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:13433
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:166
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:17012
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:1084
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:4488
#define SCIP_REAL_MAX
Definition: def.h:187
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5382
SCIP_Real maxval
Definition: struct_lp.h:211
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6945
SCIP_Real minactivity
Definition: struct_lp.h:217
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6623
SCIP_Real rhs
Definition: struct_lp.h:205
static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13564
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:11272
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:63
SCIP_Real constant
Definition: struct_lp.h:203
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2736
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7728
#define checkRowObjprod(row)
Definition: lp.c:770
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13161
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16384
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8167
datastructures for storing and manipulating the main problem
SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13335
unsigned int removable
Definition: struct_lp.h:261
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lp.c:581
unsigned int lhschanged
Definition: struct_lp.h:255
SCIP_Real * r
Definition: circlepacking.c:59
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2621
#define EPSLT(x, y, eps)
Definition: def.h:212
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:170
methods for sorting joint arrays of various types
SCIP_COL ** lazycols
Definition: struct_lp.h:302
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:1466
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:2329
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:278
#define EPSGT(x, y, eps)
Definition: def.h:214
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17261
int sbitlim
Definition: struct_lp.h:175
static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15502
SCIP_VAR ** b
Definition: circlepacking.c:65
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13181
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1957
SCIP_Real lpimarkowitz
Definition: struct_lp.h:291
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:17129
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6853
int age
Definition: struct_lp.h:177
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:219
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3420
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:159
void SCIPconsCapture(SCIP_CONS *cons)
Definition: cons.c:6196
SCIP_Real * vals
Definition: struct_lp.h:162
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6602
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2832
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:379
SCIP_Real rellooseobjval
Definition: struct_lp.h:274
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:118
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2018
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17045
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8980
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10205
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static const SCIP_Real scalars[]
Definition: lp.c:5747
int lpipos
Definition: struct_lp.h:173
int chgcolssize
Definition: struct_lp.h:322
int lpitiming
Definition: struct_lp.h:348
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:633
SCIP_Longint domchgcount
Definition: struct_stat.h:114
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:224
SCIP_Real * divechgsides
Definition: struct_lp.h:306
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:17537
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8738
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1633
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1740
SCIP_Real rootlpobjval
Definition: struct_lp.h:282
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1846
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:152
unsigned int coefchanged
Definition: struct_lp.h:257
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:160
SCIP_Longint nbarrierlps
Definition: struct_stat.h:199
SCIP_Bool flushed
Definition: struct_lp.h:366
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8528
SCIP_CLOCK * primallptime
Definition: struct_stat.h:164
SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18918
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13841
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6580
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:148
int lpdepth
Definition: struct_lp.h:174
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2556
unsigned int inglobalcutpool
Definition: struct_lp.h:262
int nrows
Definition: struct_lp.h:334
#define checkRowSqrnorm(row)
Definition: lp.c:768
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:15578
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:193
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14076
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:191
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3349
data structures for LP management
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4775
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:399
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:239
SCIP_VAR * a
Definition: circlepacking.c:66
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:618
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6258
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6291
datastructures for problem variables
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1686
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17186
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17383
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2690
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17504
int ndivingrows
Definition: struct_lp.h:341
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Longint divenolddomchgs
Definition: struct_lp.h:315
SCIP_Real lpobjval
Definition: struct_lp.h:271
static SCIP_RETCODE lpPrimalSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition: lp.c:10325
SCIP_Real primsol
Definition: struct_lp.h:95
#define SCIP_Real
Definition: def.h:186
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:124
SCIP_VAR ** vars
Definition: struct_prob.h:64
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2521
SCIP_Real flushedobj
Definition: struct_lp.h:145
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17810
int size
Definition: struct_lp.h:168
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7804
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6734
SCIP_Longint validsblp
Definition: struct_lp.h:165
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:4038
SCIP_Real lpiobjlim
Definition: struct_lp.h:286
SCIP_VAR ** y
Definition: circlepacking.c:64
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:6132
#define SCIPsetDebugMsgPrint
Definition: set.h:1771
int lpirowssize
Definition: struct_lp.h:319
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: lp.c:5114
int nunlinked
Definition: struct_lp.h:171
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4165
#define BMSallocMemory(ptr)
Definition: memory.h:120
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14312
#define SCIP_INVALID
Definition: def.h:206
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:129
internal methods for constraints and constraint handlers
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5702
SCIP_Real primsol
Definition: struct_lp.h:148
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17800
SCIP_CLOCK * duallptime
Definition: struct_stat.h:165
SCIP_Real maxprimsol
Definition: struct_lp.h:152
#define SCIP_Longint
Definition: def.h:171
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18035
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6934
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10302
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3054
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17515
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14994
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:65
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2995
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:5751
#define SCIPisFinite(x)
Definition: pub_misc.h:1901
SCIP_Real varconsratio
Definition: struct_lp.h:295
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:357
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6679
SCIP_VAR * var
Definition: struct_lp.h:160
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9902
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7882
int nlazycols
Definition: struct_lp.h:330
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1240
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:17364
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:349
SCIP_Bool dualfeasible
Definition: struct_lp.h:370
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6675
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4139
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6228
static SCIP_RETCODE ignoreInstability(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool *success)
Definition: lp.c:11554
unsigned int nlocks
Definition: struct_lp.h:264
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2895
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17989
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:453
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_clp.cpp:3895
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2720
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6956
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3439
SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18907
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3980
SCIP_Longint obsoletenode
Definition: struct_lp.h:158
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:950
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:132
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9927
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14188
SCIP_Longint obsoletenode
Definition: struct_lp.h:221
SCIP_Longint nnodes
Definition: struct_stat.h:82
SCIP_Real lpifeastol
Definition: struct_lp.h:287
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13375
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:927
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:439
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4268
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14052
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, int scaling, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:11583
SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18827
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:1496
#define SCIP_CALL_ABORT(x)
Definition: def.h:373
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3203
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17635
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:17022
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:5413
SCIP_Bool primalfeasible
Definition: struct_lp.h:120
unsigned int validminmaxidx
Definition: struct_lp.h:254
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3956
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3241
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:14351
#define SCIP_ALLOC(x)
Definition: def.h:405
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:13150
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6399
#define SCIPABORT()
Definition: def.h:366
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2920
SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7180
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:214
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:353
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:2244
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:17143
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6846
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2518
unsigned int nonlpcolssorted
Definition: struct_lp.h:252
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:17096
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17455
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:454
SCIP_Bool flushaddedcols
Definition: struct_lp.h:362
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:10674
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17558
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:359
static SCIP_RETCODE lpDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition: lp.c:10483
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9032
int ncols
Definition: struct_lp.h:328
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2610
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4199
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:17271
SCIP_Real lpobjval
Definition: struct_lp.h:119
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17881
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:460
SCIP_Real objsqrnorm
Definition: struct_lp.h:292
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition: set.c:6142
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1364
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3666
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17118
unsigned int local
Definition: struct_lp.h:259
#define EPSZ(x, eps)
Definition: def.h:216
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1647
SCIP_Real activity
Definition: struct_lp.h:214
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3796
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5263
SCIP_Bool probing
Definition: struct_lp.h:378
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:363
SCIP_Real looseobjval
Definition: struct_lp.h:272
int len
Definition: struct_lp.h:235
int age
Definition: struct_lp.h:247
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7792
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6745
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3256
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9584
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition: lp.c:17065
SCIP_Real flushedlhs
Definition: struct_lp.h:206
static SCIP_RETCODE lpAlgorithm(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:11409
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:868
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:5644
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:957
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5397
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:4193
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:4034
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:290
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3169
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17494
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:67
#define checkRowSumnorm(row)
Definition: lp.c:769