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-2024 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 */
2353  SCIP_COL* col, /**< column data */
2354  BMS_BLKMEM* blkmem, /**< block memory */
2355  SCIP_SET* set, /**< global SCIP settings */
2356  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2357  SCIP_LP* lp /**< current LP data */
2358  )
2359 {
2360  int i;
2361 
2362  assert(col != NULL);
2363  assert(col->var != NULL);
2364  assert(blkmem != NULL);
2365  assert(set != NULL);
2366  assert(lp != NULL);
2367 
2368  if( col->nunlinked > 0 )
2369  {
2370  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2371 
2372  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2373  for( i = col->nlprows; i < col->len; ++i )
2374  {
2375  assert(!SCIPsetIsZero(set, col->vals[i]));
2376  if( col->linkpos[i] == -1 )
2377  {
2378  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2379  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2380  }
2381  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2382  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2383  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2384  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2385  }
2386  }
2387  assert(col->nunlinked == 0);
2388 
2389  checkLinks(lp);
2390 
2391  return SCIP_OKAY;
2392 }
2393 
2394 /** removes column coefficients from corresponding rows */
2396  SCIP_COL* col, /**< column data */
2397  BMS_BLKMEM* blkmem, /**< block memory */
2398  SCIP_SET* set, /**< global SCIP settings */
2399  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2400  SCIP_LP* lp /**< current LP data */
2401  )
2402 {
2403  int i;
2404 
2405  assert(col != NULL);
2406  assert(col->var != NULL);
2407  assert(blkmem != NULL);
2408  assert(set != NULL);
2409  assert(lp != NULL);
2410 
2411  if( col->nunlinked < col->len )
2412  {
2413  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2414  for( i = 0; i < col->len; ++i )
2415  {
2416  if( col->linkpos[i] >= 0 )
2417  {
2418  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2419  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2420  col->linkpos[i] = -1;
2421  col->nunlinked++;
2422  }
2423  }
2424  }
2425  assert(col->nunlinked == col->len);
2426 
2427  checkLinks(lp);
2428 
2429  return SCIP_OKAY;
2430 }
2431 
2432 /** insert row coefficients in corresponding columns */
2434  SCIP_ROW* row, /**< row data */
2435  BMS_BLKMEM* blkmem, /**< block memory */
2436  SCIP_SET* set, /**< global SCIP settings */
2437  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2438  SCIP_LP* lp /**< current LP data */
2439  )
2440 {
2441  int i;
2442 
2443  assert(row != NULL);
2444  assert(blkmem != NULL);
2445  assert(set != NULL);
2446  assert(lp != NULL);
2447 
2448  if( row->nunlinked > 0 )
2449  {
2450  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2451 
2452  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2453  for( i = row->nlpcols; i < row->len; ++i )
2454  {
2455  assert(!SCIPsetIsZero(set, row->vals[i]));
2456  if( row->linkpos[i] == -1 )
2457  {
2458  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2459  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2460  }
2461  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2462  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2463  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2464  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2465  }
2466  }
2467  assert(row->nunlinked == 0);
2468 
2469  checkLinks(lp);
2470 
2471  return SCIP_OKAY;
2472 }
2473 
2474 /** removes row coefficients from corresponding columns */
2476  SCIP_ROW* row, /**< row data */
2477  SCIP_SET* set, /**< global SCIP settings */
2478  SCIP_LP* lp /**< current LP data */
2479  )
2480 {
2481  int i;
2482 
2483  assert(row != NULL);
2484  assert(set != NULL);
2485  assert(lp != NULL);
2486 
2487  if( row->nunlinked < row->len )
2488  {
2489  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2490  for( i = 0; i < row->len; ++i )
2491  {
2492  if( row->linkpos[i] >= 0 )
2493  {
2494  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2495  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2496  row->nunlinked++;
2497  }
2498  }
2499  }
2500  assert(row->nunlinked == row->len);
2501 
2502  return SCIP_OKAY;
2503 }
2504 
2505 
2506 
2507 
2508 /*
2509  * local LP parameter methods
2510  */
2511 
2512 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2513 static
2515  SCIP_LP* lp, /**< current LP data */
2516  SCIP_LPPARAM lpparam, /**< LP parameter */
2517  int value, /**< value to set parameter to */
2518  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2519  )
2520 {
2521  SCIP_RETCODE retcode;
2522 
2523  assert(lp != NULL);
2524  assert(success != NULL);
2525 
2526  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2527 
2528  /* check, if parameter is unknown */
2529  if( retcode == SCIP_PARAMETERUNKNOWN )
2530  {
2531  *success = FALSE;
2532  return SCIP_OKAY;
2533  }
2534  *success = TRUE;
2535 
2536  return retcode;
2537 }
2538 
2539 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2540 static
2542  SCIP_LP* lp, /**< current LP data */
2543  SCIP_LPPARAM lpparam, /**< LP parameter */
2544  SCIP_Bool value, /**< value to set parameter to */
2545  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2546  )
2547 {
2548  return lpSetIntpar(lp, lpparam, (int)value, success);
2549 }
2550 
2551 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2552 static
2554  SCIP_LP* lp, /**< current LP data */
2555  SCIP_LPPARAM lpparam, /**< LP parameter */
2556  SCIP_Real value, /**< value to set parameter to */
2557  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2558  )
2559 {
2560  SCIP_RETCODE retcode;
2561 
2562  assert(lp != NULL);
2563  assert(success != NULL);
2564 
2565  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2566 
2567  /* check, if parameter is unknown */
2568  if( retcode == SCIP_PARAMETERUNKNOWN )
2569  {
2570  *success = FALSE;
2571  return SCIP_OKAY;
2572  }
2573  *success = TRUE;
2574 
2575  return retcode;
2576 }
2577 
2578 #ifndef NDEBUG
2579 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2580 static
2582  SCIP_LP* lp, /**< current LP data */
2583  SCIP_LPPARAM lpparam, /**< LP parameter */
2584  int value /**< value parameter should have */
2585  )
2586 {
2587  SCIP_RETCODE retcode;
2588  int lpivalue;
2589 
2590  assert(lp != NULL);
2591 
2592  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2593 
2594  /* ignore unknown parameter error */
2595  if( retcode == SCIP_PARAMETERUNKNOWN )
2596  return SCIP_OKAY;
2597 
2598  /* check value */
2599  assert(lpivalue == value);
2600 
2601  return retcode;
2602 }
2603 
2604 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2605 static
2607  SCIP_LP* lp, /**< current LP data */
2608  SCIP_LPPARAM lpparam, /**< LP parameter */
2609  SCIP_Bool value /**< value parameter should have */
2610  )
2611 {
2612  return lpCheckIntpar(lp, lpparam, (int)value);
2613 }
2614 
2615 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2616 static
2618  SCIP_LP* lp, /**< current LP data */
2619  SCIP_LPPARAM lpparam, /**< LP parameter */
2620  SCIP_Real value /**< value parameter should have */
2621  )
2622 {
2623  SCIP_RETCODE retcode;
2624  SCIP_Real lpivalue;
2625 
2626  assert(lp != NULL);
2627 
2628  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2629 
2630  /* ignore unknown parameter error */
2631  if( retcode == SCIP_PARAMETERUNKNOWN )
2632  return SCIP_OKAY;
2633 
2634  /* check value */
2635  assert(lpivalue == value); /*lint !e777*/
2636 
2637  return retcode;
2638 }
2639 #else
2640 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2641 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2642 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2643 #endif
2644 
2645 /** should the objective limit of the LP solver be disabled */
2646 #define lpCutoffDisabled(set,prob) (set->lp_disablecutoff == 1 || ((set->nactivepricers > 0 || !SCIPprobAllColsInLP(prob, set, lp)) && set->lp_disablecutoff == 2))
2647 
2648 /** sets the objective limit of the LP solver
2649  *
2650  * Note that we are always minimizing.
2651  */
2652 static
2654  SCIP_LP* lp, /**< current LP data */
2655  SCIP_SET* set, /**< global SCIP settings */
2656  SCIP_PROB* prob, /**< problem data */
2657  SCIP_Real objlim, /**< new objective limit */
2658  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2659  )
2660 {
2661  assert(lp != NULL);
2662  assert(set != NULL);
2663  assert(success != NULL);
2664 
2665  *success = FALSE;
2666 
2667  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2668  * solver's objective limit handling, so we make sure that the objective limit is inactive (infinity). */
2669  if( lpCutoffDisabled(set, prob) || set->misc_exactsolve )
2670  objlim = SCIPlpiInfinity(lp->lpi);
2671 
2672  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2673  if( SCIPsetIsInfinity(set, objlim) )
2674  objlim = SCIPlpiInfinity(lp->lpi);
2675 
2677 
2678  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2679  {
2680  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2681  if( *success )
2682  {
2683  SCIP_Real actualobjlim;
2684 
2685  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2686  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2687  if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2688  {
2689  /* mark the current solution invalid */
2690  lp->solved = FALSE;
2691  lp->primalfeasible = FALSE;
2692  lp->primalchecked = FALSE;
2693  lp->lpobjval = SCIP_INVALID;
2695  }
2696  lp->lpiobjlim = actualobjlim;
2697  }
2698  }
2699 
2700  return SCIP_OKAY;
2701 }
2702 
2703 /** sets the feasibility tolerance of the LP solver */
2704 static
2706  SCIP_LP* lp, /**< current LP data */
2707  SCIP_Real feastol, /**< new feasibility tolerance */
2708  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2709  )
2710 {
2711  assert(lp != NULL);
2712  assert(feastol >= 0.0);
2713  assert(success != NULL);
2714 
2716 
2717  if( feastol != lp->lpifeastol ) /*lint !e777*/
2718  {
2719  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2720  if( *success )
2721  {
2722  SCIP_Real actualfeastol;
2723 
2724  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2725  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2726  if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2727  {
2728  /* mark the current solution invalid */
2729  lp->solved = FALSE;
2730  lp->primalfeasible = FALSE;
2731  lp->primalchecked = FALSE;
2732  lp->lpobjval = SCIP_INVALID;
2734  }
2735  else
2736  *success = FALSE;
2737  lp->lpifeastol = actualfeastol;
2738  }
2739  }
2740  else
2741  *success = FALSE;
2742 
2743  return SCIP_OKAY;
2744 }
2745 
2746 /** sets the reduced costs feasibility tolerance of the LP solver */
2747 static
2749  SCIP_LP* lp, /**< current LP data */
2750  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2751  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2752  )
2753 {
2754  assert(lp != NULL);
2755  assert(dualfeastol >= 0.0);
2756  assert(success != NULL);
2757 
2759 
2760  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2761  {
2762  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2763  if( *success )
2764  {
2765  SCIP_Real actualdualfeastol;
2766 
2767  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2768  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2769  if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2770  {
2771  /* mark the current solution invalid */
2772  lp->solved = FALSE;
2773  lp->dualfeasible = FALSE;
2774  lp->dualchecked = FALSE;
2775  lp->lpobjval = SCIP_INVALID;
2777  }
2778  else
2779  *success = FALSE;
2780  lp->lpidualfeastol = actualdualfeastol;
2781  }
2782  }
2783  else
2784  *success = FALSE;
2785 
2786  return SCIP_OKAY;
2787 }
2788 
2789 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2790 static
2792  SCIP_LP* lp, /**< current LP data */
2793  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2794  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2795  )
2796 {
2797  assert(lp != NULL);
2798  assert(barrierconvtol >= 0.0);
2799  assert(success != NULL);
2800 
2802 
2803  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2804  {
2805  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2806  if( *success )
2807  {
2808  SCIP_Real actualbarrierconvtol;
2809 
2810  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2811  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
2812  if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
2814  {
2815  /* mark the current solution invalid */
2816  lp->solved = FALSE;
2817  lp->dualfeasible = FALSE;
2818  lp->dualchecked = FALSE;
2819  lp->lpobjval = SCIP_INVALID;
2821  }
2822  else
2823  *success = FALSE;
2824  lp->lpibarrierconvtol = actualbarrierconvtol;
2825  }
2826  }
2827  else
2828  *success = FALSE;
2829 
2830  return SCIP_OKAY;
2831 }
2832 
2833 /** sets the FROMSCRATCH setting of the LP solver */
2834 static
2836  SCIP_LP* lp, /**< current LP data */
2837  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2838  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2839  )
2840 {
2841  assert(lp != NULL);
2842  assert(success != NULL);
2843 
2845 
2846  if( fromscratch != lp->lpifromscratch )
2847  {
2848  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2849  if( *success )
2850  lp->lpifromscratch = fromscratch;
2851  }
2852  else
2853  *success = FALSE;
2854 
2855  return SCIP_OKAY;
2856 }
2857 
2858 /** sets the FASTMIP setting of the LP solver */
2859 static
2861  SCIP_LP* lp, /**< current LP data */
2862  int fastmip, /**< new FASTMIP setting */
2863  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2864  )
2865 {
2866  assert(lp != NULL);
2867  assert(success != NULL);
2868  assert(0 <= fastmip && fastmip <= 1);
2869 
2871 
2872  if( fastmip != lp->lpifastmip )
2873  {
2874  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2875  if( *success )
2876  {
2877  lp->lpifastmip = fastmip;
2878  lp->solved = FALSE;
2879  /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
2880  * demanding setting; however, in the current code, this should have not effect. */
2881  }
2882  }
2883  else
2884  *success = FALSE;
2885 
2886  return SCIP_OKAY;
2887 }
2888 
2889 /** sets the SCALING setting of the LP solver */
2890 static
2892  SCIP_LP* lp, /**< current LP data */
2893  int scaling, /**< new SCALING setting */
2894  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2895  )
2896 {
2897  assert(lp != NULL);
2898  assert(success != NULL);
2899 
2901 
2902  if( scaling != lp->lpiscaling )
2903  {
2904  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2905  if( *success )
2906  lp->lpiscaling = scaling;
2907  }
2908  else
2909  *success = FALSE;
2910 
2911  return SCIP_OKAY;
2912 }
2913 
2914 /** sets the number of THREADS of the LP solver */
2915 static
2917  SCIP_LP* lp, /**< current LP data */
2918  int threads, /**< new number of threads used to solve the LP */
2919  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2920  )
2921 {
2922  assert(lp != NULL);
2923  assert(success != NULL);
2924 
2926 
2927  if( threads != lp->lpithreads )
2928  {
2929  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2930  if( *success )
2931  lp->lpithreads = threads;
2932  }
2933  else
2934  *success = FALSE;
2935 
2936  return SCIP_OKAY;
2937 }
2938 
2939 /** sets the PRESOLVING setting of the LP solver */
2940 static
2942  SCIP_LP* lp, /**< current LP data */
2943  SCIP_Bool presolving, /**< new PRESOLVING setting */
2944  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2945  )
2946 {
2947  assert(lp != NULL);
2948  assert(success != NULL);
2949 
2951 
2952  if( presolving != lp->lpipresolving )
2953  {
2954  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2955  if( *success )
2956  lp->lpipresolving = presolving;
2957  }
2958  else
2959  *success = FALSE;
2960 
2961  return SCIP_OKAY;
2962 }
2963 
2964 /** sets the ROWREPSWITCH setting of the LP solver */
2965 static
2967  SCIP_LP* lp, /**< current LP data */
2968  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2969  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2970  )
2971 {
2972  assert(lp != NULL);
2973  assert(success != NULL);
2974 
2976 
2977  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2978  {
2979  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2980  if( *success )
2981  lp->lpirowrepswitch = rowrepswitch;
2982  }
2983  else
2984  *success = FALSE;
2985 
2986  return SCIP_OKAY;
2987 }
2988 
2989 /** sets the iteration limit of the LP solver */
2990 static
2992  SCIP_LP* lp, /**< current LP data */
2993  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2994  )
2995 {
2996  SCIP_Bool success;
2997 
2998  assert(lp != NULL);
2999  assert(itlim >= -1);
3000 
3001  if( itlim == -1 )
3002  itlim = INT_MAX;
3003 
3005 
3006  if( itlim != lp->lpiitlim )
3007  {
3008  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
3009  if( success )
3010  {
3011  if( itlim > lp->lpiitlim )
3012  {
3013  /* mark the current solution invalid */
3014  lp->solved = FALSE;
3015  lp->lpobjval = SCIP_INVALID;
3017  }
3018  lp->lpiitlim = itlim;
3019  }
3020  }
3021 
3022  return SCIP_OKAY;
3023 }
3024 
3025 /** sets the pricing strategy of the LP solver */
3026 static
3028  SCIP_LP* lp, /**< current LP data */
3029  SCIP_PRICING pricing /**< pricing strategy */
3030  )
3031 {
3032  SCIP_Bool success;
3033 
3034  assert(lp != NULL);
3035 
3037 
3038  if( pricing != lp->lpipricing )
3039  {
3040  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3041  if( success )
3042  lp->lpipricing = pricing;
3043  }
3044 
3045  return SCIP_OKAY;
3046 }
3047 
3048 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3049 static
3051  SCIP_LP* lp, /**< current LP data */
3052  char pricingchar /**< character representing the pricing strategy */
3053  )
3054 {
3055  SCIP_PRICING pricing;
3056 
3057  switch( pricingchar )
3058  {
3059  case 'l':
3060  pricing = SCIP_PRICING_LPIDEFAULT;
3061  break;
3062  case 'a':
3063  pricing = SCIP_PRICING_AUTO;
3064  break;
3065  case 'f':
3066  pricing = SCIP_PRICING_FULL;
3067  break;
3068  case 'p':
3069  pricing = SCIP_PRICING_PARTIAL;
3070  break;
3071  case 's':
3072  pricing = SCIP_PRICING_STEEP;
3073  break;
3074  case 'q':
3075  pricing = SCIP_PRICING_STEEPQSTART;
3076  break;
3077  case 'd':
3078  pricing = SCIP_PRICING_DEVEX;
3079  break;
3080  default:
3081  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3082  return SCIP_INVALIDDATA;
3083  }
3084 
3085  SCIP_CALL( lpSetPricing(lp, pricing) );
3086 
3087  return SCIP_OKAY;
3088 }
3089 
3090 /** sets the verbosity of the LP solver */
3091 static
3093  SCIP_LP* lp, /**< current LP data */
3094  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3095  )
3096 {
3097  SCIP_Bool success;
3098 
3099  assert(lp != NULL);
3100 
3102 
3103  if( lpinfo != lp->lpilpinfo )
3104  {
3105  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3106  if( success )
3107  lp->lpilpinfo = lpinfo;
3108  }
3109 
3110  return SCIP_OKAY;
3111 }
3112 
3113 /** sets the CONDITIONLIMIT setting of the LP solver */
3114 static
3116  SCIP_LP* lp, /**< current LP data */
3117  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3118  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3119  )
3120 {
3121  assert(lp != NULL);
3122  assert(success != NULL);
3123 
3125 
3126  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3127  {
3128  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3129  if( *success )
3130  lp->lpiconditionlimit = condlimit;
3131  }
3132  else
3133  *success = FALSE;
3134 
3135  return SCIP_OKAY;
3136 }
3137 
3138 /** sets the MARKOWITZ setting of the LP solver */
3139 static
3141  SCIP_LP* lp, /**< current LP data */
3142  SCIP_Real threshhold, /**< new MARKOWITZ value */
3143  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3144  )
3145 {
3146  assert(lp != NULL);
3147  assert(success != NULL);
3148 
3150 
3151  if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3152  {
3153  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3154  if( *success )
3155  lp->lpimarkowitz = threshhold;
3156  }
3157  else
3158  *success = FALSE;
3159 
3160  return SCIP_OKAY;
3161 }
3162 
3163 /** sets the type of timer of the LP solver */
3164 static
3166  SCIP_LP* lp, /**< current LP data */
3167  SCIP_CLOCKTYPE timing, /**< new timing value */
3168  SCIP_Bool enabled, /**< is timing enabled? */
3169  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3170  )
3171 {
3172  int lptiming;
3173 
3174  assert(lp != NULL);
3175  assert(success != NULL);
3176  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*//*lint !e1564*/
3177 
3179 
3180  if( !enabled )
3181  lptiming = 0;
3182  else
3183  lptiming = (int) timing;
3184 
3185  if( lptiming != lp->lpitiming ) /*lint !e777*/
3186  {
3187  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3188  if( *success )
3189  lp->lpitiming = lptiming;
3190  }
3191  else
3192  *success = FALSE;
3193 
3194  return SCIP_OKAY;
3195 }
3196 
3197 /** sets the initial random seed of the LP solver */
3198 static
3200  SCIP_LP* lp, /**< current LP data */
3201  int randomseed, /**< new initial random seed */
3202  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3203  )
3204 {
3205  assert(lp != NULL);
3206  assert(success != NULL);
3207 
3208  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3209 
3210  if( randomseed == 0 )
3211  {
3212  lp->lpirandomseed = randomseed;
3213  *success = TRUE;
3214  }
3215  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3216  {
3217  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3218  if( *success )
3219  lp->lpirandomseed = randomseed;
3220  }
3221  else
3222  *success = FALSE;
3223 
3224  return SCIP_OKAY;
3225 }
3226 
3227 /** sets the LP solution polishing method */
3228 static
3230  SCIP_LP* lp, /**< current LP data */
3231  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3232  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3233  )
3234 {
3235  assert(lp != NULL);
3236  assert(success != NULL);
3237 
3238  if( polishing != lp->lpisolutionpolishing )
3239  {
3240  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3241  if( *success )
3242  lp->lpisolutionpolishing = polishing;
3243  }
3244  else
3245  *success = FALSE;
3246 
3247  return SCIP_OKAY;
3248 }
3249 
3250 /** sets the LP refactorization interval */
3251 static
3253  SCIP_LP* lp, /**< current LP data */
3254  int refactor, /**< LP refactorization interval (0: automatic) */
3255  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3256  )
3257 {
3258  assert(lp != NULL);
3259  assert(success != NULL);
3260 
3261  if( refactor != lp->lpirefactorinterval )
3262  {
3263  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3264  if( *success )
3265  lp->lpirefactorinterval = refactor;
3266  }
3267  else
3268  *success = FALSE;
3269 
3270  return SCIP_OKAY;
3271 }
3272 
3273 
3274 /*
3275  * Column methods
3276  */
3277 
3278 /** creates an LP column */
3280  SCIP_COL** col, /**< pointer to column data */
3281  BMS_BLKMEM* blkmem, /**< block memory */
3282  SCIP_SET* set, /**< global SCIP settings */
3283  SCIP_STAT* stat, /**< problem statistics */
3284  SCIP_VAR* var, /**< variable, this column represents */
3285  int len, /**< number of nonzeros in the column */
3286  SCIP_ROW** rows, /**< array with rows of column entries */
3287  SCIP_Real* vals, /**< array with coefficients of column entries */
3288  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3289  )
3290 {
3291  int i;
3292 
3293  assert(col != NULL);
3294  assert(blkmem != NULL);
3295  assert(set != NULL);
3296  assert(stat != NULL);
3297  assert(var != NULL);
3298  assert(len >= 0);
3299  assert(len == 0 || (rows != NULL && vals != NULL));
3300 
3301  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3302 
3303  if( len > 0 )
3304  {
3305  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3306  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3307  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3308 
3309  for( i = 0; i < len; ++i )
3310  {
3311  assert(rows[i] != NULL);
3312  assert(!SCIPsetIsZero(set, vals[i]));
3313  (*col)->linkpos[i] = -1;
3314  }
3315  }
3316  else
3317  {
3318  (*col)->rows = NULL;
3319  (*col)->vals = NULL;
3320  (*col)->linkpos = NULL;
3321  }
3322 
3323  (*col)->var = var;
3324  (*col)->obj = SCIPvarGetObj(var);
3325  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3326  (*col)->lb = SCIPvarGetLbLocal(var);
3327  (*col)->ub = SCIPvarGetUbLocal(var);
3328  (*col)->flushedobj = 0.0;
3329  (*col)->flushedlb = 0.0;
3330  (*col)->flushedub = 0.0;
3331  (*col)->index = stat->ncolidx;
3332  SCIPstatIncrement(stat, set, ncolidx);
3333  (*col)->size = len;
3334  (*col)->len = len;
3335  (*col)->nlprows = 0;
3336  (*col)->nunlinked = len;
3337  (*col)->lppos = -1;
3338  (*col)->lpipos = -1;
3339  (*col)->lpdepth = -1;
3340  (*col)->primsol = 0.0;
3341  (*col)->redcost = SCIP_INVALID;
3342  (*col)->farkascoef = SCIP_INVALID;
3343  (*col)->minprimsol = (*col)->ub;
3344  (*col)->maxprimsol = (*col)->lb;
3345  (*col)->sbdown = SCIP_INVALID;
3346  (*col)->sbup = SCIP_INVALID;
3347  (*col)->sbsolval = SCIP_INVALID;
3348  (*col)->sblpobjval = SCIP_INVALID;
3349  (*col)->sbnode = -1;
3350  (*col)->validredcostlp = -1;
3351  (*col)->validfarkaslp = -1;
3352  (*col)->validsblp = -1;
3353  (*col)->sbitlim = -1;
3354  (*col)->nsbcalls = 0;
3355  (*col)->age = 0;
3356  (*col)->obsoletenode = -1;
3357  (*col)->var_probindex = SCIPvarGetProbindex(var);
3358  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3359  (*col)->lprowssorted = TRUE;
3360  (*col)->nonlprowssorted = (len <= 1);
3361  (*col)->objchanged = FALSE;
3362  (*col)->lbchanged = FALSE;
3363  (*col)->ubchanged = FALSE;
3364  (*col)->coefchanged = FALSE;
3365  (*col)->integral = SCIPvarIsIntegral(var);
3366  (*col)->removable = removable;
3367  (*col)->sbdownvalid = FALSE;
3368  (*col)->sbupvalid = FALSE;
3369  (*col)->lazylb = SCIPvarGetLbLazy(var);
3370  (*col)->lazyub = SCIPvarGetUbLazy(var);
3371  (*col)->storedsolvals = NULL;
3372 
3373  return SCIP_OKAY;
3374 }
3375 
3376 /** frees an LP column */
3378  SCIP_COL** col, /**< pointer to LP column */
3379  BMS_BLKMEM* blkmem, /**< block memory */
3380  SCIP_SET* set, /**< global SCIP settings */
3381  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3382  SCIP_LP* lp /**< current LP data */
3383  )
3384 {
3385  assert(blkmem != NULL);
3386  assert(col != NULL);
3387  assert(*col != NULL);
3388  assert((*col)->var != NULL);
3389  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3390  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3391  assert((*col)->lppos == -1);
3392  assert((*col)->lpipos == -1);
3393 
3394  /* remove column indices from corresponding rows */
3395  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3396 
3397  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3398  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3399  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3400  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3401  BMSfreeBlockMemory(blkmem, col);
3402 
3403  return SCIP_OKAY;
3404 }
3405 
3406 /** output column to file stream */
3408  SCIP_COL* col, /**< LP column */
3409  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3410  FILE* file /**< output file (or NULL for standard output) */
3411  )
3412 {
3413  int r;
3414 
3415  assert(col != NULL);
3416  assert(col->var != NULL);
3417 
3418  /* print bounds */
3419  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3420 
3421  /* print coefficients */
3422  if( col->len == 0 )
3423  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3424  for( r = 0; r < col->len; ++r )
3425  {
3426  assert(col->rows[r] != NULL);
3427  assert(col->rows[r]->name != NULL);
3428  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3429  }
3430  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3431 }
3432 
3433 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3434  */
3436  SCIP_COL* col /**< column to be sorted */
3437  )
3438 {
3439  /* sort LP rows */
3440  colSortLP(col);
3441 
3442  /* sort non-LP rows */
3443  colSortNonLP(col);
3444 }
3445 
3446 /** adds a previously non existing coefficient to an LP column */
3448  SCIP_COL* col, /**< LP column */
3449  BMS_BLKMEM* blkmem, /**< block memory */
3450  SCIP_SET* set, /**< global SCIP settings */
3451  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3452  SCIP_LP* lp, /**< current LP data */
3453  SCIP_ROW* row, /**< LP row */
3454  SCIP_Real val /**< value of coefficient */
3455  )
3456 {
3457  assert(lp != NULL);
3458  assert(!lp->diving);
3459 
3460  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3461 
3462  checkLinks(lp);
3463 
3464  return SCIP_OKAY;
3465 }
3466 
3467 /** deletes existing coefficient from column */
3469  SCIP_COL* col, /**< column to be changed */
3470  BMS_BLKMEM* blkmem, /**< block memory */
3471  SCIP_SET* set, /**< global SCIP settings */
3472  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3473  SCIP_LP* lp, /**< current LP data */
3474  SCIP_ROW* row /**< coefficient to be deleted */
3475  )
3476 {
3477  int pos;
3478 
3479  assert(col != NULL);
3480  assert(col->var != NULL);
3481  assert(lp != NULL);
3482  assert(!lp->diving);
3483  assert(row != NULL);
3484 
3485  /* search the position of the row in the column's row vector */
3486  pos = colSearchCoef(col, row);
3487  if( pos == -1 )
3488  {
3489  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3490  return SCIP_INVALIDDATA;
3491  }
3492  assert(0 <= pos && pos < col->len);
3493  assert(col->rows[pos] == row);
3494 
3495  /* if row knows of the column, remove the column from the row's col vector */
3496  if( col->linkpos[pos] >= 0 )
3497  {
3498  assert(row->cols[col->linkpos[pos]] == col);
3499  assert(row->cols_index[col->linkpos[pos]] == col->index);
3500  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3501  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3502  }
3503 
3504  /* delete the row from the column's row vector */
3505  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3506 
3507  checkLinks(lp);
3508 
3509  return SCIP_OKAY;
3510 }
3511 
3512 /** changes or adds a coefficient to an LP column */
3514  SCIP_COL* col, /**< LP column */
3515  BMS_BLKMEM* blkmem, /**< block memory */
3516  SCIP_SET* set, /**< global SCIP settings */
3517  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3518  SCIP_LP* lp, /**< current LP data */
3519  SCIP_ROW* row, /**< LP row */
3520  SCIP_Real val /**< value of coefficient */
3521  )
3522 {
3523  int pos;
3524 
3525  assert(col != NULL);
3526  assert(lp != NULL);
3527  assert(!lp->diving);
3528  assert(row != NULL);
3529 
3530  /* search the position of the row in the column's row vector */
3531  pos = colSearchCoef(col, row);
3532 
3533  /* check, if row already exists in the column's row vector */
3534  if( pos == -1 )
3535  {
3536  /* add previously not existing coefficient */
3537  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3538  }
3539  else
3540  {
3541  /* modify already existing coefficient */
3542  assert(0 <= pos && pos < col->len);
3543  assert(col->rows[pos] == row);
3544 
3545  /* if row knows of the column, change the corresponding coefficient in the row */
3546  if( col->linkpos[pos] >= 0 )
3547  {
3548  assert(row->cols[col->linkpos[pos]] == col);
3549  assert(row->cols_index[col->linkpos[pos]] == col->index);
3550  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3551  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3552  }
3553 
3554  /* change the coefficient in the column */
3555  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3556  }
3557 
3558  checkLinks(lp);
3559 
3560  return SCIP_OKAY;
3561 }
3562 
3563 /** increases value of an existing or non-existing coefficient in an LP column */
3565  SCIP_COL* col, /**< LP column */
3566  BMS_BLKMEM* blkmem, /**< block memory */
3567  SCIP_SET* set, /**< global SCIP settings */
3568  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3569  SCIP_LP* lp, /**< current LP data */
3570  SCIP_ROW* row, /**< LP row */
3571  SCIP_Real incval /**< value to add to the coefficient */
3572  )
3573 {
3574  int pos;
3575 
3576  assert(col != NULL);
3577  assert(lp != NULL);
3578  assert(!lp->diving);
3579  assert(row != NULL);
3580 
3581  if( SCIPsetIsZero(set, incval) )
3582  return SCIP_OKAY;
3583 
3584  /* search the position of the row in the column's row vector */
3585  pos = colSearchCoef(col, row);
3586 
3587  /* check, if row already exists in the column's row vector */
3588  if( pos == -1 )
3589  {
3590  /* add previously not existing coefficient */
3591  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3592  }
3593  else
3594  {
3595  /* modify already existing coefficient */
3596  assert(0 <= pos && pos < col->len);
3597  assert(col->rows[pos] == row);
3598 
3599  /* if row knows of the column, change the corresponding coefficient in the row */
3600  if( col->linkpos[pos] >= 0 )
3601  {
3602  assert(row->cols[col->linkpos[pos]] == col);
3603  assert(row->cols_index[col->linkpos[pos]] == col->index);
3604  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3605  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3606  }
3607 
3608  /* change the coefficient in the column */
3609  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3610  }
3611 
3612  checkLinks(lp);
3613 
3614  return SCIP_OKAY;
3615 }
3616 
3617 /** insert column in the chgcols list (if not already there) */
3618 static
3620  SCIP_COL* col, /**< LP column to change */
3621  SCIP_SET* set, /**< global SCIP settings */
3622  SCIP_LP* lp /**< current LP data */
3623  )
3624 {
3625  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3626  {
3627  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3628  lp->chgcols[lp->nchgcols] = col;
3629  lp->nchgcols++;
3630  }
3631 
3632  /* mark the current LP unflushed */
3633  lp->flushed = FALSE;
3634 
3635  return SCIP_OKAY;
3636 }
3637 
3638 /** Is the new value reliable or may we have cancellation?
3639  *
3640  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3641  * cancellations which can occur during increasing the oldvalue to the newvalue
3642  */
3643 static
3645  SCIP_SET* set, /**< global SCIP settings */
3646  SCIP_Real newvalue, /**< new value */
3647  SCIP_Real oldvalue /**< old reliable value */
3648  )
3649 {
3650  SCIP_Real quotient;
3651 
3652  assert(set != NULL);
3653  assert(oldvalue != SCIP_INVALID); /*lint !e777*/
3654 
3655  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3656 
3657  return SCIPsetIsZero(set, quotient);
3658 }
3659 
3660 /** update norms of objective function vector */
3661 static
3663  SCIP_LP* lp, /**< current LP data */
3664  SCIP_SET* set, /**< global SCIP settings */
3665  SCIP_Real oldobj, /**< old objective value of variable */
3666  SCIP_Real newobj /**< new objective value of variable */
3667  )
3668 {
3669  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3670  {
3671  if( !lp->objsqrnormunreliable )
3672  {
3673  SCIP_Real oldvalue;
3674 
3675  oldvalue = lp->objsqrnorm;
3676  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3677 
3678  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3679  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3680  lp->objsqrnormunreliable = TRUE;
3681  else
3682  {
3683  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3684 
3685  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3686  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3687 
3688  assert(lp->objsqrnorm >= 0.0);
3689  }
3690  }
3691 
3692  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3693  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3694  }
3695 }
3696 
3697 /** changes objective value of column */
3699  SCIP_COL* col, /**< LP column to change */
3700  SCIP_SET* set, /**< global SCIP settings */
3701  SCIP_LP* lp, /**< current LP data */
3702  SCIP_Real newobj /**< new objective value */
3703  )
3704 {
3705  assert(col != NULL);
3706  assert(col->var != NULL);
3707  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3708  assert(SCIPvarGetCol(col->var) == col);
3709  assert(lp != NULL);
3710 
3711  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3712 
3713  /* only add actual changes */
3714  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3715  {
3716  /* only variables with a real position in the LPI can be inserted */
3717  if( col->lpipos >= 0 )
3718  {
3719  /* insert column in the chgcols list (if not already there) */
3720  SCIP_CALL( insertColChgcols(col, set, lp) );
3721 
3722  /* mark objective value change in the column */
3723  col->objchanged = TRUE;
3724 
3725  assert(lp->nchgcols > 0);
3726  }
3727  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3728  * LP and the LP has to be flushed
3729  */
3730  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3731  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3732  {
3733  /* mark the LP unflushed */
3734  lp->flushed = FALSE;
3735  }
3736  }
3737 
3738  /* store new objective function value */
3739  col->obj = newobj;
3740 
3741  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3742  if( !lp->divingobjchg )
3743  {
3744  SCIP_Real oldobj = col->unchangedobj;
3745 
3746  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3747  col->unchangedobj = newobj;
3748 
3749  /* update the objective function vector norms */
3750  lpUpdateObjNorms(lp, set, oldobj, newobj);
3751  }
3752 
3753  return SCIP_OKAY;
3754 }
3755 
3756 /** changes lower bound of column */
3758  SCIP_COL* col, /**< LP column to change */
3759  SCIP_SET* set, /**< global SCIP settings */
3760  SCIP_LP* lp, /**< current LP data */
3761  SCIP_Real newlb /**< new lower bound value */
3762  )
3763 {
3764  assert(col != NULL);
3765  assert(col->var != NULL);
3766  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3767  assert(SCIPvarGetCol(col->var) == col);
3768  assert(lp != NULL);
3769 
3770  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3771 
3772  /* only add actual changes */
3773  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3774  {
3775  /* only variables with a real position in the LPI can be inserted */
3776  if( col->lpipos >= 0 )
3777  {
3778  /* insert column in the chgcols list (if not already there) */
3779  SCIP_CALL( insertColChgcols(col, set, lp) );
3780 
3781  /* mark bound change in the column */
3782  col->lbchanged = TRUE;
3783 
3784  assert(lp->nchgcols > 0);
3785  }
3786  /* 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
3787  * flushed
3788  */
3789  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3790  {
3791  /* mark the LP unflushed */
3792  lp->flushed = FALSE;
3793  }
3794  }
3795 
3796  col->lb = newlb;
3797 
3798  return SCIP_OKAY;
3799 }
3800 
3801 /** changes upper bound of column */
3803  SCIP_COL* col, /**< LP column to change */
3804  SCIP_SET* set, /**< global SCIP settings */
3805  SCIP_LP* lp, /**< current LP data */
3806  SCIP_Real newub /**< new upper bound value */
3807  )
3808 {
3809  assert(col != NULL);
3810  assert(col->var != NULL);
3811  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3812  assert(SCIPvarGetCol(col->var) == col);
3813  assert(lp != NULL);
3814 
3815  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3816 
3817  /* only add actual changes */
3818  if( !SCIPsetIsEQ(set, col->ub, newub) )
3819  {
3820  /* only variables with a real position in the LPI can be inserted */
3821  if( col->lpipos >= 0 )
3822  {
3823  /* insert column in the chgcols list (if not already there) */
3824  SCIP_CALL( insertColChgcols(col, set, lp) );
3825 
3826  /* mark bound change in the column */
3827  col->ubchanged = TRUE;
3828 
3829  assert(lp->nchgcols > 0);
3830  }
3831  /* 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
3832  * flushed
3833  */
3834  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3835  {
3836  /* mark the LP unflushed */
3837  lp->flushed = FALSE;
3838  }
3839  }
3840 
3841  col->ub = newub;
3842 
3843  return SCIP_OKAY;
3844 }
3845 
3846 /** calculates the reduced costs of a column using the given dual solution vector */
3848  SCIP_COL* col, /**< LP column */
3849  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3850  )
3851 {
3852  SCIP_ROW* row;
3853  SCIP_Real redcost;
3854  int i;
3855 
3856  assert(col != NULL);
3857  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3858  assert(SCIPvarGetCol(col->var) == col);
3859  assert(dualsol != NULL);
3860 
3861  redcost = col->obj;
3862  for( i = 0; i < col->nlprows; ++i )
3863  {
3864  row = col->rows[i];
3865  assert(row != NULL);
3866  assert(row->lppos >= 0);
3867  redcost -= col->vals[i] * dualsol[row->lppos];
3868  }
3869 
3870  if( col->nunlinked > 0 )
3871  {
3872  for( i = col->nlprows; i < col->len; ++i )
3873  {
3874  row = col->rows[i];
3875  assert(row != NULL);
3876  assert(row->lppos == -1 || col->linkpos[i] == -1);
3877  if( row->lppos >= 0 )
3878  redcost -= col->vals[i] * dualsol[row->lppos];
3879  }
3880  }
3881 #ifndef NDEBUG
3882  else
3883  {
3884  for( i = col->nlprows; i < col->len; ++i )
3885  {
3886  row = col->rows[i];
3887  assert(row != NULL);
3888  assert(row->lppos == -1);
3889  assert(col->linkpos[i] >= 0);
3890  }
3891  }
3892 #endif
3893 
3894  return redcost;
3895 }
3896 
3897 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3898 static
3900  SCIP_COL* col /**< LP column */
3901  )
3902 {
3903  SCIP_ROW* row;
3904  SCIP_Real redcost;
3905  int i;
3906 
3907  assert(col != NULL);
3908  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3909  assert(SCIPvarGetCol(col->var) == col);
3910 
3911  redcost = col->obj;
3912  for( i = 0; i < col->nlprows; ++i )
3913  {
3914  row = col->rows[i];
3915  assert(row != NULL);
3916  assert(row->dualsol != SCIP_INVALID); /*lint !e777*/
3917  assert(row->lppos >= 0);
3918  assert(col->linkpos[i] >= 0);
3919  redcost -= col->vals[i] * row->dualsol;
3920  }
3921 
3922  if( col->nunlinked > 0 )
3923  {
3924  for( i = col->nlprows; i < col->len; ++i )
3925  {
3926  row = col->rows[i];
3927  assert(row != NULL);
3928  assert(row->lppos >= 0 || row->dualsol == 0.0);
3929  assert(row->lppos == -1 || col->linkpos[i] == -1);
3930  if( row->lppos >= 0 )
3931  redcost -= col->vals[i] * row->dualsol;
3932  }
3933  }
3934 #ifndef NDEBUG
3935  else
3936  {
3937  for( i = col->nlprows; i < col->len; ++i )
3938  {
3939  row = col->rows[i];
3940  assert(row != NULL);
3941  assert(row->dualsol == 0.0);
3942  assert(row->lppos == -1);
3943  assert(col->linkpos[i] >= 0);
3944  }
3945  }
3946 #endif
3947 
3948  return redcost;
3949 }
3950 
3951 /** gets the reduced costs of a column in last LP or after recalculation */
3953  SCIP_COL* col, /**< LP column */
3954  SCIP_STAT* stat, /**< problem statistics */
3955  SCIP_LP* lp /**< current LP data */
3956  )
3957 {
3958  assert(col != NULL);
3959  assert(stat != NULL);
3960  assert(lp != NULL);
3961  assert(col->validredcostlp <= stat->lpcount);
3962  assert(lp->validsollp == stat->lpcount);
3963 
3964  if( col->validredcostlp < stat->lpcount )
3965  {
3966  col->redcost = colCalcInternalRedcost(col);
3967  col->validredcostlp = stat->lpcount;
3968  }
3969  assert(col->validredcostlp == stat->lpcount);
3970  assert(col->redcost != SCIP_INVALID); /*lint !e777*/
3971 
3972  return col->redcost;
3973 }
3974 
3975 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3977  SCIP_COL* col, /**< LP column */
3978  SCIP_SET* set, /**< global SCIP settings */
3979  SCIP_STAT* stat, /**< problem statistics */
3980  SCIP_LP* lp /**< current LP data */
3981  )
3982 {
3983  assert(col != NULL);
3984  assert(set != NULL);
3985  assert(stat != NULL);
3986  assert(lp != NULL);
3987  assert(lp->validsollp == stat->lpcount);
3988 
3989  /* A column's reduced cost is defined as
3990  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3991  * The activity is equal to the activity of the corresponding row in the dual LP.
3992  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3993  * The sides of the dual row depend on the bounds of the column:
3994  * - lb == ub : dual row is a free row with infinite sides
3995  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3996  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3997  * - lb < ub <= 0: obj <= activity => redcost <= 0
3998  */
3999  if( SCIPsetIsEQ(set, col->lb, col->ub) )
4000  {
4001  /* dual row is free */
4002  return SCIPsetInfinity(set);
4003  }
4004  else
4005  {
4006  SCIP_Real redcost;
4007 
4008  /* calculate reduced costs */
4009  redcost = SCIPcolGetRedcost(col, stat, lp);
4010 
4011  if( !SCIPsetIsNegative(set, col->lb) )
4012  {
4013  /* dual row is activity <= obj <=> redcost >= 0 */
4014  return redcost;
4015  }
4016  else if( SCIPsetIsPositive(set, col->ub) )
4017  {
4018  /* dual row is activity == obj <=> redcost == 0 */
4019  return -REALABS(redcost);
4020  }
4021  else
4022  {
4023  /* dual row is activity >= obj <=> redcost <= 0 */
4024  return -redcost;
4025  }
4026  }
4027 }
4028 
4029 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4031  SCIP_COL* col, /**< LP column */
4032  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4033  )
4034 {
4035  SCIP_ROW* row;
4036  SCIP_Real farkas;
4037  int i;
4038 
4039  assert(col != NULL);
4040  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4041  assert(SCIPvarGetCol(col->var) == col);
4042  assert(dualfarkas != NULL);
4043 
4044  farkas = 0.0;
4045  for( i = 0; i < col->nlprows; ++i )
4046  {
4047  row = col->rows[i];
4048  assert(row != NULL);
4049  assert(row->lppos >= 0);
4050  farkas += col->vals[i] * dualfarkas[row->lppos];
4051  }
4052 
4053  if( col->nunlinked > 0 )
4054  {
4055  for( i = col->nlprows; i < col->len; ++i )
4056  {
4057  row = col->rows[i];
4058  assert(row != NULL);
4059  assert(row->lppos == -1 || col->linkpos[i] == -1);
4060  if( row->lppos >= 0 )
4061  farkas += col->vals[i] * dualfarkas[row->lppos];
4062  }
4063  }
4064 #ifndef NDEBUG
4065  else
4066  {
4067  for( i = col->nlprows; i < col->len; ++i )
4068  {
4069  row = col->rows[i];
4070  assert(row != NULL);
4071  assert(row->lppos == -1);
4072  assert(col->linkpos[i] >= 0);
4073  }
4074  }
4075 #endif
4076 
4077  return farkas;
4078 }
4079 
4080 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4081 static
4083  SCIP_COL* col /**< LP column */
4084  )
4085 {
4086  SCIP_ROW* row;
4087  SCIP_Real farkas;
4088  int i;
4089 
4090  assert(col != NULL);
4091  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4092  assert(SCIPvarGetCol(col->var) == col);
4093 
4094  farkas = 0.0;
4095  for( i = 0; i < col->nlprows; ++i )
4096  {
4097  row = col->rows[i];
4098  assert(row != NULL);
4099  assert(row->dualfarkas != SCIP_INVALID); /*lint !e777*/
4100  assert(row->lppos >= 0);
4101  assert(col->linkpos[i] >= 0);
4102  farkas += col->vals[i] * row->dualfarkas;
4103  }
4104 
4105  if( col->nunlinked > 0 )
4106  {
4107  for( i = col->nlprows; i < col->len; ++i )
4108  {
4109  row = col->rows[i];
4110  assert(row != NULL);
4111  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4112  assert(row->lppos == -1 || col->linkpos[i] == -1);
4113  if( row->lppos >= 0 )
4114  farkas += col->vals[i] * row->dualfarkas;
4115  }
4116  }
4117 #ifndef NDEBUG
4118  else
4119  {
4120  for( i = col->nlprows; i < col->len; ++i )
4121  {
4122  row = col->rows[i];
4123  assert(row != NULL);
4124  assert(row->dualfarkas == 0.0);
4125  assert(row->lppos == -1);
4126  assert(col->linkpos[i] >= 0);
4127  }
4128  }
4129 #endif
4130 
4131  return farkas;
4132 }
4133 
4134 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4136  SCIP_COL* col, /**< LP column */
4137  SCIP_STAT* stat, /**< problem statistics */
4138  SCIP_LP* lp /**< current LP data */
4139  )
4140 {
4141  assert(col != NULL);
4142  assert(stat != NULL);
4143  assert(lp != NULL);
4144  assert(col->validfarkaslp <= stat->lpcount);
4145  assert(lp->validfarkaslp == stat->lpcount);
4146 
4147  if( col->validfarkaslp < stat->lpcount )
4148  {
4150  col->validfarkaslp = stat->lpcount;
4151  }
4152  assert(col->validfarkaslp == stat->lpcount);
4153  assert(col->farkascoef != SCIP_INVALID); /*lint !e777*/
4154 
4155  return col->farkascoef;
4156 }
4157 
4158 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4159  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4160  */
4162  SCIP_COL* col, /**< LP column */
4163  SCIP_STAT* stat, /**< problem statistics */
4164  SCIP_LP* lp /**< current LP data */
4165  )
4166 {
4167  SCIP_Real farkascoef;
4168 
4169  assert(col != NULL);
4170 
4171  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4172 
4173  if( farkascoef > 0.0 )
4174  return col->ub * farkascoef;
4175  else
4176  return col->lb * farkascoef;
4177 }
4178 
4179 /** start strong branching - call before any strong branching */
4181  SCIP_LP* lp /**< LP data */
4182  )
4183 {
4184  assert(lp != NULL);
4185  assert(!lp->strongbranching);
4186 
4187  lp->strongbranching = TRUE;
4188  SCIPdebugMessage("starting strong branching ...\n");
4190 
4191  return SCIP_OKAY;
4192 }
4193 
4194 /** end strong branching - call after any strong branching */
4196  SCIP_LP* lp /**< LP data */
4197  )
4198 {
4199  assert(lp != NULL);
4200  assert(lp->strongbranching);
4201 
4202  lp->strongbranching = FALSE;
4203  SCIPdebugMessage("ending strong branching ...\n");
4205 
4206  return SCIP_OKAY;
4207 }
4208 
4209 /** sets strong branching information for a column variable */
4211  SCIP_COL* col, /**< LP column */
4212  SCIP_SET* set, /**< global SCIP settings */
4213  SCIP_STAT* stat, /**< dynamic problem statistics */
4214  SCIP_LP* lp, /**< LP data */
4215  SCIP_Real lpobjval, /**< objective value of the current LP */
4216  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4217  SCIP_Real sbdown, /**< dual bound after branching column down */
4218  SCIP_Real sbup, /**< dual bound after branching column up */
4219  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4220  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4221  SCIP_Longint iter, /**< total number of strong branching iterations */
4222  int itlim /**< iteration limit applied to the strong branching call */
4223  )
4224 {
4225  assert(col != NULL);
4226  assert(col->var != NULL);
4227  assert(SCIPcolIsIntegral(col));
4228  assert(SCIPvarIsIntegral(col->var));
4229  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4230  assert(SCIPvarGetCol(col->var) == col);
4231  assert(col->lpipos >= 0);
4232  assert(col->lppos >= 0);
4233  assert(set != NULL);
4234  assert(stat != NULL);
4235  assert(lp != NULL);
4236  assert(lp->strongbranchprobing);
4237  assert(col->lppos < lp->ncols);
4238  assert(lp->cols[col->lppos] == col);
4239  assert(itlim >= 1);
4240 
4241  col->sblpobjval = lpobjval;
4242  col->sbsolval = primsol;
4243  col->validsblp = stat->nlps;
4244  col->sbnode = stat->nnodes;
4245 
4246  col->sbitlim = itlim;
4247  col->nsbcalls++;
4248 
4249  col->sbdown = MIN(sbdown, lp->cutoffbound);
4250  col->sbup = MIN(sbup, lp->cutoffbound);
4251  col->sbdownvalid = sbdownvalid;
4252  col->sbupvalid = sbupvalid;
4253 
4254  SCIPstatIncrement(stat, set, nstrongbranchs);
4255  SCIPstatAdd(stat, set, nsblpiterations, iter);
4256  if( stat->nnodes == 1 )
4257  {
4258  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4259  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4260  }
4261 }
4262 
4263 /** invalidates strong branching information for a column variable */
4265  SCIP_COL* col, /**< LP column */
4266  SCIP_SET* set, /**< global SCIP settings */
4267  SCIP_STAT* stat, /**< dynamic problem statistics */
4268  SCIP_LP* lp /**< LP data */
4269  )
4270 {
4271  assert(col != NULL);
4272  assert(col->var != NULL);
4273  assert(SCIPcolIsIntegral(col));
4274  assert(SCIPvarIsIntegral(col->var));
4275  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4276  assert(SCIPvarGetCol(col->var) == col);
4277  assert(col->lpipos >= 0);
4278  assert(col->lppos >= 0);
4279  assert(set != NULL);
4280  assert(stat != NULL);
4281  assert(lp != NULL);
4282  assert(lp->strongbranchprobing);
4283  assert(col->lppos < lp->ncols);
4284  assert(lp->cols[col->lppos] == col);
4285 
4286  col->sbdown = SCIP_INVALID;
4287  col->sbup = SCIP_INVALID;
4288  col->sbdownvalid = FALSE;
4289  col->sbupvalid = FALSE;
4290  col->validsblp = -1;
4291  col->sbsolval = SCIP_INVALID;
4292  col->sblpobjval = SCIP_INVALID;
4293  col->sbnode = -1;
4294  col->sbitlim = -1;
4295 }
4296 
4297 
4298 /** gets strong branching information on a column variable */
4300  SCIP_COL* col, /**< LP column */
4301  SCIP_Bool integral, /**< should integral strong branching be performed? */
4302  SCIP_SET* set, /**< global SCIP settings */
4303  SCIP_STAT* stat, /**< dynamic problem statistics */
4304  SCIP_PROB* prob, /**< problem data */
4305  SCIP_LP* lp, /**< LP data */
4306  int itlim, /**< iteration limit for strong branchings */
4307  SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4308  SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4309  SCIP_Real* down, /**< stores dual bound after branching column down */
4310  SCIP_Real* up, /**< stores dual bound after branching column up */
4311  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4312  * otherwise, it can only be used as an estimate value */
4313  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4314  * otherwise, it can only be used as an estimate value */
4315  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4316  )
4317 {
4318  SCIP_Real sbdown;
4319  SCIP_Real sbup;
4320  SCIP_Bool sbdownvalid;
4321  SCIP_Bool sbupvalid;
4322  SCIP_Longint validsblp;
4323  SCIP_Real sbsolval;
4324  SCIP_Real sblpobjval;
4325  SCIP_Longint sbnode;
4326  int sbitlim;
4327  int nsbcalls;
4328 
4329  assert(col != NULL);
4330  assert(col->var != NULL);
4331  assert(SCIPcolIsIntegral(col));
4332  assert(SCIPvarIsIntegral(col->var));
4333  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4334  assert(SCIPvarGetCol(col->var) == col);
4335  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4336  assert(col->lpipos >= 0);
4337  assert(col->lppos >= 0);
4338  assert(set != NULL);
4339  assert(stat != NULL);
4340  assert(lp != NULL);
4341  assert(lp->flushed);
4342  assert(lp->solved);
4343  assert(lp->strongbranching);
4344  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4345  assert(lp->validsollp == stat->lpcount);
4346  assert(col->lppos < lp->ncols);
4347  assert(lp->cols[col->lppos] == col);
4348  assert(itlim >= 1);
4349  /* assert(down != NULL);
4350  * assert(up != NULL); temporary hack for cloud branching
4351  */
4352  assert(lperror != NULL);
4353 
4354  *lperror = FALSE;
4355 
4356  sbdown = col->sbdown;
4357  sbup = col->sbup;
4358  sbdownvalid = col->sbdownvalid;
4359  sbupvalid = col->sbupvalid;
4360  sbitlim = col->sbitlim;
4361  nsbcalls = col->nsbcalls;
4362 
4363  validsblp = stat->nlps;
4364  sbsolval = col->primsol;
4365  sblpobjval = SCIPlpGetObjval(lp, set, prob);
4366  sbnode = stat->nnodes;
4367  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4368 
4369  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4370  if( lp->looseobjvalinf > 0 )
4371  {
4372  sbdown = -SCIPsetInfinity(set);
4373  sbup = -SCIPsetInfinity(set);
4374  sbdownvalid = FALSE;
4375  sbupvalid = FALSE;
4376  }
4377  else
4378  {
4379  SCIP_RETCODE retcode;
4380  int iter;
4381 
4382  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4383  SCIPvarGetName(col->var), col->primsol, itlim);
4384 
4385  /* start timing */
4386  SCIPclockStart(stat->strongbranchtime, set);
4387 
4388  /* call LPI strong branching */
4389  sbitlim = itlim;
4390  nsbcalls++;
4391 
4392  sbdown = lp->lpobjval;
4393  sbup = lp->lpobjval;
4394 
4395  if( integral )
4396  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4397  else
4398  {
4399  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4400  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4401  }
4402 
4403  /* check return code for errors */
4404  if( retcode == SCIP_LPERROR )
4405  {
4406  *lperror = TRUE;
4407  sbdown = SCIP_INVALID;
4408  sbup = SCIP_INVALID;
4409  sbdownvalid = FALSE;
4410  sbupvalid = FALSE;
4411  validsblp = -1;
4412  sbsolval = SCIP_INVALID;
4413  sblpobjval = SCIP_INVALID;
4414  sbnode = -1;
4415  }
4416  else
4417  {
4418  SCIP_Real looseobjval;
4419 
4420  *lperror = FALSE;
4421  SCIP_CALL( retcode );
4422 
4423  looseobjval = getFiniteLooseObjval(lp, set, prob);
4424  sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4425  sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4426 
4427  /* update strong branching statistics */
4428  if( updatestat )
4429  {
4430  if( iter == -1 )
4431  {
4432  /* calculate average iteration number */
4433  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4434  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4435  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4436  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4437  : 0;
4438  if( iter/2 >= itlim )
4439  iter = 2*itlim;
4440  }
4441  SCIPstatIncrement(stat, set, nstrongbranchs);
4442  SCIPstatAdd(stat, set, nsblpiterations, iter);
4443  if( stat->nnodes == 1 )
4444  {
4445  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4446  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4447  }
4448  }
4449  }
4450 
4451  /* stop timing */
4452  SCIPclockStop(stat->strongbranchtime, set);
4453  }
4454  assert(*lperror || sbdown != SCIP_INVALID); /*lint !e777*/
4455  assert(*lperror || sbup != SCIP_INVALID); /*lint !e777*/
4456 
4457  if( down != NULL)
4458  *down = sbdown;
4459  if( up != NULL )
4460  *up = sbup;
4461  if( downvalid != NULL )
4462  *downvalid = sbdownvalid;
4463  if( upvalid != NULL )
4464  *upvalid = sbupvalid;
4465 
4466  if( updatecol )
4467  {
4468  col->sbdown = sbdown;
4469  col->sbup = sbup;
4470  col->sbdownvalid = sbdownvalid;
4471  col->sbupvalid = sbupvalid;
4472  col->validsblp = validsblp;
4473  col->sbsolval = sbsolval;
4474  col->sblpobjval = sblpobjval;
4475  col->sbnode = sbnode;
4476  col->sbitlim = sbitlim;
4477  col->nsbcalls = nsbcalls;
4478  }
4479 
4480  return SCIP_OKAY;
4481 }
4482 
4483 /** gets strong branching information on column variables */
4485  SCIP_COL** cols, /**< LP columns */
4486  int ncols, /**< number of columns */
4487  SCIP_Bool integral, /**< should integral strong branching be performed? */
4488  SCIP_SET* set, /**< global SCIP settings */
4489  SCIP_STAT* stat, /**< dynamic problem statistics */
4490  SCIP_PROB* prob, /**< problem data */
4491  SCIP_LP* lp, /**< LP data */
4492  int itlim, /**< iteration limit for strong branchings */
4493  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4494  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4495  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4496  * otherwise, they can only be used as an estimate value */
4497  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4498  * otherwise, they can only be used as an estimate value */
4499  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4500  )
4501 {
4502  SCIP_RETCODE retcode;
4503  SCIP_Real* sbdown;
4504  SCIP_Real* sbup;
4505  SCIP_Bool* sbdownvalid;
4506  SCIP_Bool* sbupvalid;
4507  SCIP_Real* primsols;
4508  SCIP_COL** subcols;
4509  int* lpipos;
4510  int* subidx;
4511  int nsubcols;
4512  int iter;
4513  int j;
4514 
4515  assert(cols != NULL);
4516  assert(set != NULL);
4517  assert(stat != NULL);
4518  assert(lp != NULL);
4519  assert(lp->flushed);
4520  assert(lp->solved);
4521  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4522  assert(lp->validsollp == stat->lpcount);
4523  assert(itlim >= 1);
4524  assert(down != NULL);
4525  assert(up != NULL);
4526  assert(lperror != NULL);
4527 
4528  *lperror = FALSE;
4529 
4530  if ( ncols <= 0 )
4531  return SCIP_OKAY;
4532 
4533  /* start timing */
4534  SCIPclockStart(stat->strongbranchtime, set);
4535 
4536  /* initialize storage */
4537  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4538  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4539  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4540  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4541  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4542  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4543  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4544  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4545 
4546  nsubcols = 0;
4547  for( j = 0; j < ncols; ++j )
4548  {
4549  SCIP_COL* col;
4550  col = cols[j];
4551 
4552  assert(col->lppos < lp->ncols);
4553  assert(lp->cols[col->lppos] == col);
4554  assert(SCIPcolIsIntegral(col));
4555  assert(SCIPvarIsIntegral(col->var));
4556  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4557  assert(SCIPvarGetCol(col->var) == col);
4558  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
4559  assert(col->lpipos >= 0);
4560  assert(col->lppos >= 0);
4561 
4562  col->validsblp = stat->nlps;
4563  col->sbsolval = col->primsol;
4564  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4565  col->sbnode = stat->nnodes;
4566  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4567 
4568  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4569  if( lp->looseobjvalinf > 0 )
4570  {
4571  /* directly set up column and result vectors*/
4572  col->sbdown = -SCIPsetInfinity(set);
4573  col->sbup = -SCIPsetInfinity(set);
4574  col->sbdownvalid = FALSE;
4575  col->sbupvalid = FALSE;
4576  down[j] = col->sbdown;
4577  up[j] = col->sbup;
4578  if( downvalid != NULL )
4579  downvalid[j] = col->sbdownvalid;
4580  if( upvalid != NULL )
4581  upvalid[j] = col->sbupvalid;
4582  }
4583  else
4584  {
4585  col->sbitlim = itlim;
4586  col->nsbcalls++;
4587 
4588  lpipos[nsubcols] = col->lpipos;
4589  primsols[nsubcols] = col->primsol;
4590  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4591  subidx[nsubcols] = j;
4592  subcols[nsubcols++] = col;
4593  }
4594  }
4595 
4596  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4597 
4598  /* call LPI strong branching */
4599  if ( integral )
4600  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4601  else
4602  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4603 
4604  /* check return code for errors */
4605  if( retcode == SCIP_LPERROR )
4606  {
4607  *lperror = TRUE;
4608 
4609  for( j = 0; j < nsubcols; ++j )
4610  {
4611  SCIP_COL* col;
4612  int idx;
4613 
4614  col = subcols[j];
4615  idx = subidx[j];
4616 
4617  col->sbdown = SCIP_INVALID;
4618  col->sbup = SCIP_INVALID;
4619  col->sbdownvalid = FALSE;
4620  col->sbupvalid = FALSE;
4621  col->validsblp = -1;
4622  col->sbsolval = SCIP_INVALID;
4623  col->sblpobjval = SCIP_INVALID;
4624  col->sbnode = -1;
4625 
4626  down[idx] = col->sbdown;
4627  up[idx] = col->sbup;
4628  if( downvalid != NULL )
4629  downvalid[idx] = col->sbdownvalid;
4630  if( upvalid != NULL )
4631  upvalid[idx] = col->sbupvalid;
4632  }
4633  }
4634  else
4635  {
4636  SCIP_Real looseobjval;
4637 
4638  *lperror = FALSE;
4639  SCIP_CALL( retcode );
4640 
4641  looseobjval = getFiniteLooseObjval(lp, set, prob);
4642 
4643  for( j = 0; j < nsubcols; ++j )
4644  {
4645  SCIP_COL* col;
4646  int idx;
4647 
4648  col = subcols[j];
4649  idx = subidx[j];
4650 
4651  assert( col->sbdown != SCIP_INVALID); /*lint !e777*/
4652  assert( col->sbup != SCIP_INVALID); /*lint !e777*/
4653 
4654  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4655  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4656  col->sbdownvalid = sbdownvalid[j];
4657  col->sbupvalid = sbupvalid[j];
4658 
4659  down[idx] = col->sbdown;
4660  up[idx] = col->sbup;
4661  if( downvalid != NULL )
4662  downvalid[idx] = col->sbdownvalid;
4663  if( upvalid != NULL )
4664  upvalid[idx] = col->sbupvalid;
4665  }
4666 
4667  /* update strong branching statistics */
4668  if( iter == -1 )
4669  {
4670  /* calculate average iteration number */
4671  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4672  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4673  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4674  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4675  : 0;
4676  if( iter/2 >= itlim )
4677  iter = 2*itlim;
4678  }
4679  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4680  SCIPstatAdd(stat, set, nsblpiterations, iter);
4681  if( stat->nnodes == 1 )
4682  {
4683  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4684  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4685  }
4686  }
4687 
4688  SCIPsetFreeBufferArray(set, &sbupvalid);
4689  SCIPsetFreeBufferArray(set, &sbdownvalid);
4690  SCIPsetFreeBufferArray(set, &sbup);
4691  SCIPsetFreeBufferArray(set, &sbdown);
4692  SCIPsetFreeBufferArray(set, &primsols);
4693  SCIPsetFreeBufferArray(set, &lpipos);
4694  SCIPsetFreeBufferArray(set, &subidx);
4695  SCIPsetFreeBufferArray(set, &subcols);
4696 
4697  /* stop timing */
4698  SCIPclockStop(stat->strongbranchtime, set);
4699 
4700  return SCIP_OKAY;
4701 }
4702 
4703 /** gets last strong branching information available for a column variable;
4704  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4705  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4706  */
4708  SCIP_COL* col, /**< LP column */
4709  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4710  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4711  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4712  * otherwise, it can only be used as an estimate value */
4713  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4714  * otherwise, it can only be used as an estimate value */
4715  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4716  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4717  )
4718 {
4719  assert(col != NULL);
4720 
4721  if( down != NULL )
4722  *down = col->sbdown;
4723  if( up != NULL )
4724  *up = col->sbup;
4725  if( downvalid != NULL )
4726  *downvalid = col->sbdownvalid;
4727  if( upvalid != NULL )
4728  *upvalid = col->sbupvalid;
4729  if( solval != NULL )
4730  *solval = col->sbsolval;
4731  if( lpobjval != NULL )
4732  *lpobjval = col->sblpobjval;
4733 }
4734 
4735 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4736  * the LP where the strong branching on this column was applied;
4737  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4738  */
4740  SCIP_COL* col, /**< LP column */
4741  SCIP_STAT* stat /**< dynamic problem statistics */
4742  )
4743 {
4744  assert(col != NULL);
4745  assert(stat != NULL);
4746 
4747  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4748 }
4749 
4750 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4752  SCIP_COL* col, /**< LP column */
4753  SCIP_STAT* stat /**< problem statistics */
4754  )
4755 {
4756  assert(col != NULL);
4757  assert(stat != NULL);
4758  assert(stat->nnodes > 0);
4759 
4760  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4761  col->obsoletenode = stat->nnodes;
4762 }
4763 
4764 
4765 /*
4766  * Row methods
4767  */
4768 
4769 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4770 static
4772  SCIP_ROW* row, /**< LP row */
4773  SCIP_SET* set /**< global SCIP settings */
4774  )
4775 {
4776  int i;
4777 
4778  assert(row != NULL);
4779  assert(set != NULL);
4780 
4781  row->sqrnorm = 0.0;
4782  row->sumnorm = 0.0;
4783  row->objprod = 0.0;
4784  row->maxval = 0.0;
4785  row->nummaxval = 1;
4786  row->minval = SCIPsetInfinity(set);
4787  row->numminval = 1;
4788  row->minidx = INT_MAX;
4789  row->maxidx = INT_MIN;
4790  row->validminmaxidx = TRUE;
4791  row->lpcolssorted = TRUE;
4792  row->nonlpcolssorted = TRUE;
4793 
4794  /* check, if row is sorted
4795  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4796  */
4797  for( i = 0; i < row->nlpcols; ++i )
4798  {
4799  assert(row->cols[i] != NULL);
4800  assert(!SCIPsetIsZero(set, row->vals[i]));
4801  assert(row->cols[i]->lppos >= 0);
4802  assert(row->linkpos[i] >= 0);
4803  assert(row->cols[i]->index == row->cols_index[i]);
4804 
4805  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4806  if( i > 0 )
4807  {
4808  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4809  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4810  }
4811  }
4812  for( i = row->nlpcols; i < row->len; ++i )
4813  {
4814  assert(row->cols[i] != NULL);
4815  assert(!SCIPsetIsZero(set, row->vals[i]));
4816  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4817  assert(row->cols[i]->index == row->cols_index[i]);
4818 
4819  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4820  if( i > row->nlpcols )
4821  {
4822  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4823  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4824  }
4825  }
4826 }
4827 
4828 /** calculates min/maxval and min/maxidx from scratch */
4829 static
4831  SCIP_ROW* row, /**< LP row */
4832  SCIP_SET* set /**< global SCIP settings */
4833  )
4834 {
4835  SCIP_COL* col;
4836  SCIP_Real absval;
4837  int i;
4838 
4839  assert(row != NULL);
4840  assert(set != NULL);
4841 
4842  row->maxval = 0.0;
4843  row->nummaxval = 1;
4844  row->numintcols = 0;
4845  row->minval = SCIPsetInfinity(set);
4846  row->numminval = 1;
4847  row->minidx = INT_MAX;
4848  row->maxidx = INT_MIN;
4849  row->validminmaxidx = TRUE;
4850 
4851  /* calculate maxval, minval, minidx, and maxidx */
4852  for( i = 0; i < row->len; ++i )
4853  {
4854  col = row->cols[i];
4855  assert(col != NULL);
4856  assert(!SCIPsetIsZero(set, row->vals[i]));
4857 
4858  absval = REALABS(row->vals[i]);
4859  assert(!SCIPsetIsZero(set, absval));
4860 
4861  /* update min/maxidx */
4862  row->minidx = MIN(row->minidx, col->index);
4863  row->maxidx = MAX(row->maxidx, col->index);
4864  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4865 
4866  /* update maximal and minimal non-zero value */
4867  if( row->nummaxval > 0 )
4868  {
4869  if( SCIPsetIsGT(set, absval, row->maxval) )
4870  {
4871  row->maxval = absval;
4872  row->nummaxval = 1;
4873  }
4874  else if( SCIPsetIsGE(set, absval, row->maxval) )
4875  {
4876  /* make sure the maxval is always exactly the same */
4877  row->maxval = MAX(absval, row->maxval);
4878  row->nummaxval++;
4879  }
4880  }
4881  if( row->numminval > 0 )
4882  {
4883  if( SCIPsetIsLT(set, absval, row->minval) )
4884  {
4885  row->minval = absval;
4886  row->numminval = 1;
4887  }
4888  else if( SCIPsetIsLE(set, absval, row->minval) )
4889  {
4890  /* make sure the minval is always exactly the same */
4891  row->minval = MIN(absval, row->minval);
4892  row->numminval++;
4893  }
4894  }
4895  }
4896 }
4897 
4898 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4899 static
4901  SCIP_Real val, /**< value that should be scaled to an integral value */
4902  SCIP_Real scalar, /**< scalar that should be tried */
4903  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4904  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4905  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4906  )
4907 {
4908  SCIP_Real sval;
4909  SCIP_Real downval;
4910  SCIP_Real upval;
4911 
4912  assert(mindelta <= 0.0);
4913  assert(maxdelta >= 0.0);
4914 
4915  sval = val * scalar;
4916  downval = floor(sval);
4917  upval = ceil(sval);
4918 
4919  if( SCIPrelDiff(sval, downval) <= maxdelta )
4920  {
4921  if( intval != NULL )
4922  *intval = downval;
4923  return TRUE;
4924  }
4925  else if( SCIPrelDiff(sval, upval) >= mindelta )
4926  {
4927  if( intval != NULL )
4928  *intval = upval;
4929  return TRUE;
4930  }
4931 
4932  return FALSE;
4933 }
4934 
4935 /** scales row with given factor, and rounds coefficients to integers if close enough;
4936  * the constant is automatically moved to the sides;
4937  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4938  */
4939 static
4941  SCIP_ROW* row, /**< LP row */
4942  BMS_BLKMEM* blkmem, /**< block memory */
4943  SCIP_SET* set, /**< global SCIP settings */
4944  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4945  SCIP_STAT* stat, /**< problem statistics */
4946  SCIP_LP* lp, /**< current LP data */
4947  SCIP_Real scaleval, /**< value to scale row with */
4948  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4949  * if they are close to integral values? */
4950  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4951  * upto which the integral is used instead of the scaled real coefficient */
4952  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4953  * upto which the integral is used instead of the scaled real coefficient */
4954  )
4955 {
4956  SCIP_COL* col;
4957  SCIP_Real val;
4958  SCIP_Real newval;
4959  SCIP_Real intval;
4960  SCIP_Real mindelta;
4961  SCIP_Real maxdelta;
4962  SCIP_Real lb;
4963  SCIP_Real ub;
4964  SCIP_Bool mindeltainf;
4965  SCIP_Bool maxdeltainf;
4966  int oldlen;
4967  int c;
4968 
4969  assert(row != NULL);
4970  assert(row->len == 0 || row->cols != NULL);
4971  assert(row->len == 0 || row->vals != NULL);
4972  assert(SCIPsetIsPositive(set, scaleval));
4973  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4974  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4975 
4976  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4977 
4978  mindelta = 0.0;
4979  maxdelta = 0.0;
4980  mindeltainf = FALSE;
4981  maxdeltainf = FALSE;
4982  oldlen = row->len;
4983 
4984  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4985  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4986  * this rounding can lead to
4987  */
4988  row->integral = TRUE;
4989 
4990  c = 0;
4991  while( c < row->len )
4992  {
4993  col = row->cols[c];
4994  val = row->vals[c];
4995  assert(!SCIPsetIsZero(set, val));
4996 
4997  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4998  if( row->local )
4999  {
5000  lb = col->lb;
5001  ub = col->ub;
5002  }
5003  else
5004  {
5005  lb = SCIPvarGetLbGlobal(col->var);
5006  ub = SCIPvarGetUbGlobal(col->var);
5007  }
5008 
5009  /* calculate scaled coefficient */
5010  newval = val * scaleval;
5011  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5012  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5013  {
5014  if( !SCIPsetIsEQ(set, intval, newval) )
5015  {
5016  if( intval < newval )
5017  {
5018  mindelta += (intval - newval)*ub;
5019  maxdelta += (intval - newval)*lb;
5020  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5021  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5022  }
5023  else
5024  {
5025  mindelta += (intval - newval)*lb;
5026  maxdelta += (intval - newval)*ub;
5027  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5028  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5029  }
5030  }
5031  newval = intval;
5032  }
5033 
5034  if( !SCIPsetIsEQ(set, val, newval) )
5035  {
5036  /* if column knows of the row, change the corresponding coefficient in the column */
5037  if( row->linkpos[c] >= 0 )
5038  {
5039  assert(col->rows[row->linkpos[c]] == row);
5040  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5041  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5042  }
5043 
5044  /* change the coefficient in the row, and update the norms and integrality status */
5045  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5046 
5047  /* current coefficient has been deleted from the row because it was almost zero */
5048  if( oldlen != row->len )
5049  {
5050  assert(row->len == oldlen - 1);
5051  c--;
5052  oldlen = row->len;
5053  }
5054  }
5055  else
5056  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5057 
5058  ++c;
5059  }
5060 
5061  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5062  * to not destroy feasibility due to rounding
5063  */
5064  /**@todo ensure that returned cut does not have infinite lhs and rhs */
5065  if( !SCIPsetIsInfinity(set, -row->lhs) )
5066  {
5067  if( mindeltainf )
5068  newval = -SCIPsetInfinity(set);
5069  else
5070  {
5071  newval = (row->lhs - row->constant) * scaleval + mindelta;
5072  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5073  newval = SCIPsetSumCeil(set, newval);
5074  }
5075  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5076  }
5077  if( !SCIPsetIsInfinity(set, row->rhs) )
5078  {
5079  if( maxdeltainf )
5080  newval = SCIPsetInfinity(set);
5081  else
5082  {
5083  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5084  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5085  newval = SCIPsetSumFloor(set, newval);
5086  }
5087  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5088  }
5089 
5090  /* clear the row constant */
5091  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5092 
5093  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5094  debugRowPrint(set, row);
5095 
5096 #ifdef SCIP_DEBUG
5097  /* check integrality status of row */
5098  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5099  {}
5100  assert(row->integral == (c == row->len));
5101 #endif
5102 
5103  /* invalid the activity */
5104  row->validactivitylp = -1;
5105 
5106  return SCIP_OKAY;
5107 }
5108 
5109 /** creates and captures an LP row */
5111  SCIP_ROW** row, /**< pointer to LP row data */
5112  BMS_BLKMEM* blkmem, /**< block memory */
5113  SCIP_SET* set, /**< global SCIP settings */
5114  SCIP_STAT* stat, /**< problem statistics */
5115  const char* name, /**< name of row */
5116  int len, /**< number of nonzeros in the row */
5117  SCIP_COL** cols, /**< array with columns of row entries */
5118  SCIP_Real* vals, /**< array with coefficients of row entries */
5119  SCIP_Real lhs, /**< left hand side of row */
5120  SCIP_Real rhs, /**< right hand side of row */
5121  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5122  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5123  SCIP_Bool local, /**< is row only valid locally? */
5124  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5125  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5126  )
5127 {
5128  assert(row != NULL);
5129  assert(blkmem != NULL);
5130  assert(stat != NULL);
5131  assert(len >= 0);
5132  assert(len == 0 || (cols != NULL && vals != NULL));
5133  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5134  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5135  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5136  */
5137  assert(lhs <= rhs);
5138 
5139  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5140 
5141  (*row)->integral = TRUE;
5142  if( len > 0 )
5143  {
5144  SCIP_VAR* var;
5145  int i;
5146 
5147  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5148  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5149  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5150  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5151 
5152  for( i = 0; i < len; ++i )
5153  {
5154  assert(cols[i] != NULL);
5155  assert(!SCIPsetIsZero(set, vals[i]));
5156 
5157  var = cols[i]->var;
5158  (*row)->cols_index[i] = cols[i]->index;
5159  (*row)->linkpos[i] = -1;
5160  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5161  {
5162  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5163  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5164  }
5165  else
5166  {
5167  (*row)->integral = FALSE;
5168  }
5169  }
5170  }
5171  else
5172  {
5173  (*row)->cols = NULL;
5174  (*row)->cols_index = NULL;
5175  (*row)->vals = NULL;
5176  (*row)->linkpos = NULL;
5177  }
5178 
5179  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5180  (*row)->constant = 0.0;
5181  (*row)->lhs = lhs;
5182  (*row)->rhs = rhs;
5183  (*row)->flushedlhs = -SCIPsetInfinity(set);
5184  (*row)->flushedrhs = SCIPsetInfinity(set);
5185  (*row)->sqrnorm = 0.0;
5186  (*row)->sumnorm = 0.0;
5187  (*row)->objprod = 0.0;
5188  (*row)->maxval = 0.0;
5189  (*row)->minval = SCIPsetInfinity(set);
5190  (*row)->dualsol = 0.0;
5191  (*row)->activity = SCIP_INVALID;
5192  (*row)->dualfarkas = 0.0;
5193  (*row)->pseudoactivity = SCIP_INVALID;
5194  (*row)->minactivity = SCIP_INVALID;
5195  (*row)->maxactivity = SCIP_INVALID;
5196  (*row)->origin = origin;
5197  (*row)->eventfilter = NULL;
5198  (*row)->index = stat->nrowidx;
5199  SCIPstatIncrement(stat, set, nrowidx);
5200  (*row)->size = len;
5201  (*row)->len = len;
5202  (*row)->nlpcols = 0;
5203  (*row)->nunlinked = len;
5204  (*row)->nuses = 0;
5205  (*row)->lppos = -1;
5206  (*row)->lpipos = -1;
5207  (*row)->lpdepth = -1;
5208  (*row)->minidx = INT_MAX;
5209  (*row)->maxidx = INT_MIN;
5210  (*row)->nummaxval = 0;
5211  (*row)->numminval = 0;
5212  (*row)->numintcols = -1;
5213  (*row)->validactivitylp = -1;
5214  (*row)->validpsactivitydomchg = -1;
5215  (*row)->validactivitybdsdomchg = -1;
5216  (*row)->nlpsaftercreation = 0L;
5217  (*row)->activeinlpcounter = 0L;
5218  (*row)->age = 0;
5219  (*row)->rank = 0;
5220  (*row)->obsoletenode = -1;
5221  (*row)->fromcutpool = FALSE;
5222  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5223  (*row)->lpcolssorted = TRUE;
5224  (*row)->nonlpcolssorted = (len <= 1);
5225  (*row)->delaysort = FALSE;
5226  (*row)->validminmaxidx = FALSE;
5227  (*row)->lhschanged = FALSE;
5228  (*row)->rhschanged = FALSE;
5229  (*row)->coefchanged = FALSE;
5230  (*row)->local = local;
5231  (*row)->modifiable = modifiable;
5232  (*row)->nlocks = 0;
5233  (*row)->origintype = origintype; /*lint !e641*/
5234  (*row)->removable = removable;
5235  (*row)->inglobalcutpool = FALSE;
5236  (*row)->storedsolvals = NULL;
5237 
5238  /* calculate row norms and min/maxidx, and check if row is sorted */
5239  rowCalcNorms(*row, set);
5240 
5241  /* capture the row */
5242  SCIProwCapture(*row);
5243 
5244  /* create event filter */
5245  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5246 
5247  /* capture origin constraint if available */
5248  if( origintype == SCIP_ROWORIGINTYPE_CONS )
5249  {
5250  SCIP_CONS* cons = (SCIP_CONS*) origin;
5251  assert(cons != NULL);
5252  SCIPconsCapture(cons);
5253  }
5254 
5255  return SCIP_OKAY;
5256 } /*lint !e715*/
5257 
5258 /** frees an LP row */
5260  SCIP_ROW** row, /**< pointer to LP row */
5261  BMS_BLKMEM* blkmem, /**< block memory */
5262  SCIP_SET* set, /**< global SCIP settings */
5263  SCIP_LP* lp /**< current LP data */
5264  )
5265 {
5266  assert(blkmem != NULL);
5267  assert(row != NULL);
5268  assert(*row != NULL);
5269  assert((*row)->nuses == 0);
5270  assert((*row)->lppos == -1);
5271  assert((*row)->eventfilter != NULL);
5272 
5273  /* release constraint that has been used for creating the row */
5274  if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5275  {
5276  SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5277  assert(cons != NULL);
5278  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5279  }
5280 
5281  /* remove column indices from corresponding rows */
5282  SCIP_CALL( rowUnlink(*row, set, lp) );
5283 
5284  /* free event filter */
5285  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5286 
5287  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5288  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5289  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5290  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5291  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5292  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5293  BMSfreeBlockMemory(blkmem, row);
5294 
5295  return SCIP_OKAY;
5296 }
5297 
5298 /** output row to file stream */
5300  SCIP_ROW* row, /**< LP row */
5301  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5302  FILE* file /**< output file (or NULL for standard output) */
5303  )
5304 {
5305  int i;
5306 
5307  assert(row != NULL);
5308 
5309  /* print row name */
5310  if( row->name != NULL && row->name[0] != '\0' )
5311  {
5312  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5313  }
5314 
5315  /* print left hand side */
5316  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5317 
5318  /* print coefficients */
5319  if( row->len == 0 )
5320  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5321  for( i = 0; i < row->len; ++i )
5322  {
5323  assert(row->cols[i] != NULL);
5324  assert(row->cols[i]->var != NULL);
5325  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5326  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5327  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5328  }
5329 
5330  /* print constant */
5331  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5332  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5333 
5334  /* print right hand side */
5335  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5336 }
5337 
5338 /** increases usage counter of LP row */
5340  SCIP_ROW* row /**< LP row */
5341  )
5342 {
5343  assert(row != NULL);
5344  assert(row->nuses >= 0);
5345  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5346 
5347  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5348  row->nuses++;
5349 }
5350 
5351 /** decreases usage counter of LP row, and frees memory if necessary */
5353  SCIP_ROW** row, /**< pointer to LP row */
5354  BMS_BLKMEM* blkmem, /**< block memory */
5355  SCIP_SET* set, /**< global SCIP settings */
5356  SCIP_LP* lp /**< current LP data */
5357  )
5358 {
5359  assert(blkmem != NULL);
5360  assert(row != NULL);
5361  assert(*row != NULL);
5362  assert((*row)->nuses >= 1);
5363  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5364 
5365  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5366  (*row)->nuses--;
5367  if( (*row)->nuses == 0 )
5368  {
5369  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5370  }
5371 
5372  *row = NULL;
5373 
5374  return SCIP_OKAY;
5375 }
5376 
5377 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5379  SCIP_ROW* row /**< LP row */
5380  )
5381 {
5382  assert(row != NULL);
5383 
5384  /* check, if row is modifiable */
5385  if( !row->modifiable )
5386  {
5387  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5388  row->nlocks++;
5389  }
5390 }
5391 
5392 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5394  SCIP_ROW* row /**< LP row */
5395  )
5396 {
5397  assert(row != NULL);
5398 
5399  /* check, if row is modifiable */
5400  if( !row->modifiable )
5401  {
5402  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5403  assert(row->nlocks > 0);
5404  row->nlocks--;
5405  }
5406 }
5407 
5408 /** adds a previously non existing coefficient to an LP row */
5410  SCIP_ROW* row, /**< LP row */
5411  BMS_BLKMEM* blkmem, /**< block memory */
5412  SCIP_SET* set, /**< global SCIP settings */
5413  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5414  SCIP_LP* lp, /**< current LP data */
5415  SCIP_COL* col, /**< LP column */
5416  SCIP_Real val /**< value of coefficient */
5417  )
5418 {
5419  assert(lp != NULL);
5420  assert(!lp->diving || row->lppos == -1);
5421 
5422  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5423 
5424  checkLinks(lp);
5425 
5426  return SCIP_OKAY;
5427 }
5428 
5429 /** deletes coefficient from row */
5431  SCIP_ROW* row, /**< row to be changed */
5432  BMS_BLKMEM* blkmem, /**< block memory */
5433  SCIP_SET* set, /**< global SCIP settings */
5434  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5435  SCIP_LP* lp, /**< current LP data */
5436  SCIP_COL* col /**< coefficient to be deleted */
5437  )
5438 {
5439  int pos;
5440 
5441  assert(row != NULL);
5442  assert(!row->delaysort);
5443  assert(lp != NULL);
5444  assert(!lp->diving || row->lppos == -1);
5445  assert(col != NULL);
5446  assert(col->var != NULL);
5447 
5448  /* search the position of the column in the row's col vector */
5449  pos = rowSearchCoef(row, col);
5450  if( pos == -1 )
5451  {
5452  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5453  return SCIP_INVALIDDATA;
5454  }
5455  assert(0 <= pos && pos < row->len);
5456  assert(row->cols[pos] == col);
5457  assert(row->cols_index[pos] == col->index);
5458 
5459  /* if column knows of the row, remove the row from the column's row vector */
5460  if( row->linkpos[pos] >= 0 )
5461  {
5462  assert(col->rows[row->linkpos[pos]] == row);
5463  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5464  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5465  }
5466 
5467  /* delete the column from the row's col vector */
5468  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5469 
5470  checkLinks(lp);
5471 
5472  return SCIP_OKAY;
5473 }
5474 
5475 /** changes or adds a coefficient to an LP row */
5477  SCIP_ROW* row, /**< LP row */
5478  BMS_BLKMEM* blkmem, /**< block memory */
5479  SCIP_SET* set, /**< global SCIP settings */
5480  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5481  SCIP_LP* lp, /**< current LP data */
5482  SCIP_COL* col, /**< LP column */
5483  SCIP_Real val /**< value of coefficient */
5484  )
5485 {
5486  int pos;
5487 
5488  assert(row != NULL);
5489  assert(!row->delaysort);
5490  assert(lp != NULL);
5491  assert(!lp->diving || row->lppos == -1);
5492  assert(col != NULL);
5493 
5494  /* search the position of the column in the row's col vector */
5495  pos = rowSearchCoef(row, col);
5496 
5497  /* check, if column already exists in the row's col vector */
5498  if( pos == -1 )
5499  {
5500  /* add previously not existing coefficient */
5501  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5502  }
5503  else
5504  {
5505  /* modify already existing coefficient */
5506  assert(0 <= pos && pos < row->len);
5507  assert(row->cols[pos] == col);
5508  assert(row->cols_index[pos] == col->index);
5509 
5510  /* if column knows of the row, change the corresponding coefficient in the column */
5511  if( row->linkpos[pos] >= 0 )
5512  {
5513  assert(col->rows[row->linkpos[pos]] == row);
5514  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5515  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5516  }
5517 
5518  /* change the coefficient in the row */
5519  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5520  }
5521 
5522  checkLinks(lp);
5523 
5524  return SCIP_OKAY;
5525 }
5526 
5527 /** increases value of an existing or non-existing coefficient in an LP row */
5529  SCIP_ROW* row, /**< LP row */
5530  BMS_BLKMEM* blkmem, /**< block memory */
5531  SCIP_SET* set, /**< global SCIP settings */
5532  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5533  SCIP_LP* lp, /**< current LP data */
5534  SCIP_COL* col, /**< LP column */
5535  SCIP_Real incval /**< value to add to the coefficient */
5536  )
5537 {
5538  int pos;
5539 
5540  assert(row != NULL);
5541  assert(lp != NULL);
5542  assert(!lp->diving || row->lppos == -1);
5543  assert(col != NULL);
5544 
5545  if( SCIPsetIsZero(set, incval) )
5546  return SCIP_OKAY;
5547 
5548  /* search the position of the column in the row's col vector */
5549  pos = rowSearchCoef(row, col);
5550 
5551  /* check, if column already exists in the row's col vector */
5552  if( pos == -1 )
5553  {
5554  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5555  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5556  }
5557  else
5558  {
5559  /* modify already existing coefficient */
5560  assert(0 <= pos && pos < row->len);
5561  assert(row->cols[pos] == col);
5562  assert(row->cols_index[pos] == col->index);
5563 
5564  /* if column knows of the row, change the corresponding coefficient in the column */
5565  if( row->linkpos[pos] >= 0 )
5566  {
5567  assert(col->rows[row->linkpos[pos]] == row);
5568  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5569  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5570  }
5571 
5572  /* change the coefficient in the row */
5573  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5574  }
5575 
5576  checkLinks(lp);
5577 
5578  /* invalid the activity */
5579  row->validactivitylp = -1;
5580 
5581  return SCIP_OKAY;
5582 }
5583 
5584 /** changes constant value of a row */
5586  SCIP_ROW* row, /**< LP row */
5587  BMS_BLKMEM* blkmem, /**< block memory */
5588  SCIP_SET* set, /**< global SCIP settings */
5589  SCIP_STAT* stat, /**< problem statistics */
5590  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5591  SCIP_LP* lp, /**< current LP data */
5592  SCIP_Real constant /**< new constant value */
5593  )
5594 {
5595  assert(row != NULL);
5596  assert(row->lhs <= row->rhs);
5597  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5598  assert(stat != NULL);
5599  assert(lp != NULL);
5600  assert(!lp->diving || row->lppos == -1);
5601 
5602  if( !SCIPsetIsEQ(set, constant, row->constant) )
5603  {
5604  SCIP_Real oldconstant;
5605 
5606  if( row->validpsactivitydomchg == stat->domchgcount )
5607  {
5608  assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
5609  row->pseudoactivity += constant - row->constant;
5610  }
5611  if( row->validactivitybdsdomchg == stat->domchgcount )
5612  {
5613  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
5614  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
5615  row->minactivity += constant - row->constant;
5616  row->maxactivity += constant - row->constant;
5617  }
5618 
5619  if( !SCIPsetIsInfinity(set, -row->lhs) )
5620  {
5621  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5622  }
5623  if( !SCIPsetIsInfinity(set, row->rhs) )
5624  {
5625  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5626  }
5627 
5628  oldconstant = row->constant;
5629 
5630  row->constant = constant;
5631 
5632  /* issue row constant changed event */
5633  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5634  }
5635 
5636  return SCIP_OKAY;
5637 }
5638 
5639 /** add constant value to a row */
5641  SCIP_ROW* row, /**< LP row */
5642  BMS_BLKMEM* blkmem, /**< block memory */
5643  SCIP_SET* set, /**< global SCIP settings */
5644  SCIP_STAT* stat, /**< problem statistics */
5645  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5646  SCIP_LP* lp, /**< current LP data */
5647  SCIP_Real addval /**< constant value to add to the row */
5648  )
5649 {
5650  assert(row != NULL);
5651  assert(row->lhs <= row->rhs);
5652  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5653  assert(stat != NULL);
5654  assert(lp != NULL);
5655  assert(!lp->diving || row->lppos == -1);
5656 
5657  if( !SCIPsetIsZero(set, addval) )
5658  {
5659  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5660  }
5661 
5662  return SCIP_OKAY;
5663 }
5664 
5665 /** changes left hand side of LP row */
5667  SCIP_ROW* row, /**< LP row */
5668  BMS_BLKMEM* blkmem, /**< block memory */
5669  SCIP_SET* set, /**< global SCIP settings */
5670  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5671  SCIP_LP* lp, /**< current LP data */
5672  SCIP_Real lhs /**< new left hand side */
5673  )
5674 {
5675  assert(row != NULL);
5676  assert(lp != NULL);
5677 
5678  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5679  {
5680  SCIP_Real oldlhs;
5681 
5682  oldlhs = row->lhs;
5683 
5684  row->lhs = lhs;
5685  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5686 
5687  if( !lp->diving )
5688  {
5689  /* issue row side changed event */
5690  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5691  }
5692  }
5693 
5694  return SCIP_OKAY;
5695 }
5696 
5697 /** changes right hand side of LP row */
5699  SCIP_ROW* row, /**< LP row */
5700  BMS_BLKMEM* blkmem, /**< block memory */
5701  SCIP_SET* set, /**< global SCIP settings */
5702  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5703  SCIP_LP* lp, /**< current LP data */
5704  SCIP_Real rhs /**< new right hand side */
5705  )
5706 {
5707  assert(row != NULL);
5708  assert(lp != NULL);
5709 
5710  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5711  {
5712  SCIP_Real oldrhs;
5713 
5714  oldrhs = row->rhs;
5715 
5716  row->rhs = rhs;
5717  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5718 
5719  if( !lp->diving )
5720  {
5721  /* issue row side changed event */
5722  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5723  }
5724  }
5725 
5726  return SCIP_OKAY;
5727 }
5728 
5729 /** changes the local flag of LP row */
5731  SCIP_ROW* row, /**< LP row */
5732  SCIP_Bool local /**< new value for local flag */
5733  )
5734 {
5735  assert(row != NULL);
5736 
5737  row->local = local;
5738 
5739  return SCIP_OKAY;
5740 }
5741 
5742 /** additional scalars that are tried in integrality scaling */
5743 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5744 static const int nscalars = 9;
5745 
5746 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5748  SCIP_ROW* row, /**< LP row */
5749  SCIP_SET* set, /**< global SCIP settings */
5750  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5751  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5752  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5753  SCIP_Real maxscale, /**< maximal allowed scalar */
5754  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5755  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5756  SCIP_Bool* success /**< stores whether returned value is valid */
5757  )
5758 {
5759 #ifndef NDEBUG
5760  SCIP_COL* col;
5761 #endif
5762  SCIP_Longint gcd;
5763  SCIP_Longint scm;
5764  SCIP_Longint nominator;
5765  SCIP_Longint denominator;
5766  SCIP_Real val;
5767  SCIP_Real absval;
5768  SCIP_Real minval;
5769  SCIP_Real scaleval;
5770  SCIP_Real twomultval;
5771  SCIP_Bool scalable;
5772  SCIP_Bool twomult;
5773  SCIP_Bool rational;
5774  int c;
5775  int s;
5776 
5777  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5778  assert(row != NULL);
5779  assert(row->len == 0 || row->cols != NULL);
5780  assert(row->len == 0 || row->cols_index != NULL);
5781  assert(row->len == 0 || row->vals != NULL);
5782  assert(maxdnom >= 1);
5783  assert(mindelta < 0.0);
5784  assert(maxdelta > 0.0);
5785  assert(success != NULL);
5786 
5787  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5788  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5789 
5790  if( intscalar != NULL )
5791  *intscalar = SCIP_INVALID;
5792  *success = FALSE;
5793 
5794  /* get minimal absolute non-zero value */
5795  minval = SCIP_REAL_MAX;
5796  for( c = 0; c < row->len; ++c )
5797  {
5798 #ifndef NDEBUG
5799  col = row->cols[c];
5800  assert(col != NULL);
5801  assert(col->var != NULL);
5802  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5803  assert(SCIPvarGetCol(col->var) == col);
5804 #endif
5805  val = row->vals[c];
5806  assert(!SCIPsetIsZero(set, val));
5807 
5808  if( val < mindelta || val > maxdelta )
5809  {
5810  absval = REALABS(val);
5811  minval = MIN(minval, absval);
5812  }
5813  }
5814  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5815  {
5816  /* all coefficients are zero (inside tolerances) */
5817  if( intscalar != NULL )
5818  *intscalar = 1.0;
5819  *success = TRUE;
5820  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5821 
5822  return SCIP_OKAY;
5823  }
5824  assert(minval > MIN(-mindelta, maxdelta));
5825  assert(SCIPsetIsPositive(set, minval));
5826  assert(!SCIPsetIsInfinity(set, minval));
5827 
5828  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5829  * and a power of 2
5830  */
5831  scaleval = 1.0/minval;
5832  scalable = (scaleval <= maxscale);
5833  for( c = 0; c < row->len && scalable; ++c )
5834  {
5835  /* don't look at continuous variables, if we don't have to */
5836  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5837  continue;
5838 
5839  /* check, if the coefficient can be scaled with a simple scalar */
5840  val = row->vals[c];
5841  absval = REALABS(val);
5842  while( scaleval <= maxscale
5843  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5844  {
5845  for( s = 0; s < nscalars; ++s )
5846  {
5847  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5848  {
5849  scaleval *= scalars[s];
5850  break;
5851  }
5852  }
5853  if( s >= nscalars )
5854  scaleval *= 2.0;
5855  }
5856  scalable = (scaleval <= maxscale);
5857  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5858  }
5859  if( scalable )
5860  {
5861  /* make row coefficients integral by dividing them by the smallest coefficient
5862  * (and multiplying them with a power of 2)
5863  */
5864  assert(scaleval <= maxscale);
5865  if( intscalar != NULL )
5866  *intscalar = scaleval;
5867  *success = TRUE;
5868  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5869 
5870  return SCIP_OKAY;
5871  }
5872 
5873  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5874  twomultval = 1.0;
5875  twomult = (twomultval <= maxscale);
5876  for( c = 0; c < row->len && twomult; ++c )
5877  {
5878  /* don't look at continuous variables, if we don't have to */
5879  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5880  continue;
5881 
5882  /* check, if the coefficient can be scaled with a simple scalar */
5883  val = row->vals[c];
5884  absval = REALABS(val);
5885  while( twomultval <= maxscale
5886  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5887  {
5888  for( s = 0; s < nscalars; ++s )
5889  {
5890  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5891  {
5892  twomultval *= scalars[s];
5893  break;
5894  }
5895  }
5896  if( s >= nscalars )
5897  twomultval *= 2.0;
5898  }
5899  twomult = (twomultval <= maxscale);
5900  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5901  val, twomultval, val*twomultval, twomult);
5902  }
5903  if( twomult )
5904  {
5905  /* make row coefficients integral by multiplying them with a power of 2 */
5906  assert(twomultval <= maxscale);
5907  if( intscalar != NULL )
5908  *intscalar = twomultval;
5909  *success = TRUE;
5910  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5911 
5912  return SCIP_OKAY;
5913  }
5914 
5915  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5916  * and the smallest common multiple of the denominators
5917  */
5918  gcd = 1;
5919  scm = 1;
5920  rational = (maxdnom > 1);
5921 
5922  /* first coefficient (to initialize gcd) */
5923  for( c = 0; c < row->len && rational; ++c )
5924  {
5925  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5926  {
5927  val = row->vals[c];
5928  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5929  if( rational && nominator != 0 )
5930  {
5931  assert(denominator > 0);
5932  gcd = ABS(nominator);
5933  scm = denominator;
5934  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5935  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5936  val, nominator, denominator, gcd, scm, rational);
5937  break;
5938  }
5939  }
5940  }
5941 
5942  /* remaining coefficients */
5943  for( ++c; c < row->len && rational; ++c )
5944  {
5945  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5946  {
5947  val = row->vals[c];
5948  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5949  if( rational && nominator != 0 )
5950  {
5951  assert(denominator > 0);
5952  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5953  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5954  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5955  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5956  val, nominator, denominator, gcd, scm, rational);
5957  }
5958  }
5959  }
5960 
5961  if( rational )
5962  {
5963  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5964  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5965  if( intscalar != NULL )
5966  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5967  *success = TRUE;
5968  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5969  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5970  }
5971  else
5972  {
5973  assert(!(*success));
5974  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5975  }
5976 
5977  return SCIP_OKAY;
5978 }
5979 
5980 /** tries to scale row, s.t. all coefficients become integral */
5982  SCIP_ROW* row, /**< LP row */
5983  BMS_BLKMEM* blkmem, /**< block memory */
5984  SCIP_SET* set, /**< global SCIP settings */
5985  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5986  SCIP_STAT* stat, /**< problem statistics */
5987  SCIP_LP* lp, /**< current LP data */
5988  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5989  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5990  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5991  SCIP_Real maxscale, /**< maximal value to scale row with */
5992  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5993  SCIP_Bool* success /**< stores whether row could be made rational */
5994  )
5995 {
5996  SCIP_Real intscalar;
5997 
5998  assert(success != NULL);
5999 
6000  /* calculate scalar to make coefficients integral */
6001  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
6002  &intscalar, success) );
6003 
6004  if( *success )
6005  {
6006  /* scale the row */
6007  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
6008  }
6009 
6010  return SCIP_OKAY;
6011 }
6012 
6013 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6014  * higher ones
6015  */
6017  SCIP_ROW* row /**< row to be sorted */
6018  )
6019 {
6020  assert(row != NULL);
6021 
6022  /* sort LP columns */
6023  rowSortLP(row);
6024 
6025  /* sort non-LP columns */
6026  rowSortNonLP(row);
6027 
6028 #ifdef SCIP_MORE_DEBUG
6029  /* check the sorting */
6030  {
6031  int c;
6032  if( !row->delaysort )
6033  {
6034  for( c = 1; c < row->nlpcols; ++c )
6035  assert(row->cols[c]->index >= row->cols[c-1]->index);
6036  for( c = row->nlpcols + 1; c < row->len; ++c )
6037  assert(row->cols[c]->index >= row->cols[c-1]->index);
6038  }
6039  }
6040 #endif
6041 }
6042 
6043 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6044  * zero entries from row
6045  * the row must not be linked to the columns; otherwise, we would need to update the columns as
6046  * well, which is too expensive
6047  */
6048 static
6050  SCIP_ROW* row, /**< row to be sorted */
6051  SCIP_SET* set /**< global SCIP settings */
6052  )
6053 {
6054  assert(row != NULL);
6055  assert(!row->delaysort);
6056  assert(row->nunlinked == row->len);
6057  assert(row->nlpcols == 0);
6058 
6059  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6060 
6061  /* do nothing on empty rows; if row is sorted, nothing has to be done */
6062  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6063  {
6064  SCIP_COL** cols;
6065  int* cols_index;
6066  SCIP_Real* vals;
6067  int s;
6068  int t;
6069 
6070  /* make sure, the row is sorted */
6071  SCIProwSort(row);
6072  assert(row->lpcolssorted);
6073  assert(row->nonlpcolssorted);
6074 
6075  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6076  cols = row->cols;
6077  cols_index = row->cols_index;
6078  vals = row->vals;
6079  assert(cols != NULL);
6080  assert(cols_index != NULL);
6081  assert(vals != NULL);
6082 
6083  t = 0;
6084  row->integral = TRUE;
6085  assert(!SCIPsetIsZero(set, vals[0]));
6086  assert(row->linkpos[0] == -1);
6087 
6088  for( s = 1; s < row->len; ++s )
6089  {
6090  assert(!SCIPsetIsZero(set, vals[s]));
6091  assert(row->linkpos[s] == -1);
6092 
6093  if( cols[s] == cols[t] )
6094  {
6095  /* merge entries with equal column */
6096  vals[t] += vals[s];
6097  }
6098  else
6099  {
6100  /* go to the next entry, overwriting current entry if coefficient is zero */
6101  if( !SCIPsetIsZero(set, vals[t]) )
6102  {
6103  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6104  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6105 
6106  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6107  t++;
6108  }
6109  cols[t] = cols[s];
6110  cols_index[t] = cols_index[s];
6111  vals[t] = vals[s];
6112  }
6113  }
6114  if( !SCIPsetIsZero(set, vals[t]) )
6115  {
6116  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6117  t++;
6118  }
6119  assert(s == row->len);
6120  assert(t <= row->len);
6121 
6122  row->len = t;
6123  row->nunlinked = t;
6124 
6125  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6126  if( t < s )
6127  rowCalcNorms(row, set);
6128  }
6129 
6130 #ifndef NDEBUG
6131  /* check for double entries */
6132  {
6133  int i;
6134  int j;
6135 
6136  for( i = 0; i < row->len; ++i )
6137  {
6138  assert(row->cols[i] != NULL);
6139  assert(row->cols[i]->index == row->cols_index[i]);
6140  for( j = i+1; j < row->len; ++j )
6141  assert(row->cols[i] != row->cols[j]);
6142  }
6143  }
6144 #endif
6145 }
6146 
6147 /** enables delaying of row sorting */
6149  SCIP_ROW* row /**< LP row */
6150  )
6151 {
6152  assert(row != NULL);
6153  assert(!row->delaysort);
6154 
6155  row->delaysort = TRUE;
6156 }
6157 
6158 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6160  SCIP_ROW* row, /**< LP row */
6161  SCIP_SET* set /**< global SCIP settings */
6162  )
6163 {
6164  assert(row != NULL);
6165  assert(row->delaysort);
6166 
6167  row->delaysort = FALSE;
6168  rowMerge(row, set);
6169 }
6170 
6171 /** recalculates the current activity of a row */
6173  SCIP_ROW* row, /**< LP row */
6174  SCIP_STAT* stat /**< problem statistics */
6175  )
6176 {
6177  SCIP_COL* col;
6178  int c;
6179 
6180  assert(row != NULL);
6181  assert(stat != NULL);
6182 
6183  row->activity = row->constant;
6184  for( c = 0; c < row->nlpcols; ++c )
6185  {
6186  col = row->cols[c];
6187  assert(col != NULL);
6188  assert(col->primsol != SCIP_INVALID); /*lint !e777*/
6189  assert(col->lppos >= 0);
6190  assert(row->linkpos[c] >= 0);
6191  row->activity += row->vals[c] * col->primsol;
6192  }
6193 
6194  if( row->nunlinked > 0 )
6195  {
6196  for( c = row->nlpcols; c < row->len; ++c )
6197  {
6198  col = row->cols[c];
6199  assert(col != NULL);
6200  assert(col->lppos >= 0 || col->primsol == 0.0);
6201  assert(col->lppos == -1 || row->linkpos[c] == -1);
6202  if( col->lppos >= 0 )
6203  row->activity += row->vals[c] * col->primsol;
6204  }
6205  }
6206 #ifndef NDEBUG
6207  else
6208  {
6209  for( c = row->nlpcols; c < row->len; ++c )
6210  {
6211  col = row->cols[c];
6212  assert(col != NULL);
6213  assert(col->primsol == 0.0);
6214  assert(col->lppos == -1);
6215  assert(row->linkpos[c] >= 0);
6216  }
6217  }
6218 #endif
6219 
6220  row->validactivitylp = stat->lpcount;
6221 }
6222 
6223 /** returns the activity of a row in the current LP solution */
6225  SCIP_ROW* row, /**< LP row */
6226  SCIP_SET* set, /**< global SCIP settings */
6227  SCIP_STAT* stat, /**< problem statistics */
6228  SCIP_LP* lp /**< current LP data */
6229  )
6230 {
6231  SCIP_Real inf;
6232  SCIP_Real activity;
6233 
6234  assert(row != NULL);
6235  assert(stat != NULL);
6236  assert(lp != NULL);
6237  assert(row->validactivitylp <= stat->lpcount);
6238  assert(lp->validsollp == stat->lpcount);
6239 
6240  if( row->validactivitylp != stat->lpcount )
6241  SCIProwRecalcLPActivity(row, stat);
6242  assert(row->validactivitylp == stat->lpcount);
6243  assert(row->activity != SCIP_INVALID); /*lint !e777*/
6244 
6245  activity = row->activity;
6246  inf = SCIPsetInfinity(set);
6247  activity = MAX(activity, -inf);
6248  activity = MIN(activity, +inf);
6249 
6250  return activity;
6251 }
6252 
6253 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6255  SCIP_ROW* row, /**< LP row */
6256  SCIP_SET* set, /**< global SCIP settings */
6257  SCIP_STAT* stat, /**< problem statistics */
6258  SCIP_LP* lp /**< current LP data */
6259  )
6260 {
6261  SCIP_Real activity;
6262 
6263  assert(row != NULL);
6264 
6265  activity = SCIProwGetLPActivity(row, set, stat, lp);
6266 
6267  return MIN(row->rhs - activity, activity - row->lhs);
6268 }
6269 
6270 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6271  *
6272  * @todo Implement calculation of activities similar to LPs.
6273  */
6275  SCIP_ROW* row, /**< LP row */
6276  SCIP_SET* set, /**< global SCIP settings */
6277  SCIP_STAT* stat /**< problem statistics */
6278  )
6279 {
6280  SCIP_Real inf;
6281  SCIP_Real activity;
6282  SCIP_COL* col;
6283  int c;
6284 
6285  assert( row != NULL );
6286  assert( stat != NULL );
6287 
6288  activity = row->constant;
6289  for (c = 0; c < row->nlpcols; ++c)
6290  {
6291  col = row->cols[c];
6292  assert( col != NULL );
6293  assert( col->lppos >= 0 );
6294  assert( col->var != NULL );
6295  assert( row->linkpos[c] >= 0 );
6296  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6297  }
6298 
6299  if ( row->nunlinked > 0 )
6300  {
6301  for (c = row->nlpcols; c < row->len; ++c)
6302  {
6303  col = row->cols[c];
6304  assert( col != NULL );
6305  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6306  if ( col->lppos >= 0 )
6307  {
6308  assert( col->var != NULL );
6309  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6310  }
6311  }
6312  }
6313 #ifndef NDEBUG
6314  else
6315  {
6316  for (c = row->nlpcols; c < row->len; ++c)
6317  {
6318  col = row->cols[c];
6319  assert( col != NULL );
6320  assert( col->lppos == -1 );
6321  assert( row->linkpos[c] >= 0 );
6322  }
6323  }
6324 #endif
6325  inf = SCIPsetInfinity(set);
6326  activity = MAX(activity, -inf);
6327  activity = MIN(activity, +inf);
6328 
6329  return MIN(row->rhs - activity, activity - row->lhs);
6330 }
6331 
6332 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6333  *
6334  * @todo Implement calculation of activities similar to LPs.
6335  */
6337  SCIP_ROW* row, /**< LP row */
6338  SCIP_SET* set, /**< global SCIP settings */
6339  SCIP_STAT* stat /**< problem statistics */
6340  )
6341 {
6342  SCIP_Real inf;
6343  SCIP_Real activity;
6344  SCIP_COL* col;
6345  int c;
6346 
6347  assert( row != NULL );
6348  assert( stat != NULL );
6349 
6350  activity = row->constant;
6351  for (c = 0; c < row->nlpcols; ++c)
6352  {
6353  col = row->cols[c];
6354  assert( col != NULL );
6355  assert( col->lppos >= 0 );
6356  assert( col->var != NULL );
6357  assert( row->linkpos[c] >= 0 );
6358  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6359  }
6360 
6361  if ( row->nunlinked > 0 )
6362  {
6363  for (c = row->nlpcols; c < row->len; ++c)
6364  {
6365  col = row->cols[c];
6366  assert( col != NULL );
6367  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6368  if ( col->lppos >= 0 )
6369  {
6370  assert( col->var != NULL );
6371  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6372  }
6373  }
6374  }
6375 #ifndef NDEBUG
6376  else
6377  {
6378  for (c = row->nlpcols; c < row->len; ++c)
6379  {
6380  col = row->cols[c];
6381  assert( col != NULL );
6382  assert( col->lppos == -1 );
6383  assert( row->linkpos[c] >= 0 );
6384  }
6385  }
6386 #endif
6387  inf = SCIPsetInfinity(set);
6388  activity = MAX(activity, -inf);
6389  activity = MIN(activity, +inf);
6390 
6391  return MIN(row->rhs - activity, activity - row->lhs);
6392 }
6393 
6394 /** calculates the current pseudo activity of a row */
6396  SCIP_ROW* row, /**< row data */
6397  SCIP_STAT* stat /**< problem statistics */
6398  )
6399 {
6400  SCIP_COL* col;
6401  int i;
6402 
6403  assert(row != NULL);
6404  assert(stat != NULL);
6405 
6406  row->pseudoactivity = row->constant;
6407  for( i = 0; i < row->len; ++i )
6408  {
6409  col = row->cols[i];
6410  assert(col != NULL);
6411  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6412  assert(col->var != NULL);
6413  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6414 
6415  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6416  }
6417  row->validpsactivitydomchg = stat->domchgcount;
6418  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6419 }
6420 
6421 /** returns the pseudo activity of a row in the current pseudo solution */
6423  SCIP_ROW* row, /**< LP row */
6424  SCIP_SET* set, /**< global SCIP settings */
6425  SCIP_STAT* stat /**< problem statistics */
6426  )
6427 {
6428  SCIP_Real inf;
6429  SCIP_Real activity;
6430 
6431  assert(row != NULL);
6432  assert(stat != NULL);
6433  assert(row->validpsactivitydomchg <= stat->domchgcount);
6434 
6435  /* check, if pseudo activity has to be calculated */
6436  if( row->validpsactivitydomchg != stat->domchgcount )
6437  SCIProwRecalcPseudoActivity(row, stat);
6438  assert(row->validpsactivitydomchg == stat->domchgcount);
6439  assert(row->pseudoactivity != SCIP_INVALID); /*lint !e777*/
6440 
6441  activity = row->pseudoactivity;
6442  inf = SCIPsetInfinity(set);
6443  activity = MAX(activity, -inf);
6444  activity = MIN(activity, +inf);
6445 
6446  return activity;
6447 }
6448 
6449 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6451  SCIP_ROW* row, /**< LP row */
6452  SCIP_SET* set, /**< global SCIP settings */
6453  SCIP_STAT* stat /**< problem statistics */
6454  )
6455 {
6456  SCIP_Real pseudoactivity;
6457 
6458  assert(row != NULL);
6459 
6460  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6461 
6462  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6463 }
6464 
6465 /** returns the activity of a row for a given solution */
6467  SCIP_ROW* row, /**< LP row */
6468  SCIP_SET* set, /**< global SCIP settings */
6469  SCIP_STAT* stat, /**< problem statistics data */
6470  SCIP_SOL* sol /**< primal CIP solution */
6471  )
6472 {
6473  SCIP_COL* col;
6474  SCIP_Real inf;
6475  SCIP_Real activity;
6476  SCIP_Real solval;
6477  int i;
6478 
6479  assert(row != NULL);
6480 
6481  activity = row->constant;
6482  for( i = 0; i < row->len; ++i )
6483  {
6484  col = row->cols[i];
6485  assert(col != NULL);
6486  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6487  solval = SCIPsolGetVal(sol, set, stat, col->var);
6488  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6489  {
6490  if( SCIPsetIsInfinity(set, -row->lhs) )
6491  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6492  else if( SCIPsetIsInfinity(set, row->rhs) )
6493  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6494  else
6495  solval = (col->lb + col->ub)/2.0;
6496  }
6497  activity += row->vals[i] * solval;
6498  }
6499 
6500  inf = SCIPsetInfinity(set);
6501  activity = MAX(activity, -inf);
6502  activity = MIN(activity, +inf);
6503 
6504  return activity;
6505 }
6506 
6507 /** returns the feasibility of a row for the given solution */
6509  SCIP_ROW* row, /**< LP row */
6510  SCIP_SET* set, /**< global SCIP settings */
6511  SCIP_STAT* stat, /**< problem statistics data */
6512  SCIP_SOL* sol /**< primal CIP solution */
6513  )
6514 {
6515  SCIP_Real activity;
6516 
6517  assert(row != NULL);
6518 
6519  activity = SCIProwGetSolActivity(row, set, stat, sol);
6520 
6521  return MIN(row->rhs - activity, activity - row->lhs);
6522 }
6523 
6524 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6525 static
6527  SCIP_ROW* row, /**< row data */
6528  SCIP_SET* set, /**< global SCIP settings */
6529  SCIP_STAT* stat /**< problem statistics data */
6530  )
6531 {
6532  SCIP_COL* col;
6533  SCIP_Real val;
6534  SCIP_Bool mininfinite;
6535  SCIP_Bool maxinfinite;
6536  int i;
6537 
6538  assert(row != NULL);
6539  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6540  assert(stat != NULL);
6541 
6542  /* calculate activity bounds */
6543  mininfinite = FALSE;
6544  maxinfinite = FALSE;
6545  row->minactivity = row->constant;
6546  row->maxactivity = row->constant;
6547  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6548  {
6549  col = row->cols[i];
6550  assert(col != NULL);
6551  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6552  val = row->vals[i];
6553  if( val >= 0.0 )
6554  {
6555  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6556  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6557  if( !mininfinite )
6558  row->minactivity += val * col->lb;
6559  if( !maxinfinite )
6560  row->maxactivity += val * col->ub;
6561  }
6562  else
6563  {
6564  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6565  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6566  if( !mininfinite )
6567  row->minactivity += val * col->ub;
6568  if( !maxinfinite )
6569  row->maxactivity += val * col->lb;
6570  }
6571  }
6572 
6573  if( mininfinite )
6574  row->minactivity = -SCIPsetInfinity(set);
6575  if( maxinfinite )
6576  row->maxactivity = SCIPsetInfinity(set);
6577  row->validactivitybdsdomchg = stat->domchgcount;
6578 
6579 #ifndef NDEBUG
6580  {
6581  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6582 
6583  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6584  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6585  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6586  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6587  * tolerance as a proxy to account for the accumulation effect
6588  */
6589  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6590  || EPSISINT(row->minactivity - row->constant, inttol));
6591  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6592  || EPSISINT(row->maxactivity - row->constant, inttol));
6593  }
6594 #endif
6595 }
6596 
6597 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6599  SCIP_ROW* row, /**< LP row */
6600  SCIP_SET* set, /**< global SCIP settings */
6601  SCIP_STAT* stat /**< problem statistics data */
6602  )
6603 {
6604  assert(row != NULL);
6605  assert(stat != NULL);
6606  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6607 
6608  /* check, if activity bounds has to be calculated */
6609  if( row->validactivitybdsdomchg != stat->domchgcount )
6610  rowCalcActivityBounds(row, set, stat);
6611  assert(row->validactivitybdsdomchg == stat->domchgcount);
6612  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6613  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6614 
6615  return row->minactivity;
6616 }
6617 
6618 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6620  SCIP_ROW* row, /**< LP row */
6621  SCIP_SET* set, /**< global SCIP settings */
6622  SCIP_STAT* stat /**< problem statistics data */
6623  )
6624 {
6625  assert(row != NULL);
6626  assert(stat != NULL);
6627  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6628 
6629  /* check, if activity bounds has to be calculated */
6630  if( row->validactivitybdsdomchg != stat->domchgcount )
6631  rowCalcActivityBounds(row, set, stat);
6632  assert(row->validactivitybdsdomchg == stat->domchgcount);
6633  assert(row->minactivity != SCIP_INVALID); /*lint !e777*/
6634  assert(row->maxactivity != SCIP_INVALID); /*lint !e777*/
6635 
6636  return row->maxactivity;
6637 }
6638 
6639 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6641  SCIP_ROW* row, /**< LP row */
6642  SCIP_SET* set, /**< global SCIP settings */
6643  SCIP_STAT* stat /**< problem statistics data */
6644  )
6645 {
6646  assert(row != NULL);
6647 
6648  if( row->modifiable )
6649  return FALSE;
6650  if( !SCIPsetIsInfinity(set, -row->lhs) )
6651  {
6652  SCIP_Real minactivity;
6653 
6654  minactivity = SCIProwGetMinActivity(row, set, stat);
6655  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6656  return FALSE;
6657  }
6658  if( !SCIPsetIsInfinity(set, row->rhs) )
6659  {
6660  SCIP_Real maxactivity;
6661 
6662  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6663  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6664  return FALSE;
6665  }
6666 
6667  return TRUE;
6668 }
6669 
6670 /** gets maximal absolute value of row vector coefficients */
6672  SCIP_ROW* row, /**< LP row */
6673  SCIP_SET* set /**< global SCIP settings */
6674  )
6675 {
6676  assert(row != NULL);
6677 
6678  if( row->nummaxval == 0 )
6679  rowCalcIdxsAndVals(row, set);
6680  assert(row->nummaxval > 0);
6681  assert(row->maxval >= 0.0 || row->len == 0);
6682 
6683  return row->maxval;
6684 }
6685 
6686 /** gets minimal absolute value of row vector's non-zero coefficients */
6688  SCIP_ROW* row, /**< LP row */
6689  SCIP_SET* set /**< global SCIP settings */
6690  )
6691 {
6692  assert(row != NULL);
6693 
6694  if( row->numminval == 0 )
6695  rowCalcIdxsAndVals(row, set);
6696  assert(row->numminval > 0);
6697  assert(row->minval >= 0.0 || row->len == 0);
6698 
6699  return row->minval;
6700 }
6701 
6702 /** gets maximal column index of row entries */
6704  SCIP_ROW* row, /**< LP row */
6705  SCIP_SET* set /**< global SCIP settings */
6706  )
6707 {
6708  assert(row != NULL);
6709 
6710  if( row->validminmaxidx == 0 )
6711  rowCalcIdxsAndVals(row, set);
6712  assert(row->maxidx >= 0 || row->len == 0);
6713  assert(row->validminmaxidx);
6714 
6715  return row->maxidx;
6716 }
6717 
6718 /** gets minimal column index of row entries */
6720  SCIP_ROW* row, /**< LP row */
6721  SCIP_SET* set /**< global SCIP settings */
6722  )
6723 {
6724  assert(row != NULL);
6725 
6726  if( row->validminmaxidx == 0 )
6727  rowCalcIdxsAndVals(row, set);
6728  assert(row->minidx >= 0 || row->len == 0);
6729  assert(row->validminmaxidx);
6730 
6731  return row->minidx;
6732 }
6733 
6734 /** gets number of integral columns in row */
6736  SCIP_ROW* row, /**< LP row */
6737  SCIP_SET* set /**< global SCIP settings */
6738  )
6739 {
6740  assert(row != NULL);
6741 
6742  if( row->numintcols == -1 )
6743  rowCalcIdxsAndVals(row, set);
6744 
6745  assert(row->numintcols <= row->len && row->numintcols >= 0);
6746 
6747  return row->numintcols;
6748 }
6749 
6750 /** returns row's cutoff distance in the direction of the given primal solution */
6752  SCIP_ROW* row, /**< LP row */
6753  SCIP_SET* set, /**< global SCIP settings */
6754  SCIP_STAT* stat, /**< problem statistics data */
6755  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6756  SCIP_LP* lp /**< current LP data */
6757  )
6758 {
6759  SCIP_Real solcutoffdist;
6760  int k;
6761 
6762  assert(sol != NULL);
6763 
6764  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6765  {
6766  SCIP_Real scale = 0.0;
6767 
6768  lp->validsoldirlp = stat->lpcount;
6769  lp->validsoldirsol = sol;
6770 
6772 
6773  for( k = 0; k < lp->ncols; ++k )
6774  {
6775  assert(lp->cols[k]->lppos == k);
6776  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6777  scale += SQR(lp->soldirection[k]);
6778  }
6779 
6780  if( scale > 0.0 )
6781  {
6782  scale = 1.0 / sqrt(scale);
6783 
6784  for( k = 0; k < lp->ncols; ++k )
6785  lp->soldirection[k] *= scale;
6786  }
6787  }
6788 
6789  solcutoffdist = 0.0;
6790  for( k = 0; k < row->nlpcols; ++k )
6791  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6792 
6793  for( k = row->nlpcols; k < row->len; ++k )
6794  {
6795  if( row->cols[k]->lppos >= 0 )
6796  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6797  }
6798 
6799  if( SCIPsetIsSumZero(set, solcutoffdist) )
6800  solcutoffdist = set->num_sumepsilon;
6801 
6802  solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
6803 
6804  return solcutoffdist;
6805 }
6806 
6807 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6809  SCIP_ROW* row, /**< LP row */
6810  SCIP_SET* set, /**< global SCIP settings */
6811  SCIP_STAT* stat, /**< problem statistics data */
6812  SCIP_LP* lp /**< current LP data */
6813  )
6814 {
6815  SCIP_Real norm;
6816  SCIP_Real feasibility;
6817  SCIP_Real eps;
6818 
6819  assert(set != NULL);
6820 
6821  switch( set->sepa_efficacynorm )
6822  {
6823  case 'e':
6824  norm = SCIProwGetNorm(row);
6825  break;
6826  case 'm':
6827  norm = SCIProwGetMaxval(row, set);
6828  break;
6829  case 's':
6830  norm = SCIProwGetSumNorm(row);
6831  break;
6832  case 'd':
6833  norm = (row->len == 0 ? 0.0 : 1.0);
6834  break;
6835  default:
6836  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6837  SCIPABORT();
6838  norm = 0.0; /*lint !e527*/
6839  }
6840 
6841  eps = SCIPsetSumepsilon(set);
6842  norm = MAX(norm, eps);
6843  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6844 
6845  return -feasibility / norm;
6846 }
6847 
6848 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6850  SCIP_ROW* row, /**< LP row */
6851  SCIP_SET* set, /**< global SCIP settings */
6852  SCIP_STAT* stat, /**< problem statistics data */
6853  SCIP_LP* lp, /**< current LP data */
6854  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6855  )
6856 {
6857  SCIP_Real efficacy;
6858 
6859  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6860 
6861  return SCIPsetIsEfficacious(set, root, efficacy);
6862 }
6863 
6864 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6866  SCIP_ROW* row, /**< LP row */
6867  SCIP_SET* set, /**< global SCIP settings */
6868  SCIP_STAT* stat, /**< problem statistics data */
6869  SCIP_SOL* sol /**< primal CIP solution */
6870  )
6871 {
6872  SCIP_Real norm;
6873  SCIP_Real feasibility;
6874  SCIP_Real eps;
6875 
6876  assert(set != NULL);
6877 
6878  switch( set->sepa_efficacynorm )
6879  {
6880  case 'e':
6881  norm = SCIProwGetNorm(row);
6882  break;
6883  case 'm':
6884  norm = SCIProwGetMaxval(row, set);
6885  break;
6886  case 's':
6887  norm = SCIProwGetSumNorm(row);
6888  break;
6889  case 'd':
6890  norm = (row->len == 0 ? 0.0 : 1.0);
6891  break;
6892  default:
6893  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6894  SCIPABORT();
6895  norm = 0.0; /*lint !e527*/
6896  }
6897 
6898  eps = SCIPsetSumepsilon(set);
6899  norm = MAX(norm, eps);
6900  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6901 
6902  return -feasibility / norm;
6903 }
6904 
6905 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6906  * efficacy
6907  */
6909  SCIP_ROW* row, /**< LP row */
6910  SCIP_SET* set, /**< global SCIP settings */
6911  SCIP_STAT* stat, /**< problem statistics data */
6912  SCIP_SOL* sol, /**< primal CIP solution */
6913  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6914  )
6915 {
6916  SCIP_Real efficacy;
6917 
6918  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6919 
6920  return SCIPsetIsEfficacious(set, root, efficacy);
6921 }
6922 
6923 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6925  SCIP_ROW* row, /**< LP row */
6926  SCIP_SET* set, /**< global SCIP settings */
6927  SCIP_STAT* stat /**< problem statistics data */
6928  )
6929 {
6930  SCIP_Real norm;
6931  SCIP_Real feasibility;
6932  SCIP_Real eps;
6933 
6934  assert(set != NULL);
6935 
6936  switch( set->sepa_efficacynorm )
6937  {
6938  case 'e':
6939  norm = SCIProwGetNorm(row);
6940  break;
6941  case 'm':
6942  norm = SCIProwGetMaxval(row, set);
6943  break;
6944  case 's':
6945  norm = SCIProwGetSumNorm(row);
6946  break;
6947  case 'd':
6948  norm = (row->len == 0 ? 0.0 : 1.0);
6949  break;
6950  default:
6951  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6952  SCIPABORT();
6953  norm = 0.0; /*lint !e527*/
6954  }
6955 
6956  eps = SCIPsetSumepsilon(set);
6957  norm = MAX(norm, eps);
6958  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6959 
6960  return -feasibility / norm;
6961 }
6962 
6963 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6965  SCIP_ROW* row, /**< LP row */
6966  SCIP_SET* set, /**< global SCIP settings */
6967  SCIP_STAT* stat /**< problem statistics data */
6968  )
6969 {
6970  SCIP_Real norm;
6971  SCIP_Real feasibility;
6972  SCIP_Real eps;
6973 
6974  assert(set != NULL);
6975 
6976  switch( set->sepa_efficacynorm )
6977  {
6978  case 'e':
6979  norm = SCIProwGetNorm(row);
6980  break;
6981  case 'm':
6982  norm = SCIProwGetMaxval(row, set);
6983  break;
6984  case 's':
6985  norm = SCIProwGetSumNorm(row);
6986  break;
6987  case 'd':
6988  norm = (row->len == 0 ? 0.0 : 1.0);
6989  break;
6990  default:
6991  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6992  SCIPABORT();
6993  norm = 0.0; /*lint !e527*/
6994  }
6995 
6996  eps = SCIPsetSumepsilon(set);
6997  norm = MAX(norm, eps);
6998  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6999 
7000  return -feasibility / norm;
7001 }
7002 
7003 /** returns the scalar product of the coefficient vectors of the two given rows
7004  *
7005  * @note the scalar product is computed w.r.t. the current LP columns only
7006  * @todo also consider non-LP columns for the computation?
7007  */
7009  SCIP_ROW* row1, /**< first LP row */
7010  SCIP_ROW* row2 /**< second LP row */
7011  )
7012 {
7013  SCIP_Real scalarprod;
7014  int* row1colsidx;
7015  int* row2colsidx;
7016  int i1;
7017  int i2;
7018 
7019  assert(row1 != NULL);
7020  assert(row2 != NULL);
7021 
7022  /* Sort the column indices of both rows.
7023  *
7024  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7025  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7026  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7027  * for both or one of the non-LP columns for both.
7028  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7029  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7030  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7031  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7032  *
7033  * We distinguish the following cases:
7034  *
7035  * 1) both rows have no unlinked columns
7036  * -> we just check the LP partitions
7037  *
7038  * 2) exactly one row is completely unlinked, the other one is completely linked
7039  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7040  * (thus all common LP columns are regarded)
7041  *
7042  * 3) we have unlinked and LP columns in both rows
7043  * -> we need to compare four partitions at once
7044  *
7045  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7046  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7047  * other row
7048  *
7049  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7050  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7051  *
7052  * 5) both rows are completely unlinked
7053  * -> we need to compare two partitions: both complete rows
7054  */
7055  SCIProwSort(row1);
7056  assert(row1->lpcolssorted);
7057  assert(row1->nonlpcolssorted);
7058  SCIProwSort(row2);
7059  assert(row2->lpcolssorted);
7060  assert(row2->nonlpcolssorted);
7061 
7062  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7063  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7064 
7065  row1colsidx = row1->cols_index;
7066  row2colsidx = row2->cols_index;
7067 
7068 #ifndef NDEBUG
7069  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7070  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7071  {
7072  i1 = 0;
7073  i2 = row2->nlpcols;
7074  while( i1 < row1->nlpcols && i2 < row2->len )
7075  {
7076  assert(row1->cols[i1] != row2->cols[i2]);
7077  if( row1->cols[i1]->index < row2->cols[i2]->index )
7078  ++i1;
7079  else
7080  {
7081  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7082  ++i2;
7083  }
7084  }
7085  assert(i1 == row1->nlpcols || i2 == row2->len);
7086 
7087  i1 = row1->nlpcols;
7088  i2 = 0;
7089  while( i1 < row1->len && i2 < row2->nlpcols )
7090  {
7091  assert(row1->cols[i1] != row2->cols[i2]);
7092  if( row1->cols[i1]->index < row2->cols[i2]->index )
7093  ++i1;
7094  else
7095  {
7096  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7097  ++i2;
7098  }
7099  }
7100  assert(i1 == row1->len || i2 == row2->nlpcols);
7101  }
7102 #endif
7103 
7104  /* The "easy" cases 1) and 2) */
7105  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7106  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7107  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7108  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7109  {
7110  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7111  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7112 
7113  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7114  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7115  */
7116  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7117  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7118  scalarprod = 0.0;
7119 
7120  /* calculate the scalar product */
7121  while( i1 >= 0 && i2 >= 0 )
7122  {
7123  assert(row1->cols[i1]->index == row1colsidx[i1]);
7124  assert(row2->cols[i2]->index == row2colsidx[i2]);
7125  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7126  if( row1colsidx[i1] < row2colsidx[i2] )
7127  --i2;
7128  else if( row1colsidx[i1] > row2colsidx[i2] )
7129  --i1;
7130  else
7131  {
7132  scalarprod += row1->vals[i1] * row2->vals[i2];
7133  --i1;
7134  --i2;
7135  }
7136  }
7137  }
7138  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7139  else
7140  {
7141  SCIP_Bool lpcols;
7142  int ilp1;
7143  int inlp1;
7144  int ilp2;
7145  int inlp2;
7146  int end1;
7147  int end2;
7148 
7149  scalarprod = 0;
7150  ilp1 = 0;
7151  ilp2 = 0;
7152 
7153  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7154  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7155  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7156 
7157  /* handle the case of four partitions (case 3) until one partition is finished;
7158  * cases 4a), 4b), and 5) will fail the while-condition
7159  */
7160  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7161  {
7162  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7163  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7164  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7165  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7166  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7167  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7168  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7169  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7170 
7171  /* rows have the same linked LP columns */
7172  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7173  {
7174  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7175  ++ilp1;
7176  ++ilp2;
7177  }
7178  /* LP column of row1 is the same as unlinked column of row2 */
7179  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7180  {
7181  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7182  ++ilp1;
7183  ++inlp2;
7184  }
7185  /* unlinked column of row1 is the same as LP column of row2 */
7186  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7187  {
7188  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7189  ++inlp1;
7190  ++ilp2;
7191  }
7192  /* two unlinked LP columns are the same */
7193  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7194  {
7195  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7196  ++inlp1;
7197  ++inlp2;
7198  }
7199  /* increase smallest counter */
7200  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7201  {
7202  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7203  {
7204  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7205  ++ilp1;
7206  else
7207  ++ilp2;
7208  }
7209  else
7210  {
7211  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7212  ++ilp1;
7213  else
7214  ++inlp2;
7215  }
7216  }
7217  else
7218  {
7219  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7220  {
7221  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7222  ++inlp1;
7223  else
7224  ++ilp2;
7225  }
7226  else
7227  {
7228  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7229  ++inlp1;
7230  else
7231  ++inlp2;
7232  }
7233  }
7234  }
7235 
7236  /* One partition was completely handled, we just have to handle the three remaining partitions:
7237  * the remaining partition of this row and the two partitions of the other row.
7238  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7239  */
7240  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7241  {
7242  int tmpilp;
7243  int tmpinlp;
7244 
7245  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7246 
7247  SCIPswapPointers((void**) &row1, (void**) &row2);
7248  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7249  tmpilp = ilp1;
7250  tmpinlp = inlp1;
7251  ilp1 = ilp2;
7252  inlp1 = inlp2;
7253  ilp2 = tmpilp;
7254  inlp2 = tmpinlp;
7255  }
7256 
7257  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7258  * -> this merges cases 4a) and 4b)
7259  */
7260  if( ilp1 == row1->nlpcols )
7261  {
7262  i1 = inlp1;
7263  end1 = row1->len;
7264  lpcols = FALSE;
7265  }
7266  else
7267  {
7268  assert(inlp1 == row1->len);
7269 
7270  i1 = ilp1;
7271  end1 = row1->nlpcols;
7272  lpcols = TRUE;
7273  }
7274 
7275  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7276  * case 5) will fail the while-condition
7277  */
7278  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7279  {
7280  assert(row1->cols[i1]->index == row1colsidx[i1]);
7281  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7282  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7283  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7284  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7285 
7286  /* current column in row 1 is the same as the current LP column in row 2 */
7287  if( row1colsidx[i1] == row2colsidx[ilp2] )
7288  {
7289  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7290  ++i1;
7291  ++ilp2;
7292  }
7293  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7294  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7295  {
7296  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7297  ++i1;
7298  ++inlp2;
7299  }
7300  /* increase smallest counter */
7301  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7302  {
7303  if( row1colsidx[i1] < row2colsidx[ilp2] )
7304  ++i1;
7305  else
7306  ++ilp2;
7307  }
7308  else
7309  {
7310  if( row1colsidx[i1] < row2colsidx[inlp2] )
7311  ++i1;
7312  else
7313  ++inlp2;
7314  }
7315  }
7316 
7317  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7318  * the two rows
7319  */
7320  if( i1 < end1 )
7321  {
7322  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7323  if( ilp2 == row2->nlpcols )
7324  {
7325  i2 = inlp2;
7326  end2 = row2->len;
7327  lpcols = FALSE;
7328  }
7329  else
7330  {
7331  assert(inlp2 == row2->len);
7332 
7333  i2 = ilp2;
7334  end2 = row2->nlpcols;
7335  }
7336 
7337  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7338  while( i1 < end1 && i2 < end2 )
7339  {
7340  assert(row1->cols[i1]->index == row1colsidx[i1]);
7341  assert(row2->cols[i2]->index == row2colsidx[i2]);
7342  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7343 
7344  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7345  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7346  {
7347  scalarprod += row1->vals[i1] * row2->vals[i2];
7348  ++i1;
7349  ++i2;
7350  }
7351  /* increase smallest counter */
7352  else if( row1colsidx[i1] < row2colsidx[i2] )
7353  ++i1;
7354  else
7355  ++i2;
7356  }
7357  }
7358  }
7359 
7360  return scalarprod;
7361 }
7362 
7363 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7364 static
7366  SCIP_ROW* row1, /**< first LP row */
7367  SCIP_ROW* row2 /**< second LP row */
7368  )
7369 {
7370  int prod;
7371  int* row1colsidx;
7372  int* row2colsidx;
7373  int i1;
7374  int i2;
7375 
7376  assert(row1 != NULL);
7377  assert(row2 != NULL);
7378 
7379  /* Sort the column indices of both rows.
7380  *
7381  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7382  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7383  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7384  * for both or one of the non-LP columns for both.
7385  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7386  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7387  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7388  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7389  *
7390  * We distinguish the following cases:
7391  *
7392  * 1) both rows have no unlinked columns
7393  * -> we just check the LP partitions
7394  *
7395  * 2) exactly one row is completely unlinked, the other one is completely linked
7396  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7397  * (thus all common LP columns are regarded)
7398  *
7399  * 3) we have unlinked and LP columns in both rows
7400  * -> we need to compare four partitions at once
7401  *
7402  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7403  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7404  * other row
7405  *
7406  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7407  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7408  *
7409  * 5) both rows are completely unlinked
7410  * -> we need to compare two partitions: both complete rows
7411  */
7412  SCIProwSort(row1);
7413  assert(row1->lpcolssorted);
7414  assert(row1->nonlpcolssorted);
7415  SCIProwSort(row2);
7416  assert(row2->lpcolssorted);
7417  assert(row2->nonlpcolssorted);
7418 
7419  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7420  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7421 
7422  row1colsidx = row1->cols_index;
7423  row2colsidx = row2->cols_index;
7424 
7425 #ifndef NDEBUG
7426  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7427  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7428  {
7429  i1 = 0;
7430  i2 = row2->nlpcols;
7431  while( i1 < row1->nlpcols && i2 < row2->len )
7432  {
7433  assert(row1->cols[i1] != row2->cols[i2]);
7434  if( row1->cols[i1]->index < row2->cols[i2]->index )
7435  ++i1;
7436  else
7437  {
7438  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7439  ++i2;
7440  }
7441  }
7442  assert(i1 == row1->nlpcols || i2 == row2->len);
7443 
7444  i1 = row1->nlpcols;
7445  i2 = 0;
7446  while( i1 < row1->len && i2 < row2->nlpcols )
7447  {
7448  assert(row1->cols[i1] != row2->cols[i2]);
7449  if( row1->cols[i1]->index < row2->cols[i2]->index )
7450  ++i1;
7451  else
7452  {
7453  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7454  ++i2;
7455  }
7456  }
7457  assert(i1 == row1->len || i2 == row2->nlpcols);
7458  }
7459 #endif
7460 
7461  /* The "easy" cases 1) and 2) */
7462  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7463  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7464  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7465  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7466  {
7467  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7468  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7469 
7470  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7471  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7472  */
7473  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7474  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7475  prod = 0;
7476 
7477  /* calculate the scalar product */
7478  while( i1 >= 0 && i2 >= 0 )
7479  {
7480  assert(row1->cols[i1]->index == row1colsidx[i1]);
7481  assert(row2->cols[i2]->index == row2colsidx[i2]);
7482  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7483  if( row1colsidx[i1] < row2colsidx[i2] )
7484  --i2;
7485  else if( row1colsidx[i1] > row2colsidx[i2] )
7486  --i1;
7487  else
7488  {
7489  ++prod;
7490  --i1;
7491  --i2;
7492  }
7493  }
7494  }
7495  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7496  else
7497  {
7498  SCIP_Bool lpcols;
7499  int ilp1;
7500  int inlp1;
7501  int ilp2;
7502  int inlp2;
7503  int end1;
7504  int end2;
7505 
7506  prod = 0;
7507  ilp1 = 0;
7508  ilp2 = 0;
7509 
7510  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7511  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7512  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7513 
7514  /* handle the case of four partitions (case 3) until one partition is finished;
7515  * cases 4a), 4b), and 5) will fail the while-condition
7516  */
7517  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7518  {
7519  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7520  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7521  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7522  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7523  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7524  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7525  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7526  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7527 
7528  /* rows have the same linked LP columns */
7529  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7530  {
7531  ++prod;
7532  ++ilp1;
7533  ++ilp2;
7534  }
7535  /* LP column of row1 is the same as unlinked column of row2 */
7536  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7537  {
7538  ++prod;
7539  ++ilp1;
7540  ++inlp2;
7541  }
7542  /* unlinked column of row1 is the same as LP column of row2 */
7543  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7544  {
7545  ++prod;
7546  ++inlp1;
7547  ++ilp2;
7548  }
7549  /* two unlinked LP columns are the same */
7550  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7551  {
7552  ++prod;
7553  ++inlp1;
7554  ++inlp2;
7555  }
7556  /* increase smallest counter */
7557  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7558  {
7559  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7560  {
7561  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7562  ++ilp1;
7563  else
7564  ++ilp2;
7565  }
7566  else
7567  {
7568  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7569  ++ilp1;
7570  else
7571  ++inlp2;
7572  }
7573  }
7574  else
7575  {
7576  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7577  {
7578  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7579  ++inlp1;
7580  else
7581  ++ilp2;
7582  }
7583  else
7584  {
7585  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7586  ++inlp1;
7587  else
7588  ++inlp2;
7589  }
7590  }
7591  }
7592 
7593  /* One partition was completely handled, we just have to handle the three remaining partitions:
7594  * the remaining partition of this row and the two partitions of the other row.
7595  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7596  */
7597  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7598  {
7599  int tmpilp;
7600  int tmpinlp;
7601 
7602  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7603 
7604  SCIPswapPointers((void**) &row1, (void**) &row2);
7605  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7606  tmpilp = ilp1;
7607  tmpinlp = inlp1;
7608  ilp1 = ilp2;
7609  inlp1 = inlp2;
7610  ilp2 = tmpilp;
7611  inlp2 = tmpinlp;
7612  }
7613 
7614  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7615  * -> this merges cases 4a) and 4b)
7616  */
7617  if( ilp1 == row1->nlpcols )
7618  {
7619  i1 = inlp1;
7620  end1 = row1->len;
7621  lpcols = FALSE;
7622  }
7623  else
7624  {
7625  assert(inlp1 == row1->len);
7626 
7627  i1 = ilp1;
7628  end1 = row1->nlpcols;
7629  lpcols = TRUE;
7630  }
7631 
7632  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7633  * case 5) will fail the while-condition
7634  */
7635  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7636  {
7637  assert(row1->cols[i1]->index == row1colsidx[i1]);
7638  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7639  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7640  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7641  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7642 
7643  /* current column in row 1 is the same as the current LP column in row 2 */
7644  if( row1colsidx[i1] == row2colsidx[ilp2] )
7645  {
7646  ++prod;
7647  ++i1;
7648  ++ilp2;
7649  }
7650  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7651  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7652  {
7653  ++prod;
7654  ++i1;
7655  ++inlp2;
7656  }
7657  /* increase smallest counter */
7658  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7659  {
7660  if( row1colsidx[i1] < row2colsidx[ilp2] )
7661  ++i1;
7662  else
7663  ++ilp2;
7664  }
7665  else
7666  {
7667  if( row1colsidx[i1] < row2colsidx[inlp2] )
7668  ++i1;
7669  else
7670  ++inlp2;
7671  }
7672  }
7673 
7674  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7675  * the two rows
7676  */
7677  if( i1 < end1 )
7678  {
7679  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7680  if( ilp2 == row2->nlpcols )
7681  {
7682  i2 = inlp2;
7683  end2 = row2->len;
7684  lpcols = FALSE;
7685  }
7686  else
7687  {
7688  assert(inlp2 == row2->len);
7689 
7690  i2 = ilp2;
7691  end2 = row2->nlpcols;
7692  }
7693 
7694  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7695  while( i1 < end1 && i2 < end2 )
7696  {
7697  assert(row1->cols[i1]->index == row1colsidx[i1]);
7698  assert(row2->cols[i2]->index == row2colsidx[i2]);
7699  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7700 
7701  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7702  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7703  {
7704  ++prod;
7705  ++i1;
7706  ++i2;
7707  }
7708  /* increase smallest counter */
7709  else if( row1colsidx[i1] < row2colsidx[i2] )
7710  ++i1;
7711  else
7712  ++i2;
7713  }
7714  }
7715  }
7716 
7717  return prod;
7718 }
7719 
7720 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7721  * p = |v*w|/(|v|*|w|);
7722  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7723  */
7725  SCIP_ROW* row1, /**< first LP row */
7726  SCIP_ROW* row2, /**< second LP row */
7727  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7728  )
7729 {
7730  SCIP_Real parallelism;
7731  SCIP_Real scalarprod;
7732 
7733  switch( orthofunc )
7734  {
7735  case 'e':
7736  scalarprod = SCIProwGetScalarProduct(row1, row2);
7737  if( scalarprod == 0.0 )
7738  {
7739  parallelism = 0.0;
7740  break;
7741  }
7742 
7743  if( SCIProwGetNorm(row1) == 0.0 )
7744  {
7745  /* In theory, this should not happen if the scalarproduct is not zero
7746  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7747  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7748  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7749  */
7750  int i;
7751  for( i = 0; i < row1->len; ++i )
7752  if( row1->cols[i]->lppos >= 0 )
7753  row1->sqrnorm += SQR(row1->vals[i]);
7754  assert(SCIProwGetNorm(row1) != 0.0);
7755  }
7756 
7757  if( SCIProwGetNorm(row2) == 0.0 )
7758  {
7759  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7760  int i;
7761  for( i = 0; i < row2->len; ++i )
7762  if( row2->cols[i]->lppos >= 0 )
7763  row2->sqrnorm += SQR(row2->vals[i]);
7764  assert(SCIProwGetNorm(row2) != 0.0);
7765  }
7766 
7767  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7768  break;
7769 
7770  case 'd':
7771  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7772  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7773  break;
7774 
7775  default:
7776  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7777  SCIPABORT();
7778  parallelism = 0.0; /*lint !e527*/
7779  }
7780 
7781  return parallelism;
7782 }
7783 
7784 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7785  * o = 1 - |v*w|/(|v|*|w|);
7786  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7787  */
7789  SCIP_ROW* row1, /**< first LP row */
7790  SCIP_ROW* row2, /**< second LP row */
7791  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7792  )
7793 {
7794  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7795 }
7796 
7797 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7798  * function, if the value is 0, it is orthogonal to the objective function
7799  */
7801  SCIP_ROW* row, /**< LP row */
7802  SCIP_SET* set, /**< global SCIP settings */
7803  SCIP_LP* lp /**< current LP data */
7804  )
7805 {
7806  SCIP_Real prod;
7807  SCIP_Real parallelism;
7808 
7809  assert(row != NULL);
7810  assert(lp != NULL);
7811 
7812  if( lp->objsqrnormunreliable )
7813  SCIPlpRecalculateObjSqrNorm(set, lp);
7814 
7815  assert(!lp->objsqrnormunreliable);
7816  assert(lp->objsqrnorm >= 0.0);
7817 
7818  checkRowSqrnorm(row);
7819  checkRowObjprod(row);
7820 
7821  prod = row->sqrnorm * lp->objsqrnorm;
7822 
7823  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / sqrt(prod) : 0.0;
7824  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7825  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7826  parallelism = MIN(parallelism, 1.0);
7827  parallelism = MAX(parallelism, 0.0);
7828 
7829  return parallelism;
7830 }
7831 
7832 /** includes event handler with given data in row's event filter */
7834  SCIP_ROW* row, /**< row */
7835  BMS_BLKMEM* blkmem, /**< block memory */
7836  SCIP_SET* set, /**< global SCIP settings */
7837  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7838  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7839  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7840  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7841  )
7842 {
7843  assert(row != NULL);
7844  assert(row->eventfilter != NULL);
7845  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7846  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7847 
7848  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7849  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7850 
7851  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7852 
7853  return SCIP_OKAY;
7854 }
7855 
7856 /** deletes event handler with given data from row's event filter */
7858  SCIP_ROW* row, /**< row */
7859  BMS_BLKMEM* blkmem, /**< block memory */
7860  SCIP_SET* set, /**< global SCIP settings */
7861  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7862  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7863  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7864  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7865  )
7866 {
7867  assert(row != NULL);
7868  assert(row->eventfilter != NULL);
7869 
7870  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7871 
7872  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7873 
7874  return SCIP_OKAY;
7875 }
7876 
7877 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7879  SCIP_ROW* row, /**< LP row */
7880  SCIP_STAT* stat /**< problem statistics */
7881  )
7882 {
7883  assert(row != NULL);
7884  assert(stat != NULL);
7885  assert(stat->nnodes > 0);
7886 
7887  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7888  row->obsoletenode = stat->nnodes;
7889 }
7890 
7891 /*
7892  * LP solver data update
7893  */
7894 
7895 /** resets column data to represent a column not in the LP solver */
7896 static
7898  SCIP_COL* col /**< column to be marked deleted */
7899  )
7900 {
7901  assert(col != NULL);
7902 
7903  col->lpipos = -1;
7904  col->primsol = 0.0;
7905  col->redcost = SCIP_INVALID;
7906  col->farkascoef = SCIP_INVALID;
7907  col->sbdown = SCIP_INVALID;
7908  col->sbup = SCIP_INVALID;
7909  col->sbdownvalid = FALSE;
7910  col->sbupvalid = FALSE;
7911  col->validredcostlp = -1;
7912  col->validfarkaslp = -1;
7913  col->sbitlim = -1;
7914  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7915 }
7916 
7917 /** applies all cached column removals to the LP solver */
7918 static
7920  SCIP_LP* lp /**< current LP data */
7921  )
7922 {
7923  assert(lp != NULL);
7924  assert(lp->lpifirstchgcol <= lp->nlpicols);
7925  assert(lp->lpifirstchgcol <= lp->ncols);
7926 
7927  /* find the first column to change */
7928  while( lp->lpifirstchgcol < lp->nlpicols
7929  && lp->lpifirstchgcol < lp->ncols
7930  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7931  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7932  {
7933  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7934  lp->lpifirstchgcol++;
7935  }
7936 
7937  /* shrink LP to the part which didn't change */
7938  if( lp->lpifirstchgcol < lp->nlpicols )
7939  {
7940  int i;
7941 
7942  assert(!lp->diving);
7943  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7944  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7945  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7946  {
7947  markColDeleted(lp->lpicols[i]);
7948  }
7949  lp->nlpicols = lp->lpifirstchgcol;
7950  lp->flushdeletedcols = TRUE;
7951  lp->updateintegrality = TRUE;
7952 
7953  /* mark the LP unsolved */
7954  lp->solved = FALSE;
7955  lp->primalfeasible = FALSE;
7956  lp->primalchecked = FALSE;
7957  lp->lpobjval = SCIP_INVALID;
7959  }
7960  assert(lp->nlpicols == lp->lpifirstchgcol);
7961 
7962  return SCIP_OKAY;
7963 }
7964 
7965 /** computes for the given column the lower and upper bound that should be flushed into the LP
7966  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7967  * the bounds are explicitly added to the LP in any case
7968  */
7969 static
7971  SCIP_LP* lp, /**< current LP data */
7972  SCIP_SET* set, /**< global SCIP settings */
7973  SCIP_COL* col, /**< column to compute bounds for */
7974  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7975  SCIP_Real* lb, /**< pointer to store the new lower bound */
7976  SCIP_Real* ub /**< pointer to store the new upper bound */
7977  )
7978 {
7979  assert(lp != NULL);
7980  assert(set != NULL);
7981  assert(col != NULL);
7982  assert(lb != NULL);
7983  assert(ub != NULL);
7984 
7985  /* get the correct new lower bound:
7986  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7987  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7988  */
7989  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7990  (*lb) = -lpiinf;
7991  else
7992  (*lb) = col->lb;
7993  /* get the correct new upper bound:
7994  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7995  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7996  */
7997  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7998  (*ub) = lpiinf;
7999  else
8000  (*ub) = col->ub;
8001 }
8002 
8003 /** applies all cached column additions to the LP solver */
8004 static
8006  SCIP_LP* lp, /**< current LP data */
8007  BMS_BLKMEM* blkmem, /**< block memory */
8008  SCIP_SET* set, /**< global SCIP settings */
8009  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8010  )
8011 {
8012  SCIP_Real* obj;
8013  SCIP_Real* lb;
8014  SCIP_Real* ub;
8015  int* beg;
8016  int* ind;
8017  SCIP_Real* val;
8018  char** name;
8019  SCIP_COL* col;
8020  SCIP_Real lpiinf;
8021  int c;
8022  int pos;
8023  int nnonz;
8024  int naddcols;
8025  int naddcoefs;
8026  int i;
8027  int lpipos;
8028 
8029  assert(lp != NULL);
8030  assert(lp->lpifirstchgcol == lp->nlpicols);
8031  assert(blkmem != NULL);
8032  assert(set != NULL);
8033 
8034  /* if there are no columns to add, we are ready */
8035  if( lp->ncols == lp->nlpicols )
8036  return SCIP_OKAY;
8037 
8038  /* add the additional columns */
8039  assert(!lp->diving);
8040  assert(lp->ncols > lp->nlpicols);
8041  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8042 
8043  /* get the solver's infinity value */
8044  lpiinf = SCIPlpiInfinity(lp->lpi);
8045 
8046  /* count the (maximal) number of added coefficients, calculate the number of added columns */
8047  naddcols = lp->ncols - lp->nlpicols;
8048  naddcoefs = 0;
8049  for( c = lp->nlpicols; c < lp->ncols; ++c )
8050  naddcoefs += lp->cols[c]->len;
8051  assert(naddcols > 0);
8052 
8053  /* get temporary memory for changes */
8054  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8055  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8056  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8057  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8058  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8059  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8060  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8061 
8062  /* fill temporary memory with column data */
8063  nnonz = 0;
8064  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8065  {
8066  col = lp->cols[c];
8067  assert(col != NULL);
8068  assert(col->var != NULL);
8069  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8070  assert(SCIPvarGetCol(col->var) == col);
8071  assert(col->lppos == c);
8072  assert(nnonz + col->nlprows <= naddcoefs);
8073 
8074  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8075  debugColPrint(set, col);
8076 
8077  /* Because the column becomes a member of the LP solver, it now can take values
8078  * different from zero. That means, we have to include the column in the corresponding
8079  * row vectors.
8080  */
8081  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8082 
8083  lp->lpicols[c] = col;
8084  col->lpipos = c;
8085  col->primsol = SCIP_INVALID;
8086  col->redcost = SCIP_INVALID;
8087  col->farkascoef = SCIP_INVALID;
8088  col->sbdown = SCIP_INVALID;
8089  col->sbup = SCIP_INVALID;
8090  col->sbdownvalid = FALSE;
8091  col->sbupvalid = FALSE;
8092  col->validredcostlp = -1;
8093  col->validfarkaslp = -1;
8094  col->sbitlim = -1;
8095  col->objchanged = FALSE;
8096  col->lbchanged = FALSE;
8097  col->ubchanged = FALSE;
8098  col->coefchanged = FALSE;
8099  obj[pos] = col->obj;
8100 
8101  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8102  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8103 
8104  beg[pos] = nnonz;
8105  name[pos] = (char*)SCIPvarGetName(col->var);
8106 
8107  col->flushedobj = obj[pos];
8108  col->flushedlb = lb[pos];
8109  col->flushedub = ub[pos];
8110 
8111  for( i = 0; i < col->nlprows; ++i )
8112  {
8113  assert(col->rows[i] != NULL);
8114  lpipos = col->rows[i]->lpipos;
8115  if( lpipos >= 0 )
8116  {
8117  assert(lpipos < lp->nrows);
8118  assert(nnonz < naddcoefs);
8119  ind[nnonz] = lpipos;
8120  val[nnonz] = col->vals[i];
8121  nnonz++;
8122  }
8123  }
8124 #ifndef NDEBUG
8125  for( i = col->nlprows; i < col->len; ++i )
8126  {
8127  assert(col->rows[i] != NULL);
8128  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8129  }
8130 #endif
8131  }
8132 
8133  /* call LP interface */
8134  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8135  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8136  lp->nlpicols = lp->ncols;
8137  lp->lpifirstchgcol = lp->nlpicols;
8138 
8139  /* free temporary memory */
8140  SCIPsetFreeBufferArray(set, &name);
8141  SCIPsetFreeBufferArray(set, &val);
8142  SCIPsetFreeBufferArray(set, &ind);
8143  SCIPsetFreeBufferArray(set, &beg);
8144  SCIPsetFreeBufferArray(set, &ub);
8145  SCIPsetFreeBufferArray(set, &lb);
8146  SCIPsetFreeBufferArray(set, &obj);
8147 
8148  lp->flushaddedcols = TRUE;
8149  lp->updateintegrality = TRUE;
8150 
8151  /* mark the LP unsolved */
8152  lp->solved = FALSE;
8153  lp->dualfeasible = FALSE;
8154  lp->dualchecked = FALSE;
8155  lp->lpobjval = SCIP_INVALID;
8157 
8158  return SCIP_OKAY;
8159 }
8160 
8161 /** resets row data to represent a row not in the LP solver */
8162 static
8164  SCIP_ROW* row /**< row to be marked deleted */
8165  )
8166 {
8167  assert(row != NULL);
8168 
8169  row->lpipos = -1;
8170  row->dualsol = 0.0;
8171  row->activity = SCIP_INVALID;
8172  row->dualfarkas = 0.0;
8173  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8174  row->validactivitylp = -1;
8175 }
8176 
8177 /** applies all cached row removals to the LP solver */
8178 static
8180  SCIP_LP* lp, /**< current LP data */
8181  BMS_BLKMEM* blkmem, /**< block memory */
8182  SCIP_SET* set /**< global SCIP settings */
8183  )
8184 {
8185  assert(lp != NULL);
8186  assert(lp->lpifirstchgrow <= lp->nlpirows);
8187  assert(lp->lpifirstchgrow <= lp->nrows);
8188 
8189  /* find the first row to change */
8190  while( lp->lpifirstchgrow < lp->nlpirows
8191  && lp->lpifirstchgrow < lp->nrows
8192  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8193  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8194  {
8195  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8196  lp->lpifirstchgrow++;
8197  }
8198 
8199  /* shrink LP to the part which didn't change */
8200  if( lp->lpifirstchgrow < lp->nlpirows )
8201  {
8202  int i;
8203 
8204  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8205  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8206  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8207  {
8208  markRowDeleted(lp->lpirows[i]);
8209  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8210  }
8211  lp->nlpirows = lp->lpifirstchgrow;
8212  lp->flushdeletedrows = TRUE;
8213 
8214  /* mark the LP unsolved */
8215  lp->solved = FALSE;
8216  lp->dualfeasible = FALSE;
8217  lp->dualchecked = FALSE;
8218  lp->lpobjval = SCIP_INVALID;
8220  }
8221  assert(lp->nlpirows == lp->lpifirstchgrow);
8222 
8223  return SCIP_OKAY;
8224 }
8225 
8226 /** applies all cached row additions and removals to the LP solver */
8227 static
8229  SCIP_LP* lp, /**< current LP data */
8230  BMS_BLKMEM* blkmem, /**< block memory */
8231  SCIP_SET* set, /**< global SCIP settings */
8232  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8233  )
8234 {
8235  SCIP_Real* lhs;
8236  SCIP_Real* rhs;
8237  int* beg;
8238  int* ind;
8239  SCIP_Real* val;
8240  char** name;
8241  SCIP_ROW* row;
8242  SCIP_Real lpiinf;
8243  int r;
8244  int pos;
8245  int nnonz;
8246  int naddrows;
8247  int naddcoefs;
8248  int i;
8249  int lpipos;
8250 
8251  assert(lp != NULL);
8252  assert(lp->lpifirstchgrow == lp->nlpirows);
8253  assert(blkmem != NULL);
8254 
8255  /* if there are no rows to add, we are ready */
8256  if( lp->nrows == lp->nlpirows )
8257  return SCIP_OKAY;
8258 
8259  /* add the additional rows */
8260  assert(lp->nrows > lp->nlpirows);
8261  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8262 
8263  /* get the solver's infinity value */
8264  lpiinf = SCIPlpiInfinity(lp->lpi);
8265 
8266  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8267  naddrows = lp->nrows - lp->nlpirows;
8268  naddcoefs = 0;
8269  for( r = lp->nlpirows; r < lp->nrows; ++r )
8270  naddcoefs += lp->rows[r]->len;
8271  assert(naddrows > 0);
8272 
8273  /* get temporary memory for changes */
8274  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8275  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8276  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8277  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8278  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8279  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8280 
8281  /* fill temporary memory with row data */
8282  nnonz = 0;
8283  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8284  {
8285  row = lp->rows[r];
8286  assert(row != NULL);
8287  assert(row->lppos == r);
8288  assert(nnonz + row->nlpcols <= naddcoefs);
8289 
8290  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8291  debugRowPrint(set, row);
8292 
8293  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8294  * different from zero. That means, we have to include the row in the corresponding
8295  * column vectors.
8296  */
8297  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8298 
8299  SCIProwCapture(row);
8300  lp->lpirows[r] = row;
8301  row->lpipos = r;
8302  row->dualsol = SCIP_INVALID;
8303  row->activity = SCIP_INVALID;
8304  row->dualfarkas = SCIP_INVALID;
8305  row->validactivitylp = -1;
8306  row->lhschanged = FALSE;
8307  row->rhschanged = FALSE;
8308  row->coefchanged = FALSE;
8309  if( SCIPsetIsInfinity(set, -row->lhs) )
8310  lhs[pos] = -lpiinf;
8311  else
8312  lhs[pos] = row->lhs - row->constant;
8313  if( SCIPsetIsInfinity(set, row->rhs) )
8314  rhs[pos] = lpiinf;
8315  else
8316  rhs[pos] = row->rhs - row->constant;
8317  beg[pos] = nnonz;
8318  name[pos] = row->name;
8319 
8320  row->flushedlhs = lhs[pos];
8321  row->flushedrhs = rhs[pos];
8322 
8323  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8324  for( i = 0; i < row->nlpcols; ++i )
8325  {
8326  assert(row->cols[i] != NULL);
8327  lpipos = row->cols[i]->lpipos;
8328  if( lpipos >= 0 )
8329  {
8330  assert(lpipos < lp->ncols);
8331  assert(nnonz < naddcoefs);
8332  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8333  ind[nnonz] = lpipos;
8334  val[nnonz] = row->vals[i];
8335  nnonz++;
8336  }
8337  }
8338  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8339 #ifndef NDEBUG
8340  for( i = row->nlpcols; i < row->len; ++i )
8341  {
8342  assert(row->cols[i] != NULL);
8343  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8344  }
8345 #endif
8346  }
8347 
8348  /* call LP interface */
8349  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8350  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8351  lp->nlpirows = lp->nrows;
8352  lp->lpifirstchgrow = lp->nlpirows;
8353 
8354  /* free temporary memory */
8355  SCIPsetFreeBufferArray(set, &name);
8356  SCIPsetFreeBufferArray(set, &val);
8357  SCIPsetFreeBufferArray(set, &ind);
8358  SCIPsetFreeBufferArray(set, &beg);
8359  SCIPsetFreeBufferArray(set, &rhs);
8360  SCIPsetFreeBufferArray(set, &lhs);
8361 
8362  lp->flushaddedrows = TRUE;
8363 
8364  /* mark the LP unsolved */
8365  lp->solved = FALSE;
8366  lp->primalfeasible = FALSE;
8367  lp->primalchecked = FALSE;
8368  lp->lpobjval = SCIP_INVALID;
8370 
8371  return SCIP_OKAY;
8372 }
8373 
8374 /** applies all cached column bound and objective changes to the LP */
8375 static
8377  SCIP_LP* lp, /**< current LP data */
8378  SCIP_SET* set /**< global SCIP settings */
8379  )
8380 {
8381 #ifndef NDEBUG
8382  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8383 #endif
8384  SCIP_COL* col;
8385  int* objind;
8386  int* bdind;
8387  SCIP_Real* obj;
8388  SCIP_Real* lb;
8389  SCIP_Real* ub;
8390  SCIP_Real lpiinf;
8391  int nobjchg;
8392  int nbdchg;
8393  int i;
8394 
8395  assert(lp != NULL);
8396 
8397  if( lp->nchgcols == 0 )
8398  return SCIP_OKAY;
8399 
8400  /* get the solver's infinity value */
8401  lpiinf = SCIPlpiInfinity(lp->lpi);
8402 
8403  /* get temporary memory for changes */
8404  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8405  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8406  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8407  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8408  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8409 
8410  /* collect all cached bound and objective changes */
8411  nobjchg = 0;
8412  nbdchg = 0;
8413  for( i = 0; i < lp->nchgcols; ++i )
8414  {
8415  col = lp->chgcols[i];
8416  assert(col != NULL);
8417  assert(col->var != NULL);
8418  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8419  assert(SCIPvarGetCol(col->var) == col);
8420 
8421  if( col->lpipos >= 0 )
8422  {
8423 #ifndef NDEBUG
8424  /* do not check consistency of data with LPI in case of LPI=none */
8425  if( !lpinone )
8426  {
8427  SCIP_Real lpiobj;
8428  SCIP_Real lpilb;
8429  SCIP_Real lpiub;
8430 
8431  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8432  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8433  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8434  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8435  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8436  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8437  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8438  }
8439 #endif
8440 
8441  if( col->objchanged )
8442  {
8443  SCIP_Real newobj;
8444 
8445  newobj = col->obj;
8446  if( col->flushedobj != newobj ) /*lint !e777*/
8447  {
8448  assert(nobjchg < lp->ncols);
8449  objind[nobjchg] = col->lpipos;
8450  obj[nobjchg] = newobj;
8451  nobjchg++;
8452  col->flushedobj = newobj;
8453  }
8454  col->objchanged = FALSE;
8455  }
8456 
8457  if( col->lbchanged || col->ubchanged )
8458  {
8459  SCIP_Real newlb;
8460  SCIP_Real newub;
8461 
8462  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8463  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8464 
8465  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8466  {
8467  assert(nbdchg < lp->ncols);
8468  bdind[nbdchg] = col->lpipos;
8469  lb[nbdchg] = newlb;
8470  ub[nbdchg] = newub;
8471  nbdchg++;
8472  col->flushedlb = newlb;
8473  col->flushedub = newub;
8474  }
8475  col->lbchanged = FALSE;
8476  col->ubchanged = FALSE;
8477  }
8478  }
8479  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8480  }
8481 
8482  /* change objective values in LP */
8483  if( nobjchg > 0 )
8484  {
8485  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8486  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8487 
8488  /* mark the LP unsolved */
8489  lp->solved = FALSE;
8490  lp->dualfeasible = FALSE;
8491  lp->dualchecked = FALSE;
8492  lp->lpobjval = SCIP_INVALID;
8494  }
8495 
8496  /* change bounds in LP */
8497  if( nbdchg > 0 )
8498  {
8499  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8500  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8501 
8502  /* mark the LP unsolved */
8503  lp->solved = FALSE;
8504  lp->primalfeasible = FALSE;
8505  lp->primalchecked = FALSE;
8506  lp->lpobjval = SCIP_INVALID;
8508  }
8509 
8510  lp->nchgcols = 0;
8511 
8512  /* free temporary memory */
8513  SCIPsetFreeBufferArray(set, &ub);
8514  SCIPsetFreeBufferArray(set, &lb);
8515  SCIPsetFreeBufferArray(set, &bdind);
8516  SCIPsetFreeBufferArray(set, &obj);
8517  SCIPsetFreeBufferArray(set, &objind);
8518 
8519  return SCIP_OKAY;
8520 }
8521 
8522 /** applies all cached row side changes to the LP */
8523 static
8525  SCIP_LP* lp, /**< current LP data */
8526  SCIP_SET* set /**< global SCIP settings */
8527  )
8528 {
8529 #ifndef NDEBUG
8530  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8531 #endif
8532  SCIP_ROW* row;
8533  int* ind;
8534  SCIP_Real* lhs;
8535  SCIP_Real* rhs;
8536  SCIP_Real lpiinf;
8537  int i;
8538  int nchg;
8539 
8540  assert(lp != NULL);
8541 
8542  if( lp->nchgrows == 0 )
8543  return SCIP_OKAY;
8544 
8545  /* get the solver's infinity value */
8546  lpiinf = SCIPlpiInfinity(lp->lpi);
8547 
8548  /* get temporary memory for changes */
8549  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8550  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8551  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8552 
8553  /* collect all cached left and right hand side changes */
8554  nchg = 0;
8555  for( i = 0; i < lp->nchgrows; ++i )
8556  {
8557  row = lp->chgrows[i];
8558  assert(row != NULL);
8559 
8560  if( row->lpipos >= 0 )
8561  {
8562 #ifndef NDEBUG
8563  /* do not check consistency of data with LPI in case of LPI=none */
8564  if( !lpinone )
8565  {
8566  SCIP_Real lpilhs;
8567  SCIP_Real lpirhs;
8568 
8569  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8570  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8571  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8572  }
8573 #endif
8574  if( row->lhschanged || row->rhschanged )
8575  {
8576  SCIP_Real newlhs;
8577  SCIP_Real newrhs;
8578 
8579  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8580  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8581  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8582  {
8583  assert(nchg < lp->nrows);
8584  ind[nchg] = row->lpipos;
8585  lhs[nchg] = newlhs;
8586  rhs[nchg] = newrhs;
8587  nchg++;
8588  row->flushedlhs = newlhs;
8589  row->flushedrhs = newrhs;
8590  }
8591  row->lhschanged = FALSE;
8592  row->rhschanged = FALSE;
8593  }
8594  }
8595  }
8596 
8597  /* change left and right hand sides in LP */
8598  if( nchg > 0 )
8599  {
8600  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8601  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8602 
8603  /* mark the LP unsolved */
8604  lp->solved = FALSE;
8605  lp->primalfeasible = FALSE;
8606  lp->primalchecked = FALSE;
8607  lp->lpobjval = SCIP_INVALID;
8609  }
8610 
8611  lp->nchgrows = 0;
8612 
8613  /* free temporary memory */
8614  SCIPsetFreeBufferArray(set, &rhs);
8615  SCIPsetFreeBufferArray(set, &lhs);
8616  SCIPsetFreeBufferArray(set, &ind);
8617 
8618  return SCIP_OKAY;
8619 }
8620 
8621 /** copy integrality information to the LP */
8622 static
8624  SCIP_LP* lp, /**< current LP data */
8625  SCIP_SET* set /**< global SCIP settings */
8626  )
8627 {
8628  int i;
8629  int nintegers;
8630  int* integerInfo;
8631  SCIP_VAR* var;
8632 
8633  assert(lp != NULL);
8634 
8635  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8636 
8637  /* count total number of integralities */
8638  nintegers = 0;
8639 
8640  for( i = 0; i < lp->ncols; ++i )
8641  {
8642  var = SCIPcolGetVar(lp->cols[i]);
8643  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8644  {
8645  integerInfo[i] = 1;
8646  ++nintegers;
8647  }
8648  else
8649  integerInfo[i] = 0;
8650  }
8651 
8652  /* only pass integrality information if integer variables are present */
8653  if( nintegers > 0 )
8654  {
8655  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8656  }
8657  else
8658  {
8660  }
8661 
8662  SCIPsetFreeBufferArray(set, &integerInfo);
8663 
8664  /* mark integralities to be updated */
8665  lp->updateintegrality = FALSE;
8666 
8667  return SCIP_OKAY;
8668 }
8669 
8670 /** applies all cached changes to the LP solver */
8672  SCIP_LP* lp, /**< current LP data */
8673  BMS_BLKMEM* blkmem, /**< block memory */
8674  SCIP_SET* set, /**< global SCIP settings */
8675  SCIP_PROB* prob, /**< problem data */
8676  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8677  )
8678 {
8679  assert(lp != NULL);
8680  assert(blkmem != NULL);
8681 
8682  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",
8683  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8684 
8685  if( !lp->flushed )
8686  {
8687  lp->flushdeletedcols = FALSE;
8688  lp->flushaddedcols = FALSE;
8689  lp->flushdeletedrows = FALSE;
8690  lp->flushaddedrows = FALSE;
8691 
8692  SCIP_CALL( lpFlushDelCols(lp) );
8693  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8694  SCIP_CALL( lpFlushChgCols(lp, set) );
8695  SCIP_CALL( lpFlushChgRows(lp, set) );
8696  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8697  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8698 
8699  lp->flushed = TRUE;
8700 
8701  checkLinks(lp);
8702  }
8703 
8704  /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8705  * we want to re-optimize the LP even if nothing else has changed */
8706  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 && ! lpCutoffDisabled(set, prob) ) /*lint !e777*/
8707  {
8708  lp->solved = FALSE;
8710  }
8711 
8712  assert(lp->nlpicols == lp->ncols);
8713  assert(lp->lpifirstchgcol == lp->nlpicols);
8714  assert(lp->nlpirows == lp->nrows);
8715  assert(lp->lpifirstchgrow == lp->nlpirows);
8716  assert(lp->nchgcols == 0);
8717  assert(lp->nchgrows == 0);
8718 #ifndef NDEBUG
8719  {
8720  int ncols;
8721  int nrows;
8722 
8723  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8724  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8725  assert(ncols == lp->ncols);
8726  assert(nrows == lp->nrows);
8727  }
8728 #endif
8729 
8730  return SCIP_OKAY;
8731 }
8732 
8733 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8735  SCIP_LP* lp, /**< current LP data */
8736  SCIP_SET* set /**< global SCIP settings */
8737  )
8738 {
8739 #ifndef NDEBUG
8740  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8741 #endif
8742  int i;
8743 
8744  assert(lp != NULL);
8745 
8746 #ifndef NDEBUG
8747  /* check, if there are really no column or row deletions or coefficient changes left */
8748  while( lp->lpifirstchgcol < lp->nlpicols
8749  && lp->lpifirstchgcol < lp->ncols
8750  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8751  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8752  {
8753  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8754  lp->lpifirstchgcol++;
8755  }
8756  assert(lp->nlpicols == lp->lpifirstchgcol);
8757 
8758  while( lp->lpifirstchgrow < lp->nlpirows
8759  && lp->lpifirstchgrow < lp->nrows
8760  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8761  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8762  {
8763  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8764  lp->lpifirstchgrow++;
8765  }
8766  assert(lp->nlpirows == lp->lpifirstchgrow);
8767 #endif
8768 
8769  lp->lpifirstchgcol = lp->nlpicols;
8770  lp->lpifirstchgrow = lp->nlpirows;
8771 
8772  /* check, if there are really no column or row additions left */
8773  assert(lp->ncols == lp->nlpicols);
8774  assert(lp->nrows == lp->nlpirows);
8775 
8776  /* mark the changed columns to be unchanged, and check, if this is really correct */
8777  for( i = 0; i < lp->nchgcols; ++i )
8778  {
8779  SCIP_COL* col;
8780 
8781  col = lp->chgcols[i];
8782  assert(col != NULL);
8783  assert(col->var != NULL);
8784  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8785  assert(SCIPvarGetCol(col->var) == col);
8786 
8787  if( col->lpipos >= 0 )
8788  {
8789 #ifndef NDEBUG
8790  /* do not check consistency of data with LPI in case of LPI=none */
8791  if( !lpinone )
8792  {
8793  SCIP_Real lpiobj;
8794  SCIP_Real lpilb;
8795  SCIP_Real lpiub;
8796 
8797  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8798  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8799  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8800  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8801  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8802  assert(col->flushedobj == col->obj); /*lint !e777*/
8803  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8804  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8805  }
8806 #endif
8807  col->objchanged = FALSE;
8808  col->lbchanged = FALSE;
8809  col->ubchanged = FALSE;
8810  }
8811  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8812  }
8813  lp->nchgcols = 0;
8814 
8815  /* mark the changed rows to be unchanged, and check, if this is really correct */
8816  for( i = 0; i < lp->nchgrows; ++i )
8817  {
8818  SCIP_ROW* row;
8819 
8820  row = lp->chgrows[i];
8821  assert(row != NULL);
8822 
8823  if( row->lpipos >= 0 )
8824  {
8825 #ifndef NDEBUG
8826  /* do not check consistency of data with LPI in case of LPI=none */
8827  if( !lpinone )
8828  {
8829  SCIP_Real lpilhs;
8830  SCIP_Real lpirhs;
8831 
8832  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8833  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8834  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8835  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8836  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8837  }
8838 #endif
8839  row->lhschanged = FALSE;
8840  row->rhschanged = FALSE;
8841  }
8842  }
8843  lp->nchgrows = 0;
8844 
8845  /* mark the LP to be flushed */
8846  lp->flushed = TRUE;
8847 
8848  checkLinks(lp);
8849 
8850  return SCIP_OKAY;
8851 }
8852 
8853 
8854 
8855 
8856 /*
8857  * LP methods
8858  */
8859 
8860 /** updates link data after addition of column */
8861 static
8863  SCIP_COL* col, /**< LP column */
8864  SCIP_SET* set /**< global SCIP settings */
8865  )
8866 {
8867  SCIP_ROW* row;
8868  int i;
8869  int pos;
8870 
8871  assert(col != NULL);
8872  assert(col->lppos >= 0);
8873 
8874  /* update column arrays of all linked rows */
8875  for( i = 0; i < col->len; ++i )
8876  {
8877  pos = col->linkpos[i];
8878  if( pos >= 0 )
8879  {
8880  row = col->rows[i];
8881  assert(row != NULL);
8882  assert(row->linkpos[pos] == i);
8883  assert(row->cols[pos] == col);
8884  assert(row->nlpcols <= pos && pos < row->len);
8885 
8886  row->nlpcols++;
8887  rowSwapCoefs(row, pos, row->nlpcols-1);
8888  assert(row->cols[row->nlpcols-1] == col);
8889 
8890  /* if no swap was necessary, mark lpcols to be unsorted */
8891  if( pos == row->nlpcols-1 )
8892  row->lpcolssorted = FALSE;
8893 
8894  /* update norms */
8895  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8896  }
8897  }
8898 }
8899 
8900 /** updates link data after addition of row */
8901 static
8903  SCIP_ROW* row /**< LP row */
8904  )
8905 {
8906  SCIP_COL* col;
8907  int i;
8908  int pos;
8909 
8910  assert(row != NULL);
8911  assert(row->lppos >= 0);
8912 
8913  /* update row arrays of all linked columns */
8914  for( i = 0; i < row->len; ++i )
8915  {
8916  pos = row->linkpos[i];
8917  if( pos >= 0 )
8918  {
8919  col = row->cols[i];
8920  assert(col != NULL);
8921  assert(col->linkpos[pos] == i);
8922  assert(col->rows[pos] == row);
8923  assert(col->nlprows <= pos && pos < col->len);
8924 
8925  col->nlprows++;
8926  colSwapCoefs(col, pos, col->nlprows-1);
8927 
8928  /* if no swap was necessary, mark lprows to be unsorted */
8929  if( pos == col->nlprows-1 )
8930  col->lprowssorted = FALSE;
8931  }
8932  }
8933 }
8934 
8935 /** updates link data after removal of column */
8936 static
8938  SCIP_COL* col, /**< LP column */
8939  SCIP_SET* set /**< global SCIP settings */
8940  )
8941 {
8942  SCIP_ROW* row;
8943  int i;
8944  int pos;
8945 
8946  assert(col != NULL);
8947  assert(col->lppos == -1);
8948 
8949  /* update column arrays of all linked rows */
8950  for( i = 0; i < col->len; ++i )
8951  {
8952  pos = col->linkpos[i];
8953  if( pos >= 0 )
8954  {
8955  row = col->rows[i];
8956  assert(row != NULL);
8957  assert(row->linkpos[pos] == i);
8958  assert(row->cols[pos] == col);
8959  assert(0 <= pos && pos < row->nlpcols);
8960 
8961  /* update norms */
8962  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8963 
8964  row->nlpcols--;
8965  rowSwapCoefs(row, pos, row->nlpcols);
8966 
8967  /* if no swap was necessary, mark nonlpcols to be unsorted */
8968  if( pos == row->nlpcols )
8969  row->nonlpcolssorted = FALSE;
8970  }
8971  }
8972 }
8973 
8974 /** updates link data after removal of row */
8975 static
8977  SCIP_ROW* row /**< LP row */
8978  )
8979 {
8980  SCIP_COL* col;
8981  int i;
8982  int pos;
8983 
8984  assert(row != NULL);
8985  assert(row->lppos == -1);
8986 
8987  /* update row arrays of all linked columns */
8988  for( i = 0; i < row->len; ++i )
8989  {
8990  pos = row->linkpos[i];
8991  if( pos >= 0 )
8992  {
8993  col = row->cols[i];
8994  assert(col != NULL);
8995  assert(0 <= pos && pos < col->nlprows);
8996  assert(col->linkpos[pos] == i);
8997  assert(col->rows[pos] == row);
8998 
8999  col->nlprows--;
9000  colSwapCoefs(col, pos, col->nlprows);
9001 
9002  /* if no swap was necessary, mark lprows to be unsorted */
9003  if( pos == col->nlprows )
9004  col->nonlprowssorted = FALSE;
9005  }
9006  }
9007 }
9008 
9009 static
9011  SCIP_LP* lp, /**< LP data object */
9012  int initsize /**< initial size of the arrays */
9013  )
9014 {
9015  assert(lp != NULL);
9016  assert(lp->divechgsides == NULL);
9017  assert(lp->divechgsidetypes == NULL);
9018  assert(lp->divechgrows == NULL);
9019  assert(lp->ndivechgsides == 0);
9020  assert(lp->divechgsidessize == 0);
9021  assert(initsize > 0);
9022 
9023  lp->divechgsidessize = initsize;
9027 
9028  return SCIP_OKAY;
9029 }
9030 
9031 static
9033  SCIP_LP* lp, /**< LP data object */
9034  int minsize, /**< minimal number of elements */
9035  SCIP_Real growfact /**< growing factor */
9036  )
9037 {
9038  assert(lp != NULL);
9039  assert(lp->divechgsides != NULL);
9040  assert(lp->divechgsidetypes != NULL);
9041  assert(lp->divechgrows != NULL);
9042  assert(lp->ndivechgsides > 0);
9043  assert(lp->divechgsidessize > 0);
9044  assert(minsize > 0);
9045 
9046  if( minsize <= lp->divechgsidessize )
9047  return SCIP_OKAY;
9048 
9049  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9053 
9054  return SCIP_OKAY;
9055 }
9056 
9057 static
9059  SCIP_LP* lp /**< LP data object */
9060  )
9061 {
9062  assert(lp != NULL);
9063  assert(lp->divechgsides != NULL);
9064  assert(lp->divechgsidetypes != NULL);
9065  assert(lp->divechgrows != NULL);
9066  assert(lp->ndivechgsides == 0);
9067  assert(lp->divechgsidessize > 0);
9068 
9072  lp->divechgsidessize = 0;
9073 }
9074 
9075 #define DIVESTACKINITSIZE 100
9076 
9077 /** creates empty LP data object */
9079  SCIP_LP** lp, /**< pointer to LP data object */
9080  SCIP_SET* set, /**< global SCIP settings */
9081  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9082  SCIP_STAT* stat, /**< problem statistics */
9083  const char* name /**< problem name */
9084  )
9085 {
9086  SCIP_Bool success;
9087 
9088  assert(lp != NULL);
9089  assert(set != NULL);
9090  assert(stat != NULL);
9091  assert(name != NULL);
9092 
9093  SCIP_ALLOC( BMSallocMemory(lp) );
9094 
9095  /* open LP Solver interface */
9096  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9097 
9098  (*lp)->lpicols = NULL;
9099  (*lp)->lpirows = NULL;
9100  (*lp)->chgcols = NULL;
9101  (*lp)->chgrows = NULL;
9102  (*lp)->cols = NULL;
9103  (*lp)->soldirection = NULL;
9104  (*lp)->lazycols = NULL;
9105  (*lp)->rows = NULL;
9106  (*lp)->lpobjval = 0.0;
9107  (*lp)->glbpseudoobjval = 0.0;
9108  (*lp)->relglbpseudoobjval = 0.0;
9109  (*lp)->glbpseudoobjvalid = TRUE;
9110  (*lp)->glbpseudoobjvalinf = 0;
9111  (*lp)->pseudoobjval = 0.0;
9112  (*lp)->relpseudoobjval = 0.0;
9113  (*lp)->pseudoobjvalid = TRUE;
9114  (*lp)->pseudoobjvalinf = 0;
9115  (*lp)->looseobjval = 0.0;
9116  (*lp)->rellooseobjval = 0.0;
9117  (*lp)->looseobjvalid = TRUE;
9118  (*lp)->looseobjvalinf = 0;
9119  (*lp)->nloosevars = 0;
9120  (*lp)->rootlpobjval = SCIP_INVALID;
9121  (*lp)->rootlooseobjval = SCIP_INVALID;
9122  (*lp)->cutoffbound = SCIPsetInfinity(set);
9123  (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9124  SCIPlpResetFeastol(*lp, set);
9125  (*lp)->validdegeneracylp = -1;
9126  (*lp)->objsqrnorm = 0.0;
9127  (*lp)->objsumnorm = 0.0;
9128  (*lp)->lpicolssize = 0;
9129  (*lp)->nlpicols = 0;
9130  (*lp)->lpirowssize = 0;
9131  (*lp)->nlpirows = 0;
9132  (*lp)->lpifirstchgcol = 0;
9133  (*lp)->lpifirstchgrow = 0;
9134  (*lp)->colssize = 0;
9135  (*lp)->soldirectionsize = 0;
9136  (*lp)->ncols = 0;
9137  (*lp)->lazycolssize = 0;
9138  (*lp)->nlazycols = 0;
9139  (*lp)->rowssize = 0;
9140  (*lp)->nrows = 0;
9141  (*lp)->chgcolssize = 0;
9142  (*lp)->nchgcols = 0;
9143  (*lp)->chgrowssize = 0;
9144  (*lp)->nchgrows = 0;
9145  (*lp)->firstnewcol = 0;
9146  (*lp)->firstnewrow = 0;
9147  (*lp)->nremovablecols = 0;
9148  (*lp)->nremovablerows = 0;
9149  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9150  (*lp)->validfarkaslp = -1;
9151  (*lp)->validsoldirlp = -1;
9152  (*lp)->validsoldirsol = NULL;
9153  (*lp)->objsqrnormunreliable = FALSE;
9154  (*lp)->flushdeletedcols = FALSE;
9155  (*lp)->flushaddedcols = FALSE;
9156  (*lp)->flushdeletedrows = FALSE;
9157  (*lp)->flushaddedrows = FALSE;
9158  (*lp)->updateintegrality = TRUE;
9159  (*lp)->flushed = TRUE;
9160  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9161  (*lp)->solved = TRUE;
9162  (*lp)->primalfeasible = TRUE;
9163  (*lp)->primalchecked = TRUE;
9164  (*lp)->dualfeasible = TRUE;
9165  (*lp)->dualchecked = TRUE;
9166  (*lp)->solisbasic = FALSE;
9167  (*lp)->rootlpisrelax = TRUE;
9168  (*lp)->isrelax = TRUE;
9169  (*lp)->installing = FALSE;
9170  (*lp)->strongbranching = FALSE;
9171  (*lp)->strongbranchprobing = FALSE;
9172  (*lp)->probing = FALSE;
9173  (*lp)->diving = FALSE;
9174  (*lp)->divingobjchg = FALSE;
9175  (*lp)->divinglazyapplied = FALSE;
9176  (*lp)->divelpistate = NULL;
9177  (*lp)->divelpwasprimfeas = TRUE;
9178  (*lp)->divelpwasprimchecked = TRUE;
9179  (*lp)->divelpwasdualfeas = TRUE;
9180  (*lp)->divelpwasdualchecked = TRUE;
9181  (*lp)->divechgsides = NULL;
9182  (*lp)->divechgsidetypes = NULL;
9183  (*lp)->divechgrows = NULL;
9184  (*lp)->ndivechgsides = 0;
9185  (*lp)->divechgsidessize = 0;
9186  (*lp)->ndivingrows = 0;
9187  (*lp)->divinglpiitlim = INT_MAX;
9188  (*lp)->resolvelperror = FALSE;
9189  (*lp)->divenolddomchgs = 0;
9190  (*lp)->adjustlpval = FALSE;
9191  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9192  (*lp)->lpifeastol = (*lp)->feastol;
9193  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9194  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9195  (*lp)->lpifromscratch = FALSE;
9196  (*lp)->lpifastmip = set->lp_fastmip;
9197  (*lp)->lpiscaling = set->lp_scaling;
9198  (*lp)->lpipresolving = set->lp_presolving;
9199  (*lp)->lpilpinfo = set->disp_lpinfo;
9200  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9201  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9202  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9203  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9204  (*lp)->lpimarkowitz = set->lp_markowitz;
9205  (*lp)->lpiitlim = INT_MAX;
9206  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9207  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9208  (*lp)->lpithreads = set->lp_threads;
9209  (*lp)->lpitiming = (int) set->time_clocktype;
9210  (*lp)->lpirandomseed = set->random_randomseed;
9211  (*lp)->storedsolvals = NULL;
9212 
9213  /* allocate arrays for diving */
9215 
9216  /* set default parameters in LP solver */
9217  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9218  if( !success )
9219  {
9220  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9221  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9223  }
9224  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9225  (*lp)->lpihasfeastol = success;
9226  if( !success )
9227  {
9228  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9229  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9231  }
9232  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9233  (*lp)->lpihasdualfeastol = success;
9234  if( !success )
9235  {
9236  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9237  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9239  }
9240  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9241  (*lp)->lpihasbarrierconvtol = success;
9242  if( !success )
9243  {
9244  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9245  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9247  }
9248  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9249  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9250  (*lp)->lpihasfastmip = success;
9251  if( !success )
9252  {
9253  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9254  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9256  }
9257  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9258  (*lp)->lpihasscaling = success;
9259  if( !success )
9260  {
9261  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9262  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9264  }
9265  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9266  (*lp)->lpihaspresolving = success;
9267  if( !success )
9268  {
9269  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9270  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9272  }
9273  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9274  if( !success )
9275  {
9276  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9277  "LP Solver <%s>: clock type cannot be set\n",
9279  }
9280  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9281  if( !success )
9282  {
9283  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9284  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9286  }
9287  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9288  if( !success )
9289  {
9290  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9291  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9293  }
9294  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9295  if( !success )
9296  {
9297  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9298  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9300  }
9301  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9302  (*lp)->lpihasrowrep = success;
9303  if( !success )
9304  {
9305  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9306  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9308  }
9309  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9310  (*lp)->lpihaspolishing = success;
9311  if( !success )
9312  {
9313  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9314  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9316  }
9317  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9318  (*lp)->lpihasrefactor = success;
9319  if( !success )
9320  {
9321  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9322  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9324  }
9325  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9326  if( !success )
9327  {
9328  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9329  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9331  }
9332  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9333  if( !success )
9334  {
9335  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9336  "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9338  }
9339  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9340  if( !success )
9341  {
9342  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9343  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9345  }
9346  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9347  if( (*lp)->lpirandomseed != 0 )
9348  {
9349  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9350  if( !success )
9351  {
9352  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9353  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9355  }
9356  }
9357 
9358  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9359  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9360  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9361  {
9362  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9363  return SCIP_PARAMETERWRONGVAL;
9364  }
9365 
9366  return SCIP_OKAY;
9367 }
9368 
9369 /** frees LP data object */
9371  SCIP_LP** lp, /**< pointer to LP data object */
9372  BMS_BLKMEM* blkmem, /**< block memory */
9373  SCIP_SET* set, /**< global SCIP settings */
9374  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9375  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9376  )
9377 {
9378  int i;
9379 
9380  assert(lp != NULL);
9381  assert(*lp != NULL);
9382 
9383  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9384 
9385  freeDiveChgSideArrays(*lp);
9386 
9387  /* release LPI rows */
9388  for( i = 0; i < (*lp)->nlpirows; ++i )
9389  {
9390  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9391  }
9392 
9393  if( (*lp)->lpi != NULL )
9394  {
9395  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9396  }
9397 
9398  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9399  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9400  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9401  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9402  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9403  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9404  BMSfreeMemoryArrayNull(&(*lp)->cols);
9405  BMSfreeMemoryArrayNull(&(*lp)->rows);
9406  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9407  BMSfreeMemory(lp);
9408 
9409  return SCIP_OKAY;
9410 }
9411 
9412 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9413  * changes to the LP solver
9414  */
9416  SCIP_LP* lp, /**< LP data */
9417  BMS_BLKMEM* blkmem, /**< block memory */
9418  SCIP_SET* set, /**< global SCIP settings */
9419  SCIP_PROB* prob, /**< problem data */
9420  SCIP_STAT* stat, /**< problem statistics */
9421  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9422  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9423  )
9424 {
9425  assert(stat != NULL);
9426 
9427  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9428  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
9429 
9430  /* mark the empty LP to be solved */
9432  lp->lpobjval = 0.0;
9433  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9434  lp->validfarkaslp = -1;
9435  lp->validdegeneracylp = -1;
9436  lp->validsoldirlp = -1;
9437  lp->validsoldirsol = NULL;
9438  lp->solved = TRUE;
9439  lp->primalfeasible = TRUE;
9440  lp->primalchecked = TRUE;
9441  lp->dualfeasible = TRUE;
9442  lp->dualchecked = TRUE;
9443  lp->solisbasic = FALSE;
9445 
9446  return SCIP_OKAY;
9447 }
9448 
9449 /** adds a column to the LP */
9451  SCIP_LP* lp, /**< LP data */
9452  SCIP_SET* set, /**< global SCIP settings */
9453  SCIP_COL* col, /**< LP column */
9454  int depth /**< depth in the tree where the column addition is performed */
9455  )
9456 {
9457  assert(lp != NULL);
9458  assert(!lp->diving);
9459  assert(col != NULL);
9460  assert(col->len == 0 || col->rows != NULL);
9461  assert(col->lppos == -1);
9462  assert(col->var != NULL);
9463  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9464  assert(SCIPvarGetCol(col->var) == col);
9465  assert(SCIPvarIsIntegral(col->var) == col->integral);
9466 
9467  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9468 #ifdef SCIP_DEBUG
9469  {
9470  int i;
9471  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9472  for( i = 0; i < col->len; ++i )
9473  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9474  SCIPsetDebugMsgPrint(set, "\n");
9475  }
9476 #endif
9477 
9478  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9479  lp->cols[lp->ncols] = col;
9480  col->lppos = lp->ncols;
9481  col->lpdepth = depth;
9482  col->age = 0;
9483  lp->ncols++;
9484  if( col->removable )
9485  lp->nremovablecols++;
9486 
9487  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9488  {
9489  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9490  lp->lazycols[lp->nlazycols] = col;
9491  lp->nlazycols++;
9492  }
9493 
9494  /* mark the current LP unflushed */
9495  lp->flushed = FALSE;
9496 
9497  /* update column arrays of all linked rows */
9498  colUpdateAddLP(col, set);
9499 
9500  /* update the objective function vector norms */
9501  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9502 
9503  checkLinks(lp);
9504 
9505  return SCIP_OKAY;
9506 }
9507 
9508 /** adds a row to the LP and captures it */
9510  SCIP_LP* lp, /**< LP data */
9511  BMS_BLKMEM* blkmem, /**< block memory buffers */
9512  SCIP_SET* set, /**< global SCIP settings */
9513  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9514  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9515  SCIP_ROW* row, /**< LP row */
9516  int depth /**< depth in the tree where the row addition is performed */
9517  )
9518 {
9519  assert(lp != NULL);
9520  assert(row != NULL);
9521  assert(row->len == 0 || row->cols != NULL);
9522  assert(row->lppos == -1);
9523 
9524  SCIProwCapture(row);
9525  SCIProwLock(row);
9526 
9527  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9528 #ifdef SCIP_DEBUG
9529  {
9530  int i;
9531  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9532  for( i = 0; i < row->len; ++i )
9533  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9534  if( !SCIPsetIsZero(set, row->constant) )
9535  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9536  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9537  }
9538 #endif
9539 
9540  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9541  lp->rows[lp->nrows] = row;
9542  row->lppos = lp->nrows;
9543  row->lpdepth = depth;
9544  row->age = 0;
9545  lp->nrows++;
9546  if( row->removable )
9547  lp->nremovablerows++;
9548 
9549  /* mark the current LP unflushed */
9550  lp->flushed = FALSE;
9551 
9552  /* update row arrays of all linked columns */
9553  rowUpdateAddLP(row);
9554 
9555  checkLinks(lp);
9556 
9557  rowCalcNorms(row, set);
9558 
9559  /* check, if row addition to LP events are tracked
9560  * if so, issue ROWADDEDLP event
9561  */
9562  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9563  {
9564  SCIP_EVENT* event;
9565 
9566  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9567  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9568  }
9569 
9570  return SCIP_OKAY;
9571 }
9572 
9573 
9574 #ifndef NDEBUG
9575 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9576  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9577  * the lazycols array
9578  */
9579 static
9581  SCIP_LP* lp, /**< LP data */
9582  SCIP_SET* set /**< global SCIP settings */
9583  )
9584 {
9585  SCIP_Bool contained;
9586  int c;
9587  int i;
9588 
9589  assert(lp != NULL);
9590 
9591  /* check if each column in the lazy column array has a counter part in the column array */
9592  for( i = 0; i < lp->nlazycols; ++i )
9593  {
9594  /* check if each lazy column has at least on lazy bound */
9595  assert(lp->lazycols[i] != NULL);
9596  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9597 
9598  contained = FALSE;
9599  for( c = 0; c < lp->ncols; ++c )
9600  {
9601  if( lp->lazycols[i] == lp->cols[c] )
9602  {
9603  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9604  contained = TRUE;
9605  }
9606  }
9607  assert(contained);
9608  }
9609 
9610  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9611  * array */
9612  for( c = 0; c < lp->ncols; ++c )
9613  {
9614  contained = FALSE;
9615  assert(lp->cols[c] != NULL);
9616 
9617  for( i = 0; i < lp->nlazycols; ++i )
9618  {
9619  if( lp->lazycols[i] == lp->cols[c] )
9620  {
9621  contained = TRUE;
9622  }
9623  }
9624 
9625  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9626  }
9627 }
9628 #else
9629 #define checkLazyColArray(lp, set) /**/
9630 #endif
9631 
9632 /** removes all columns after the given number of cols from the LP */
9634  SCIP_LP* lp, /**< LP data */
9635  SCIP_SET* set, /**< global SCIP settings */
9636  int newncols /**< new number of columns in the LP */
9637  )
9638 {
9639  SCIP_COL* col;
9640  int c;
9641 
9642  assert(lp != NULL);
9643 
9644  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9645  assert(0 <= newncols);
9646  assert(newncols <= lp->ncols);
9647 
9648  if( newncols < lp->ncols )
9649  {
9650  assert(!lp->diving);
9651 
9652  for( c = lp->ncols-1; c >= newncols; --c )
9653  {
9654  col = lp->cols[c];
9655  assert(col != NULL);
9656  assert(col->len == 0 || col->rows != NULL);
9657  assert(col->var != NULL);
9658  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9659  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9660  assert(col->lppos == c);
9661 
9662  /* mark column to be removed from the LP */
9663  col->lppos = -1;
9664  col->lpdepth = -1;
9665  lp->ncols--;
9666 
9667  /* count removable columns */
9668  if( col->removable )
9669  lp->nremovablecols--;
9670 
9671  /* update column arrays of all linked rows */
9672  colUpdateDelLP(col, set);
9673 
9674  /* update the objective function vector norms */
9675  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9676  }
9677  assert(lp->ncols == newncols);
9678  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9679 
9680  /* remove columns which are deleted from the lazy column array */
9681  c = 0;
9682  while( c < lp->nlazycols )
9683  {
9684  if( lp->lazycols[c]->lppos < 0 )
9685  {
9686  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9687  lp->nlazycols--;
9688  }
9689  else
9690  c++;
9691  }
9692 
9693  /* mark the current LP unflushed */
9694  lp->flushed = FALSE;
9695 
9696  checkLazyColArray(lp, set);
9697  checkLinks(lp);
9698  }
9699  assert(lp->nremovablecols <= lp->ncols);
9700 
9701  return SCIP_OKAY;
9702 }
9703 
9704 /** removes and releases all rows after the given number of rows from the LP */
9706  SCIP_LP* lp, /**< LP data */
9707  BMS_BLKMEM* blkmem, /**< block memory */
9708  SCIP_SET* set, /**< global SCIP settings */
9709  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9710  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9711  int newnrows /**< new number of rows in the LP */
9712  )
9713 {
9714  SCIP_ROW* row;
9715  int r;
9716 
9717  assert(lp != NULL);
9718  assert(0 <= newnrows && newnrows <= lp->nrows);
9719 
9720  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9721  if( newnrows < lp->nrows )
9722  {
9723  for( r = lp->nrows-1; r >= newnrows; --r )
9724  {
9725  row = lp->rows[r];
9726  assert(row != NULL);
9727  assert(row->len == 0 || row->cols != NULL);
9728  assert(row->lppos == r);
9729 
9730  /* mark row to be removed from the LP */
9731  row->lppos = -1;
9732  row->lpdepth = -1;
9733  lp->nrows--;
9734 
9735  /* count removable rows */
9736  if( row->removable )
9737  lp->nremovablerows--;
9738 
9739  /* update row arrays of all linked columns */
9740  rowUpdateDelLP(row);
9741 
9742  SCIProwUnlock(lp->rows[r]);
9743 
9744  /* check, if row deletion events are tracked
9745  * if so, issue ROWDELETEDLP event
9746  */
9747  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9748  {
9749  SCIP_EVENT* event;
9750 
9751  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9752  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9753  }
9754 
9755  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9756  }
9757  assert(lp->nrows == newnrows);
9758  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9759 
9760  /* mark the current LP unflushed */
9761  lp->flushed = FALSE;
9762 
9763  checkLinks(lp);
9764  }
9765  assert(lp->nremovablerows <= lp->nrows);
9766 
9767  return SCIP_OKAY;
9768 }
9769 
9770 /** removes all columns and rows from LP, releases all rows */
9772  SCIP_LP* lp, /**< LP data */
9773  BMS_BLKMEM* blkmem, /**< block memory */
9774  SCIP_SET* set, /**< global SCIP settings */
9775  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9776  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9777  )
9778 {
9779  assert(lp != NULL);
9780  assert(!lp->diving);
9781 
9782  SCIPsetDebugMsg(set, "clearing LP\n");
9783  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9784  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9785 
9786  return SCIP_OKAY;
9787 }
9788 
9789 /** remembers number of columns and rows to track the newly added ones */
9791  SCIP_LP* lp /**< current LP data */
9792  )
9793 {
9794  assert(lp != NULL);
9795  assert(!lp->diving);
9796 
9797  lp->firstnewrow = lp->nrows;
9798  lp->firstnewcol = lp->ncols;
9799 }
9800 
9801 /** sets the remembered number of columns and rows to the given values */
9803  SCIP_LP* lp, /**< current LP data */
9804  int nrows, /**< number of rows to set the size marker to */
9805  int ncols /**< number of columns to set the size marker to */
9806  )
9807 {
9808  assert(lp != NULL);
9809  assert(!lp->diving);
9810 
9811  lp->firstnewrow = nrows;
9812  lp->firstnewcol = ncols;
9813 }
9814 
9815 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9817  SCIP_LP* lp, /**< LP data */
9818  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9819  )
9820 {
9821  assert(lp != NULL);
9822  assert(lp->flushed);
9823  assert(lp->solved);
9824  assert(lp->solisbasic);
9825  assert(basisind != NULL);
9826 
9827  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9828 
9829  return SCIP_OKAY;
9830 }
9831 
9832 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9834  SCIP_LP* lp, /**< LP data */
9835  int* cstat, /**< array to store column basis status, or NULL */
9836  int* rstat /**< array to store row basis status, or NULL */
9837  )
9838 {
9839  assert(lp != NULL);
9840  assert(lp->flushed);
9841  assert(lp->solved);
9842  assert(lp->solisbasic);
9843 
9844  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9845 
9846  return SCIP_OKAY;
9847 }
9848 
9849 /** gets a row from the inverse basis matrix B^-1 */
9851  SCIP_LP* lp, /**< LP data */
9852  int r, /**< row number */
9853  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9854  int* inds, /**< array to store the non-zero indices, or NULL */
9855  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9856  * (-1: if we do not store sparsity informations) */
9857  )
9858 {
9859  assert(lp != NULL);
9860  assert(lp->flushed);
9861  assert(lp->solved);
9862  assert(lp->solisbasic);
9863  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9864  assert(coef != NULL);
9865 
9866  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9867 
9868  return SCIP_OKAY;
9869 }
9870 
9871 /** gets a column from the inverse basis matrix B^-1 */
9873  SCIP_LP* lp, /**< LP data */
9874  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9875  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9876  * to get the array which links the B^-1 column numbers to the row and
9877  * column numbers of the LP! c must be between 0 and nrows-1, since the
9878  * basis has the size nrows * nrows */
9879  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9880  int* inds, /**< array to store the non-zero indices, or NULL */
9881  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9882  * (-1: if we do not store sparsity informations) */
9883  )
9884 {
9885  assert(lp != NULL);
9886  assert(lp->flushed);
9887  assert(lp->solved);
9888  assert(lp->solisbasic);
9889  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9890  assert(coef != NULL);
9891 
9892  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9893 
9894  return SCIP_OKAY;
9895 }
9896 
9897 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9899  SCIP_LP* lp, /**< LP data */
9900  int r, /**< row number */
9901  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9902  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9903  int* inds, /**< array to store the non-zero indices, or NULL */
9904  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9905  * (-1: if we do not store sparsity informations) */
9906  )
9907 {
9908  assert(lp != NULL);
9909  assert(lp->flushed);
9910  assert(lp->solved);
9911  assert(lp->solisbasic);
9912  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9913  assert(coef != NULL);
9914 
9915  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9916 
9917  return SCIP_OKAY;
9918 }
9919 
9920 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9921  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9922  */
9924  SCIP_LP* lp, /**< LP data */
9925  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9926  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9927  int* inds, /**< array to store the non-zero indices, or NULL */
9928  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9929  * (-1: if we do not store sparsity informations) */
9930  )
9931 {
9932  assert(lp != NULL);
9933  assert(lp->flushed);
9934  assert(lp->solved);
9935  assert(lp->solisbasic);
9936  assert(0 <= c && c < lp->ncols);
9937  assert(coef != NULL);
9938 
9939  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9940 
9941  return SCIP_OKAY;
9942 }
9943 
9944 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9945  * LP row are swapped in the summation
9946  */
9948  SCIP_LP* lp, /**< LP data */
9949  SCIP_SET* set, /**< global SCIP settings */
9950  SCIP_PROB* prob, /**< problem data */
9951  SCIP_Real* weights, /**< row weights in row summation */
9952  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9953  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9954  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9955  )
9956 {
9957  SCIP_ROW* row;
9958  int r;
9959  int i;
9960  int idx;
9961  SCIP_Bool lhsinfinite;
9962  SCIP_Bool rhsinfinite;
9963 
9964  assert(lp != NULL);
9965  assert(prob != NULL);
9966  assert(weights != NULL);
9967  assert(sumcoef != NULL);
9968  assert(sumlhs != NULL);
9969  assert(sumrhs != NULL);
9970 
9971  /**@todo test, if a column based summation is faster */
9972 
9973  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9974  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9975  *sumlhs = 0.0;
9976  *sumrhs = 0.0;
9977  lhsinfinite = FALSE;
9978  rhsinfinite = FALSE;
9979  for( r = 0; r < lp->nrows; ++r )
9980  {
9981  if( !SCIPsetIsZero(set, weights[r]) )
9982  {
9983  row = lp->rows[r];
9984  assert(row != NULL);
9985  assert(row->len == 0 || row->cols != NULL);
9986  assert(row->len == 0 || row->cols_index != NULL);
9987  assert(row->len == 0 || row->vals != NULL);
9988 
9989  /* add the row coefficients to the sum */
9990  for( i = 0; i < row->len; ++i )
9991  {
9992  assert(row->cols[i] != NULL);
9993  assert(row->cols[i]->var != NULL);
9994  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9995  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9996  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9997  idx = row->cols[i]->var_probindex;
9998  assert(0 <= idx && idx < prob->nvars);
9999  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
10000  }
10001 
10002  /* add the row sides to the sum, depending on the sign of the weight */
10003  if( weights[r] > 0.0 )
10004  {
10005  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10006  if( !lhsinfinite )
10007  (*sumlhs) += weights[r] * (row->lhs - row->constant);
10008  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10009  if( !rhsinfinite )
10010  (*sumrhs) += weights[r] * (row->rhs - row->constant);
10011  }
10012  else
10013  {
10014  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10015  if( !lhsinfinite )
10016  (*sumlhs) += weights[r] * (row->rhs - row->constant);
10017  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10018  if( !rhsinfinite )
10019  (*sumrhs) += weights[r] * (row->lhs - row->constant);
10020  }
10021  }
10022  }
10023 
10024  if( lhsinfinite )
10025  *sumlhs = -SCIPsetInfinity(set);
10026  if( rhsinfinite )
10027  *sumrhs = SCIPsetInfinity(set);
10028 
10029  return SCIP_OKAY;
10030 }
10031 
10032 /** stores LP state (like basis information) into LP state object */
10034  SCIP_LP* lp, /**< LP data */
10035  BMS_BLKMEM* blkmem, /**< block memory */
10036  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10037  )
10038 {
10039  assert(lp != NULL);
10040  assert(lp->flushed);
10041  assert(lp->solved);
10042  assert(blkmem != NULL);
10043  assert(lpistate != NULL);
10044 
10045  /* check whether there is no lp */
10046  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10047  *lpistate = NULL;
10048  else
10049  {
10050  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10051  }
10052 
10053  return SCIP_OKAY;
10054 }
10055 
10056 /** loads LP state (like basis information) into solver */
10058  SCIP_LP* lp, /**< LP data */
10059  BMS_BLKMEM* blkmem, /**< block memory */
10060  SCIP_SET* set, /**< global SCIP settings */
10061  SCIP_PROB* prob, /**< problem data */
10062  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10063  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10064  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10065  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10066  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10067  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10068  )
10069 {
10070  assert(lp != NULL);
10071  assert(blkmem != NULL);
10072 
10073  /* flush changes to the LP solver */
10074  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
10075  assert(lp->flushed);
10076 
10077  if( lp->solved && lp->solisbasic )
10078  return SCIP_OKAY;
10079 
10080  /* set LPI state in the LP solver */
10081  if( lpistate == NULL )
10082  lp->solisbasic = FALSE;
10083  else
10084  {
10085  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10086  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10087  }
10088  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10089  * flushed and solved, also, e.g., when we hit the iteration limit
10090  */
10091  lp->primalfeasible = wasprimfeas;
10092  lp->primalchecked = wasprimchecked;
10093  lp->dualfeasible = wasdualfeas;
10094  lp->dualchecked = wasdualchecked;
10095 
10096  return SCIP_OKAY;
10097 }
10098 
10099 /** frees LP state information */
10101  SCIP_LP* lp, /**< LP data */
10102  BMS_BLKMEM* blkmem, /**< block memory */
10103  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10104  )
10105 {
10106  assert(lp != NULL);
10107 
10108  if( *lpistate != NULL )
10109  {
10110  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10111  }
10112 
10113  return SCIP_OKAY;
10114 }
10115 
10116 /** interrupts the currently ongoing lp solve, or disables the interrupt */
10118  SCIP_LP* lp, /**< LP data */
10119  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
10120  )
10121 {
10122  assert(lp != NULL);
10123 
10124  if( lp->lpi == NULL )
10125  return SCIP_OKAY;
10126 
10127  SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
10128 
10129  return SCIP_OKAY;
10130 }
10131 
10132 /** stores pricing norms into LP norms object */
10134  SCIP_LP* lp, /**< LP data */
10135  BMS_BLKMEM* blkmem, /**< block memory */
10136  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10137  )
10138 {
10139  assert(lp != NULL);
10140  assert(lp->flushed);
10141  assert(lp->solved);
10142  assert(blkmem != NULL);
10143  assert(lpinorms != NULL);
10144 
10145  /* check whether there is no lp */
10146  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10147  *lpinorms = NULL;
10148  else
10149  {
10150  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10151  }
10152 
10153  return SCIP_OKAY;
10154 }
10155 
10156 /** loads pricing norms from LP norms object into solver */
10158  SCIP_LP* lp, /**< LP data */
10159  BMS_BLKMEM* blkmem, /**< block memory */
10160  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10161  )
10162 {
10163  assert(lp != NULL);
10164  assert(blkmem != NULL);
10165  assert(lp->flushed);
10166 
10167  /* set LPI norms in the LP solver */
10168  if( lpinorms != NULL )
10169  {
10170  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10171  }
10172 
10173  return SCIP_OKAY;
10174 }
10175 
10176 /** frees pricing norms information */
10178  SCIP_LP* lp, /**< LP data */
10179  BMS_BLKMEM* blkmem, /**< block memory */
10180  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10181  )
10182 {
10183  assert(lp != NULL);
10184 
10185  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10186 
10187  return SCIP_OKAY;
10188 }
10189 
10190 /** return the current cutoff bound of the lp */
10192  SCIP_LP* lp /**< current LP data */
10193  )
10194 {
10195  assert(lp != NULL);
10196 
10197  return lp->cutoffbound;
10198 }
10199 
10200 /** sets the upper objective limit of the LP solver */
10202  SCIP_LP* lp, /**< current LP data */
10203  SCIP_SET* set, /**< global SCIP settings */
10204  SCIP_PROB* prob, /**< problem data */
10205  SCIP_Real cutoffbound /**< new upper objective limit */
10206  )
10207 {
10208  assert(lp != NULL);
10209 
10210  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10211 
10212  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10213  * in SCIPendDive())
10214  */
10215  if( SCIPlpDivingObjChanged(lp) )
10216  {
10217  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10218  return SCIP_OKAY;
10219  }
10220 
10221  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10222  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10223  {
10224  /* mark the current solution invalid */
10225  lp->solved = FALSE;
10226  lp->lpobjval = SCIP_INVALID;
10228  }
10229  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10230  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10231  */
10232  else if( !lpCutoffDisabled(set, prob) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
10233  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10234  {
10235  assert(lp->flushed);
10236  assert(lp->solved);
10238  }
10239 
10240  lp->cutoffbound = cutoffbound;
10241 
10242  return SCIP_OKAY;
10243 }
10244 
10245 /** gets current primal feasibility tolerance of LP solver */
10247  SCIP_LP* lp /**< current LP data */
10248  )
10249 {
10250  assert(lp != NULL);
10251 
10252  return lp->feastol;
10253 }
10254 
10255 /** sets primal feasibility tolerance of LP solver */
10257  SCIP_LP* lp, /**< current LP data */
10258  SCIP_SET* set, /**< global SCIP settings */
10259  SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10260  )
10261 {
10262  assert(lp != NULL);
10263  assert(newfeastol > 0.0);
10264 
10265  SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10266 
10267  /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10268  if( newfeastol < lp->feastol )
10269  {
10270  lp->solved = FALSE;
10272  }
10273 
10274  lp->feastol = newfeastol;
10275 }
10276 
10277 /** resets primal feasibility tolerance of LP solver
10278  *
10279  * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10280  */
10282  SCIP_LP* lp, /**< current LP data */
10283  SCIP_SET* set /**< global SCIP settings */
10284  )
10285 {
10286  assert(lp != NULL);
10287 
10288  SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10289 
10290  if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10291  SCIPlpSetFeastol(lp, set, MIN(SCIPsetRelaxfeastol(set), SCIPsetLPFeastolFactor(set) * SCIPsetFeastol(set))); /*lint !e666*/
10292  else
10294 }
10295 
10296 /** returns the name of the given LP algorithm */
10297 static
10298 const char* lpalgoName(
10299  SCIP_LPALGO lpalgo /**< LP algorithm */
10300  )
10301 {
10302  switch( lpalgo )
10303  {
10305  return "primal simplex";
10307  return "dual simplex";
10308  case SCIP_LPALGO_BARRIER:
10309  return "barrier";
10311  return "barrier/crossover";
10312  default:
10313  SCIPerrorMessage("invalid LP algorithm\n");
10314  SCIPABORT();
10315  return "invalid"; /*lint !e527*/
10316  }
10317 }
10318 
10319 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10320 static
10322  SCIP_LP* lp, /**< current LP data */
10323  SCIP_SET* set, /**< global SCIP settings */
10324  SCIP_STAT* stat, /**< problem statistics */
10325  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10326  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10327  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10328  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10329  )
10330 {
10331  SCIP_Real timedelta;
10332  SCIP_RETCODE retcode;
10333  int iterations;
10334 
10335  assert(lp != NULL);
10336  assert(lp->flushed);
10337  assert(set != NULL);
10338  assert(stat != NULL);
10339  assert(lperror != NULL);
10340 
10341  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",
10342  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10343 
10344  *lperror = FALSE;
10345 
10346 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10347  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10348  {
10349  char fname[SCIP_MAXSTRLEN];
10350  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10351  SCIP_CALL( SCIPlpWrite(lp, fname) );
10352  SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10353  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10354  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10355  }
10356 #endif
10357 
10358  /* start timing */
10359  if( lp->diving || lp->probing )
10360  {
10361  if( lp->strongbranchprobing )
10362  SCIPclockStart(stat->strongbranchtime, set);
10363  else
10364  SCIPclockStart(stat->divinglptime, set);
10365 
10366  timedelta = 0.0; /* unused for diving or probing */
10367  }
10368  else
10369  {
10370  SCIPclockStart(stat->primallptime, set);
10371  timedelta = -SCIPclockGetTime(stat->primallptime);
10372  }
10373 
10374  /* if this is a call to resolve an instable LP, collect time */
10375  if( instable )
10376  {
10378  }
10379 
10380  /* call primal simplex */
10381  retcode = SCIPlpiSolvePrimal(lp->lpi);
10382  if( retcode == SCIP_LPERROR )
10383  {
10384  *lperror = TRUE;
10385  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10386  }
10387  else
10388  {
10389  SCIP_CALL( retcode );
10390  }
10392  lp->solisbasic = TRUE;
10393 
10394  /* stop timing */
10395  if( lp->diving || lp->probing )
10396  {
10397  if( lp->strongbranchprobing )
10398  SCIPclockStop(stat->strongbranchtime, set);
10399  else
10400  SCIPclockStop(stat->divinglptime, set);
10401  }
10402  else
10403  {
10404  timedelta += SCIPclockGetTime(stat->primallptime);
10405  SCIPclockStop(stat->primallptime, set);
10406  }
10407 
10408  if ( instable )
10409  {
10411  }
10412 
10413  /* count number of iterations */
10414  SCIPstatIncrement(stat, set, lpcount);
10415  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10416  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10417  {
10418  if( !lp->strongbranchprobing )
10419  {
10420  SCIPstatIncrement(stat, set, nlps);
10421  SCIPstatAdd( stat, set, nlpiterations, iterations );
10422  }
10423  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10424  {
10425  SCIPstatIncrement(stat, set, nprimalresolvelps );
10426  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10427  }
10428  if ( instable )
10429  {
10430  SCIPstatIncrement(stat, set, nresolveinstablelps);
10431  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10432  }
10433  if( lp->diving || lp->probing )
10434  {
10435  if( lp->strongbranchprobing )
10436  {
10437  SCIPstatIncrement(stat, set, nsbdivinglps);
10438  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10439  }
10440  else
10441  {
10442  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10443  SCIPstatIncrement(stat, set, ndivinglps);
10444  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10445  }
10446  }
10447  else
10448  {
10449  SCIPstatIncrement(stat, set, nprimallps);
10450  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10451  }
10452  }
10453  else
10454  {
10455  if ( ! lp->diving && ! lp->probing )
10456  {
10457  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10458  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10459  }
10460 
10461  if ( keepsol && !(*lperror) )
10462  {
10463  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10464  if( lp->validsollp == stat->lpcount-1 )
10465  lp->validsollp = stat->lpcount;
10466  if( lp->validfarkaslp == stat->lpcount-1 )
10467  lp->validfarkaslp = stat->lpcount;
10468  }
10469  }
10470 
10471  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10472  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10473 
10474  return SCIP_OKAY;
10475 }
10476 
10477 /** calls LPI to perform dual simplex, measures time and counts iterations */
10478 static
10480  SCIP_LP* lp, /**< current LP data */
10481  SCIP_SET* set, /**< global SCIP settings */
10482  SCIP_STAT* stat, /**< problem statistics */
10483  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10484  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10485  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10486  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10487  )
10488 {
10489  SCIP_Real timedelta;
10490  SCIP_RETCODE retcode;
10491  int iterations;
10492 
10493  assert(lp != NULL);
10494  assert(lp->flushed);
10495  assert(set != NULL);
10496  assert(stat != NULL);
10497  assert(lperror != NULL);
10498 
10499  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",
10500  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10501 
10502  *lperror = FALSE;
10503 
10504 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10505  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10506  {
10507  char fname[SCIP_MAXSTRLEN];
10508  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10509  SCIP_CALL( SCIPlpWrite(lp, fname) );
10510  SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10511  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10512  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10513  }
10514 #endif
10515 
10516  /* start timing */
10517  if( lp->diving || lp->probing )
10518  {
10519  if( lp->strongbranchprobing )
10520  SCIPclockStart(stat->strongbranchtime, set);
10521  else
10522  SCIPclockStart(stat->divinglptime, set);
10523 
10524  timedelta = 0.0; /* unused for diving or probing */
10525  }
10526  else
10527  {
10528  SCIPclockStart(stat->duallptime, set);
10529  timedelta = -SCIPclockGetTime(stat->duallptime);
10530  }
10531 
10532  /* if this is a call to resolve an instable LP, collect time */
10533  if ( instable )
10534  {
10536  }
10537 
10538  /* call dual simplex */
10539  retcode = SCIPlpiSolveDual(lp->lpi);
10540  if( retcode == SCIP_LPERROR )
10541  {
10542  *lperror = TRUE;
10543  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10544  }
10545  else
10546  {
10547  SCIP_CALL( retcode );
10548  }
10550  lp->solisbasic = TRUE;
10551 
10552  /* stop timing */
10553  if( lp->diving || lp->probing )
10554  {
10555  if( lp->strongbranchprobing )
10556  SCIPclockStop(stat->strongbranchtime, set);
10557  else
10558  SCIPclockStop(stat->divinglptime, set);
10559  }
10560  else
10561  {
10562  timedelta += SCIPclockGetTime(stat->duallptime);
10563  SCIPclockStop(stat->duallptime, set);
10564  }
10565 
10566  if ( instable )
10567  {
10569  }
10570 
10571  /* count number of iterations */
10572  SCIPstatIncrement(stat, set, lpcount);
10573  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10574  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10575  {
10576  if( !lp->strongbranchprobing )
10577  {
10578  SCIPstatIncrement(stat, set, nlps);
10579  SCIPstatAdd(stat, set, nlpiterations, iterations);
10580  }
10581  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10582  {
10583  SCIPstatIncrement(stat, set, ndualresolvelps);
10584  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10585  }
10586  if ( instable )
10587  {
10588  SCIPstatIncrement(stat, set, nresolveinstablelps);
10589  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10590  }
10591  if( lp->diving || lp->probing )
10592  {
10593  if( lp->strongbranchprobing )
10594  {
10595  SCIPstatIncrement(stat, set, nsbdivinglps);
10596  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10597  }
10598  else
10599  {
10600  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10601  SCIPstatIncrement(stat, set, ndivinglps);
10602  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10603  }
10604  }
10605  else
10606  {
10607  SCIPstatIncrement(stat, set, nduallps);
10608  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10609  }
10610  }
10611  else
10612  {
10613  if ( ! lp->diving && ! lp->probing )
10614  {
10615  SCIPstatIncrement(stat, set, ndualzeroitlps);
10616  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10617  }
10618 
10619  if( keepsol && !(*lperror) )
10620  {
10621  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10622  if( lp->validsollp == stat->lpcount-1 )
10623  lp->validsollp = stat->lpcount;
10624  if( lp->validfarkaslp == stat->lpcount-1 )
10625  lp->validfarkaslp = stat->lpcount;
10626  }
10627  }
10628 
10629  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10630  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10631 
10632  return SCIP_OKAY;
10633 }
10634 
10635 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10636  *
10637  * We follow the approach of the following paper to find a lexicographically minimal optimal
10638  * solution:
10639  *
10640  * Zanette, Fischetti, Balas@n
10641  * Can pure cutting plane algorithms work?@n
10642  * IPCO 2008, Bertinoro, Italy.
10643  *
10644  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10645  * heuristic, i.e., we limit the number of components which are minimized.
10646  *
10647  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10648  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10649  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10650  * pivots that will not change the objective are allowed afterwards.
10651  *
10652  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10653  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10654  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10655  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10656  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10657  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10658  * reduced cost. We then choose the next variable and iterate.
10659  *
10660  * We stop the process once we do not find candidates or have performed a maximum number of
10661  * iterations.
10662  *
10663  * @todo Does this really produce a lexicographically minimal solution?
10664  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10665  * guarantee that these variables will not be changed in later stages? We can fix these variables
10666  * to their lower bound, but this destroys the basis.
10667  * @todo Should we use lexicographical minimization in diving/probing or not?
10668  */
10669 static
10671  SCIP_LP* lp, /**< current LP data */
10672  SCIP_SET* set, /**< global SCIP settings */
10673  SCIP_STAT* stat, /**< problem statistics */
10674  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10675  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10676  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10677  )
10678 {
10679  SCIP_Real timedelta;
10680  SCIP_RETCODE retcode;
10681  int totalIterations;
10682  int lexIterations;
10683  int iterations;
10684  int rounds;
10685 
10686  assert(lp != NULL);
10687  assert(lp->flushed);
10688  assert(set != NULL);
10689  assert(stat != NULL);
10690  assert(lperror != NULL);
10691 
10692  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",
10693  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10694 
10695  *lperror = FALSE;
10696 
10697  /* start timing */
10698  if( lp->diving || lp->probing )
10699  {
10700  if( lp->strongbranchprobing )
10701  SCIPclockStart(stat->strongbranchtime, set);
10702  else
10703  SCIPclockStart(stat->divinglptime, set);
10704 
10705  timedelta = 0.0; /* unused for diving or probing */
10706  }
10707  else
10708  {
10709  SCIPclockStart(stat->duallptime, set);
10710  timedelta = -SCIPclockGetTime(stat->duallptime);
10711  }
10712 
10713  /* call dual simplex for first lp */
10714  retcode = SCIPlpiSolveDual(lp->lpi);
10715  if( retcode == SCIP_LPERROR )
10716  {
10717  *lperror = TRUE;
10718  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10719  }
10720  else
10721  {
10722  SCIP_CALL( retcode );
10723  }
10724  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10725  totalIterations = iterations;
10726 
10727  /* stop timing */
10728  if( lp->diving || lp->probing )
10729  {
10730  if( lp->strongbranchprobing )
10731  SCIPclockStop(stat->strongbranchtime, set);
10732  else
10733  SCIPclockStop(stat->divinglptime, set);
10734  }
10735  else
10736  {
10737  timedelta += SCIPclockGetTime(stat->duallptime);
10738  SCIPclockStop(stat->duallptime, set);
10739  }
10740 
10741  /* count number of iterations */
10742  SCIPstatIncrement(stat, set, lpcount);
10743  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10744  {
10745  if( lp->strongbranchprobing )
10746  {
10747  SCIPstatAdd(stat, set, nlpiterations, iterations);
10748  }
10749  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10750  {
10751  SCIPstatIncrement(stat, set, ndualresolvelps);
10752  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10753  }
10754  if( lp->diving || lp->probing )
10755  {
10756  if( lp->strongbranchprobing )
10757  {
10758  SCIPstatIncrement(stat, set, nsbdivinglps);
10759  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10760  }
10761  else
10762  {
10763  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10764  SCIPstatIncrement(stat, set, ndivinglps);
10765  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10766  }
10767  }
10768  else
10769  {
10770  SCIPstatIncrement(stat, set, nduallps);
10771  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10772  }
10773  }
10774  else
10775  {
10776  if ( ! lp->diving && ! lp->probing )
10777  {
10778  SCIPstatIncrement(stat, set, ndualzeroitlps);
10779  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10780  }
10781  }
10782  lexIterations = 0;
10783 
10784  /* search for lexicographically minimal optimal solution */
10785  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10786  {
10787  SCIP_Bool chooseBasic;
10788  SCIP_Real* primsol;
10789  SCIP_Real* dualsol;
10790  SCIP_Real* redcost;
10791  int* cstat;
10792  int* rstat;
10793  SCIP_Real* newobj;
10794  SCIP_Real* newlb;
10795  SCIP_Real* newub;
10796  SCIP_Real* newlhs;
10797  SCIP_Real* newrhs;
10798  SCIP_Real* oldlb;
10799  SCIP_Real* oldub;
10800  SCIP_Real* oldlhs;
10801  SCIP_Real* oldrhs;
10802  SCIP_Real* oldobj;
10803  SCIP_Bool* fixedc;
10804  SCIP_Bool* fixedr;
10805  int* indcol;
10806  int* indrow;
10807  int* indallcol;
10808  int* indallrow;
10809  int nDualDeg;
10810  int r, c;
10811  int cntcol;
10812  int cntrow;
10813  int nruns;
10814  int pos;
10815 
10816  chooseBasic = set->lp_lexdualbasic;
10817 
10818  /* start timing */
10819  SCIPclockStart(stat->lexduallptime, set);
10820 
10821  /* get all solution information */
10822  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10823  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10824  if( chooseBasic )
10825  {
10826  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10827  }
10828  else
10829  primsol = NULL;
10830 
10831  /* get basic and nonbasic information */
10832  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10833  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10834 
10835  /* save bounds, lhs/rhs, and objective */
10836  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10837  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10838  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10839  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10840  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10841  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10842  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10843  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10844 
10845  /* get storage for several arrays */
10846  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10847  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10848  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10849 
10850  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10851  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10852  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10853 
10854  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10855  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10856 
10857  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10858  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10859 
10860  /* initialize: set objective to 0, get fixed variables */
10861  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10862  for( c = 0; c < lp->nlpicols; ++c )
10863  {
10864  newobj[c] = 0.0;
10865  indallcol[c] = c;
10866  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10867  fixedc[c] = TRUE;
10868  else
10869  fixedc[c] = FALSE;
10870  }
10871 
10872  /* initialize: get fixed slack variables */
10873  for( r = 0; r < lp->nlpirows; ++r )
10874  {
10875  indallrow[r] = r;
10876  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10877  fixedr[r] = TRUE;
10878  else
10879  fixedr[r] = FALSE;
10880  }
10881 
10882 #ifdef DEBUG_LEXDUAL
10883  {
10884  int j;
10885 
10886  if( !chooseBasic )
10887  {
10888  assert(primsol == NULL);
10889  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10890  }
10891  assert(primsol != NULL);
10892  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10893  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10894 
10895  for( j = 0; j < lp->nlpicols; ++j )
10896  {
10897  if( fixedc[j] )
10898  {
10899  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10900  }
10901  else
10902  {
10903  char type;
10904  switch( (SCIP_BASESTAT) cstat[j] )
10905  {
10906  case SCIP_BASESTAT_LOWER:
10907  type = 'l';
10908  break;
10909  case SCIP_BASESTAT_UPPER:
10910  type = 'u';
10911  break;
10912  case SCIP_BASESTAT_ZERO:
10913  type = 'z';
10914  break;
10915  case SCIP_BASESTAT_BASIC:
10916  type = 'b';
10917  break;
10918  default:
10919  type = '?';
10920  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10921  SCIPABORT();
10922  }
10923  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10924  }
10925  }
10926  SCIPsetDebugMsg(set, "\n\n");
10927 
10928  if( !chooseBasic )
10929  {
10930  SCIPsetFreeBufferArray(set, &primsol);
10931  assert(primsol == NULL);
10932  }
10933  }
10934 #endif
10935 
10936  /* perform lexicographic rounds */
10937  pos = -1;
10938  nruns = 0;
10939  rounds = 0;
10940  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10941  do
10942  {
10943  int oldpos;
10944 
10945  /* get current solution */
10946  if( chooseBasic )
10947  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10948  else
10949  {
10950  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10951  assert(primsol == NULL);
10952  }
10953 
10954  /* get current basis */
10955  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10956 
10957  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10958  nDualDeg = 0;
10959  cntcol = 0;
10960  oldpos = pos;
10961  pos = -1;
10962  for( c = 0; c < lp->nlpicols; ++c )
10963  {
10964  if( !fixedc[c] )
10965  {
10966  /* check whether variable is in basis */
10967  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10968  {
10969  /* store first candidate */
10970  if( pos == -1 && c > oldpos )
10971  {
10972  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10973  pos = c;
10974  }
10975  }
10976  else
10977  {
10978  /* reduced cost == 0 -> possible candidate */
10979  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10980  {
10981  ++nDualDeg;
10982  /* only if we have not yet found a candidate */
10983  if( pos == -1 && c > oldpos )
10984  {
10985  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10986  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10987  {
10988  newlb[cntcol] = oldlb[c];
10989  newub[cntcol] = oldlb[c];
10990  indcol[cntcol++] = c;
10991  fixedc[c] = TRUE;
10992  }
10993  else /* found a non-fixed candidate */
10994  {
10995  if( !chooseBasic )
10996  pos = c;
10997  }
10998  }
10999  }
11000  else
11001  {
11002  /* nonzero reduced cost -> variable can be fixed */
11003  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
11004  {
11005  newlb[cntcol] = oldlb[c];
11006  newub[cntcol] = oldlb[c];
11007  }
11008  else
11009  {
11010  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
11011  {
11012  newlb[cntcol] = oldub[c];
11013  newub[cntcol] = oldub[c];
11014  }
11015  else
11016  {
11017  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
11018  newlb[cntcol] = 0.0;
11019  newub[cntcol] = 0.0;
11020  }
11021  }
11022  indcol[cntcol++] = c;
11023  fixedc[c] = TRUE;
11024  }
11025  }
11026  }
11027  }
11028 
11029  /* check rows */
11030  cntrow = 0;
11031  for( r = 0; r < lp->nlpirows; ++r )
11032  {
11033  if( !fixedr[r] )
11034  {
11035  /* consider only nonbasic rows */
11036  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11037  {
11038  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
11039  if( SCIPsetIsFeasZero(set, dualsol[r]) )
11040  ++nDualDeg;
11041  else
11042  {
11043  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11044  {
11045  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11046  newlhs[cntrow] = oldlhs[r];
11047  newrhs[cntrow] = oldlhs[r];
11048  }
11049  else
11050  {
11051  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11052  newlhs[cntrow] = oldrhs[r];
11053  newrhs[cntrow] = oldrhs[r];
11054  }
11055  indrow[cntrow++] = r;
11056  fixedr[r] = TRUE;
11057  }
11058  }
11059  }
11060  }
11061 
11062  if( nDualDeg > 0 && pos >= 0 )
11063  {
11064  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11065 
11066  /* change objective */
11067  if( nruns == 0 )
11068  {
11069  /* set objective to appropriate unit vector for first run */
11070  newobj[pos] = 1.0;
11071  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11072  }
11073  else
11074  {
11075  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11076  SCIP_Real obj = 1.0;
11077  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11078  }
11079 
11080  /* fix variables */
11081  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11082  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11083 
11084  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11085  retcode = SCIPlpiSolvePrimal(lp->lpi);
11086  if( retcode == SCIP_LPERROR )
11087  {
11088  *lperror = TRUE;
11089  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11090  }
11091  else
11092  {
11093  SCIP_CALL( retcode );
11094  }
11095  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11096  lexIterations += iterations;
11097 
11098 #ifdef DEBUG_LEXDUAL
11099  if( iterations > 0 )
11100  {
11101  int j;
11102 
11103  if( !chooseBasic )
11104  {
11105  assert(primsol == NULL);
11106  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
11107  }
11108  assert(primsol != NULL);
11109  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
11110 
11111  for( j = 0; j < lp->nlpicols; ++j )
11112  {
11113  if( fixedc[j] )
11114  {
11115  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11116  }
11117  else
11118  {
11119  char cstart = '[';
11120  char cend = ']';
11121  char type;
11122 
11123  if(j == pos)
11124  {
11125  cstart = '*';
11126  cend = '*';
11127  }
11128 
11129  switch( (SCIP_BASESTAT) cstat[j] )
11130  {
11131  case SCIP_BASESTAT_LOWER:
11132  type = 'l';
11133  break;
11134  case SCIP_BASESTAT_UPPER:
11135  type = 'u';
11136  break;
11137  case SCIP_BASESTAT_ZERO:
11138  type = 'z';
11139  break;
11140  case SCIP_BASESTAT_BASIC:
11141  type = 'b';
11142  break;
11143  default:
11144  type = '?';
11145  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11146  SCIPABORT();
11147  }
11148  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11149  }
11150  }
11151  SCIPsetDebugMsg(set, "\n\n");
11152 
11153  if( !chooseBasic )
11154  {
11155  SCIPsetFreeBufferArray(set, &primsol);
11156  assert(primsol == NULL);
11157  }
11158  }
11159 #endif
11160 
11161  /* count only as round if iterations have been performed */
11162  if( iterations > 0 )
11163  ++rounds;
11164  ++nruns;
11165  }
11166  }
11167  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11168 
11169  /* reset bounds, lhs/rhs, and obj */
11170  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11171  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11172  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11173 
11174  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
11175  retcode = SCIPlpiSolveDual(lp->lpi);
11176  if( retcode == SCIP_LPERROR )
11177  {
11178  *lperror = TRUE;
11179  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11180  }
11181  else
11182  {
11183  SCIP_CALL( retcode );
11184  }
11185  assert(SCIPlpiIsOptimal(lp->lpi));
11186  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11187  lexIterations += iterations;
11188 
11189  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11190 
11191  /* count number of iterations */
11192  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11193  SCIPstatIncrement(stat, set, nlps);
11194 
11195  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11196  {
11197  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11198  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11199  {
11200  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11201  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11202  }
11203  SCIPstatIncrement(stat, set, nlexduallps);
11204  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11205 
11206  totalIterations += lexIterations;
11207  }
11208 
11209  /* free space */
11210  SCIPsetFreeBufferArray(set, &newobj);
11211 
11212  SCIPsetFreeBufferArray(set, &fixedr);
11213  SCIPsetFreeBufferArray(set, &fixedc);
11214 
11215  SCIPsetFreeBufferArray(set, &indallrow);
11216  SCIPsetFreeBufferArray(set, &indallcol);
11217 
11218  SCIPsetFreeBufferArray(set, &indrow);
11219  SCIPsetFreeBufferArray(set, &newrhs);
11220  SCIPsetFreeBufferArray(set, &newlhs);
11221 
11222  SCIPsetFreeBufferArray(set, &indcol);
11223  SCIPsetFreeBufferArray(set, &newub);
11224  SCIPsetFreeBufferArray(set, &newlb);
11225 
11226  SCIPsetFreeBufferArray(set, &oldobj);
11227  SCIPsetFreeBufferArray(set, &oldrhs);
11228  SCIPsetFreeBufferArray(set, &oldlhs);
11229  SCIPsetFreeBufferArray(set, &oldub);
11230  SCIPsetFreeBufferArray(set, &oldlb);
11231 
11232  SCIPsetFreeBufferArray(set, &rstat);
11233  SCIPsetFreeBufferArray(set, &cstat);
11234 
11235  SCIPsetFreeBufferArray(set, &redcost);
11236  SCIPsetFreeBufferArray(set, &dualsol);
11237  if( chooseBasic )
11238  SCIPsetFreeBufferArray(set, &primsol);
11239 
11240  /* stop timing */
11241  SCIPclockStop(stat->lexduallptime, set);
11242 
11243  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11244  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11245  }
11247  lp->solisbasic = TRUE;
11248 
11249  if( totalIterations > 0 && !lp->strongbranchprobing )
11250  SCIPstatIncrement(stat, set, nlps);
11251  else
11252  {
11253  if( keepsol && !(*lperror) )
11254  {
11255  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11256  if( lp->validsollp == stat->lpcount-1 )
11257  lp->validsollp = stat->lpcount;
11258  if( lp->validfarkaslp == stat->lpcount-1 )
11259  lp->validfarkaslp = stat->lpcount;
11260  }
11261  }
11262 
11263  return SCIP_OKAY;
11264 }
11265 
11266 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11267 static
11269  SCIP_LP* lp, /**< current LP data */
11270  SCIP_SET* set, /**< global SCIP settings */
11271  SCIP_STAT* stat, /**< problem statistics */
11272  SCIP_Bool crossover, /**< should crossover be performed? */
11273  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11274  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11275  )
11276 {
11277  SCIP_Real timedelta;
11278  SCIP_RETCODE retcode;
11279  int iterations;
11280 
11281  assert(lp != NULL);
11282  assert(lp->flushed);
11283  assert(set != NULL);
11284  assert(stat != NULL);
11285  assert(lperror != NULL);
11286 
11287  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",
11288  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11289  stat->nbarrierlps, stat->ndivinglps);
11290 
11291  *lperror = FALSE;
11292 
11293 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11294  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11295  {
11296  char fname[SCIP_MAXSTRLEN];
11297  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11298  SCIP_CALL( SCIPlpWrite(lp, fname) );
11299  SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11300  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11301  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11302  }
11303 #endif
11304 
11305  /* start timing */
11306  if( lp->diving || lp->probing )
11307  {
11308  if( lp->strongbranchprobing )
11309  SCIPclockStart(stat->strongbranchtime, set);
11310  else
11311  SCIPclockStart(stat->divinglptime, set);
11312 
11313  timedelta = 0.0; /* unused for diving or probing */
11314  }
11315  else
11316  {
11317  SCIPclockStart(stat->barrierlptime, set);
11318  timedelta = -SCIPclockGetTime(stat->barrierlptime);
11319  }
11320 
11321  /* call barrier algorithm */
11322  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11323  if( retcode == SCIP_LPERROR )
11324  {
11325  *lperror = TRUE;
11326  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11327  }
11328  else
11329  {
11330  SCIP_CALL( retcode );
11331  }
11333  lp->solisbasic = crossover;
11334 
11335  /* stop timing */
11336  if( lp->diving || lp->probing )
11337  {
11338  if( lp->strongbranchprobing )
11339  SCIPclockStop(stat->strongbranchtime, set);
11340  else
11341  SCIPclockStop(stat->divinglptime, set);
11342  }
11343  else
11344  {
11345  SCIPclockStop(stat->barrierlptime, set);
11346  timedelta += SCIPclockGetTime(stat->barrierlptime);
11347  }
11348 
11349  /* count number of iterations */
11350  SCIPstatIncrement(stat, set, lpcount);
11351  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11352  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11353  {
11354  if( !lp->strongbranchprobing )
11355  {
11356  SCIPstatIncrement(stat, set, nlps);
11357  SCIPstatAdd(stat, set, nlpiterations, iterations);
11358  }
11359  if( lp->diving || lp->probing )
11360  {
11361  if( lp->strongbranchprobing )
11362  {
11363  SCIPstatIncrement(stat, set, nsbdivinglps);
11364  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11365  }
11366  else
11367  {
11368  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11369  SCIPstatIncrement(stat, set, ndivinglps);
11370  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11371  }
11372  }
11373  else
11374  {
11375  SCIPstatIncrement(stat, set, nbarrierlps);
11376  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11377  }
11378  }
11379  else
11380  {
11381  if ( ! lp->diving && ! lp->probing )
11382  {
11383  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11384  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11385  }
11386 
11387  if( keepsol && !(*lperror) )
11388  {
11389  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11390  if( lp->validsollp == stat->lpcount-1 )
11391  lp->validsollp = stat->lpcount;
11392  if( lp->validfarkaslp == stat->lpcount-1 )
11393  lp->validfarkaslp = stat->lpcount;
11394  }
11395  }
11396 
11397  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11398  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11399 
11400  return SCIP_OKAY;
11401 }
11402 
11403 /** solves the LP with the given algorithm */
11404 static
11406  SCIP_LP* lp, /**< current LP data */
11407  SCIP_SET* set, /**< global SCIP settings */
11408  SCIP_STAT* stat, /**< problem statistics */
11409  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11410  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11411  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11412  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11413  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11414  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11415  )
11416 {
11417  SCIP_Real lptimelimit;
11418  SCIP_Bool success;
11419 
11420  assert(lp != NULL);
11421  assert(lp->flushed);
11422  assert(lperror != NULL);
11423 
11424  /* check if a time limit is set, and set time limit for LP solver accordingly */
11425  lptimelimit = SCIPlpiInfinity(lp->lpi);
11426  if( set->istimelimitfinite )
11427  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11428 
11429  success = FALSE;
11430  if( lptimelimit > 0.0 )
11431  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11432 
11433  if( lptimelimit <= 0.0 || !success )
11434  {
11435  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11436  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11437  *timelimit = TRUE;
11438  return SCIP_OKAY;
11439  }
11440  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11441 
11442  /* call appropriate LP algorithm */
11443  switch( lpalgo )
11444  {
11446  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11447  break;
11448 
11450  /* run dual lexicographic simplex if required */
11451  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11452  {
11453  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11454  }
11455  else
11456  {
11457  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11458  }
11459  break;
11460 
11461  case SCIP_LPALGO_BARRIER:
11462  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11463  break;
11464 
11466  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11467  break;
11468 
11469  default:
11470  SCIPerrorMessage("invalid LP algorithm\n");
11471  return SCIP_INVALIDDATA;
11472  }
11473 
11474  if( !(*lperror) )
11475  {
11476  /* check for primal and dual feasibility */
11478 
11479  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11480  }
11481 
11482  return SCIP_OKAY;
11483 }
11484 
11485 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11486  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11487  */
11488 #define MAXNUMTROUBLELPMSGS 10
11489 
11490 /** prints message about numerical trouble
11491  *
11492  * If message has verblevel at most high and display/verblevel is not full,
11493  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11494  * were printed before in the current run.
11495  */
11496 static
11498  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11499  SCIP_SET* set, /**< global SCIP settings */
11500  SCIP_STAT* stat, /**< problem statistics */
11501  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11502  const char* formatstr, /**< message format string */
11503  ... /**< arguments to format string */
11504  )
11505 {
11506  va_list ap;
11507 
11508  assert(verblevel > SCIP_VERBLEVEL_NONE);
11509  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11510  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11511 
11512  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11513  {
11514  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11515  {
11516  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11518  return;
11519 
11520  /* increase count on messages with verblevel high */
11521  ++stat->nnumtroublelpmsgs ;
11522  }
11523 
11524  /* if messages wouldn't be printed, then return already */
11525  if( verblevel > set->disp_verblevel )
11526  return;
11527  }
11528 
11529  /* print common begin of message */
11530  SCIPmessagePrintInfo(messagehdlr,
11531  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11532  stat->nnodes, stat->nlps);
11533 
11534  /* print individual part of message */
11535  va_start(ap, formatstr); /*lint !e838*/
11536  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11537  va_end(ap);
11538 
11539  /* warn that further messages will be suppressed */
11540  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11541  {
11542  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11543  }
11544 
11545  /* print closing new-line */
11546  SCIPmessagePrintInfo(messagehdlr, "\n");
11547 }
11548 
11549 static
11551  SCIP_LP* lp, /**< current LP data */
11552  SCIP_SET* set, /**< global SCIP settings */
11553  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11554  SCIP_STAT* stat, /**< problem statistics */
11555  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11556  SCIP_Bool* success /**< was instability successfully ignored */
11557  )
11558 {
11559  assert(lp != NULL);
11560  assert(set != NULL);
11561 
11562  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11563 
11564  if( *success )
11565  {
11566  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11567  if( !set->lp_checkdualfeas )
11568  lp->dualfeasible = TRUE;
11569  if( !set->lp_checkprimfeas )
11570  lp->primalchecked = TRUE;
11571  }
11572 
11573  return SCIP_OKAY;
11574 }
11575 
11576 #define FEASTOLTIGHTFAC 0.001
11577 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11578 static
11580  SCIP_LP* lp, /**< current LP data */
11581  SCIP_SET* set, /**< global SCIP settings */
11582  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11583  SCIP_STAT* stat, /**< problem statistics */
11584  SCIP_PROB* prob, /**< problem data */
11585  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11586  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11587  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11588  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11589  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11590  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11591  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11592  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11593  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
11594  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11595  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11596  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11597  )
11598 {
11599  SCIP_Bool success;
11600  SCIP_Bool success2;
11601  SCIP_Bool success3;
11602  SCIP_Bool simplex;
11603  SCIP_Bool itlimishard;
11604  SCIP_Bool usepolishing;
11605 
11606  assert(lp != NULL);
11607  assert(lp->flushed);
11608  assert(set != NULL);
11609  assert(stat != NULL);
11610  assert(lperror != NULL);
11611  assert(timelimit != NULL);
11612 
11613  *lperror = FALSE;
11614 
11615  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11616  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11617  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11618  * SCIP_LP such that we can return a primal ray
11619  */
11620  if( lp->looseobjvalinf > 0 )
11621  {
11622  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11623  return SCIP_ERROR;
11624  }
11625 
11626  /* check, whether we solve with a simplex algorithm */
11627  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11628 
11629  /* check whether the iteration limit is a hard one */
11630  itlimishard = (itlim == harditlim);
11631 
11632  /* check whether solution polishing should be used */
11633  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11634  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11635  {
11636  usepolishing = TRUE;
11637  if( lp->updateintegrality )
11638  {
11639  SCIP_CALL( lpCopyIntegrality(lp, set) );
11640  }
11641  }
11642  else
11643  usepolishing = FALSE;
11644 
11645  /* solve with given settings (usually fast but imprecise) */
11646  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11647  {
11648  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound, &success) );
11649  }
11650  else
11651  {
11652  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11653  }
11654  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11655  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11656  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11657  &success) );
11658  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11659  : SCIPsetBarrierconvtol(set), &success) );
11660  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11661  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11662  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11663  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11664  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11665  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11666  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11667  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11668  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11669  SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11670  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11671  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11672  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11673  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11674 
11675  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11676 
11677  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11678  * optimal without preforming scaling/change tolerances/presolving */
11679  resolve = FALSE;
11680 
11681  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11682  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11683  return SCIP_OKAY;
11684 
11685  if( !set->lp_checkstability )
11686  {
11687  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11688 
11689  if( success )
11690  return SCIP_OKAY;
11691  }
11692 
11693  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11694  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11695  */
11696 
11697  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11698  * do this only if the iteration limit was not exceeded in the last LP solving call
11699  */
11700  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11701  {
11702  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11703  if( success )
11704  {
11705  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11706  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11707 
11708  /* check for stability */
11709  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11710  return SCIP_OKAY;
11711 
11712  if( !set->lp_checkstability )
11713  {
11714  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11715 
11716  if( success )
11717  return SCIP_OKAY;
11718  }
11719  }
11720  }
11721 
11722  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11723  * and go directly to solving the LP from scratch
11724  */
11725  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11726  {
11727  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11728  SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
11729  if( success )
11730  {
11731  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11732  lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
11733  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11734 
11735  /* check for stability */
11736  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11737  return SCIP_OKAY;
11738 
11739  if( !set->lp_checkstability )
11740  {
11741  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11742 
11743  if( success )
11744  return SCIP_OKAY;
11745  }
11746 
11747  /* reset scaling */
11748  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11749  assert(success);
11750  }
11751  }
11752 
11753  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11754  * and go directly to solving the LP from scratch */
11755  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11756  {
11757  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11758  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11759  if( success )
11760  {
11761  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11762  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11763  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11764 
11765  /* check for stability */
11766  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11767  return SCIP_OKAY;
11768 
11769  if( !set->lp_checkstability )
11770  {
11771  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11772 
11773  if( success )
11774  return SCIP_OKAY;
11775  }
11776 
11777  /* reset presolving */
11778  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11779  assert(success);
11780  }
11781  }
11782 
11783  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11784  * do this only if the iteration limit was not exceeded in the last LP solving call
11785  */
11786  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11787  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11788  {
11789  success = FALSE;
11790  if( !tightprimfeastol )
11791  {
11792  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11793  }
11794 
11795  success2 = FALSE;
11796  if( !tightdualfeastol )
11797  {
11798  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11799  }
11800 
11801  success3 = FALSE;
11802  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11803  {
11804  SCIP_CALL( lpSetBarrierconvtol(lp, FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set), &success3) );
11805  }
11806 
11807  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11808  if( success || success2 || success3 )
11809  {
11810  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11811  lpalgoName(lpalgo));
11812  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11813 
11814  /* check for stability */
11815  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11816  return SCIP_OKAY;
11817 
11818  if( !set->lp_checkstability )
11819  {
11820  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11821 
11822  if( success )
11823  return SCIP_OKAY;
11824  }
11825 
11826  /* reset feasibility tolerance */
11827  if( !tightprimfeastol )
11828  {
11829  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11830  }
11831  if( !tightdualfeastol )
11832  {
11833  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11834  }
11835  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11836  {
11837  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11838  }
11839  }
11840  }
11841 
11842  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11843  * the given iteration limit might be a soft one to restrict resolving calls only */
11844  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11845 
11846  /* if not already done, solve again from scratch */
11847  if( !fromscratch && simplex )
11848  {
11849  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11850  if( success )
11851  {
11852  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11853  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11854 
11855  /* check for stability */
11856  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11857  return SCIP_OKAY;
11858 
11859  if( !set->lp_checkstability )
11860  {
11861  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11862 
11863  if( success )
11864  return SCIP_OKAY;
11865  }
11866  }
11867  }
11868 
11869  /* solve again, use other simplex this time */
11870  if( simplex )
11871  {
11873  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11874  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11875 
11876  /* check for stability */
11877  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11878  return SCIP_OKAY;
11879 
11880  if( !set->lp_checkstability )
11881  {
11882  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11883 
11884  if( success )
11885  return SCIP_OKAY;
11886  }
11887 
11888  /* solve again with opposite scaling and other simplex */
11889  SCIP_CALL( lpSetScaling(lp, (scaling > 0) ? 0 : 1, &success) );
11890  if( success )
11891  {
11892  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11893  lpalgoName(lpalgo), (scaling == 0) ? "with" : "without");
11894  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11895 
11896  /* check for stability */
11897  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11898  return SCIP_OKAY;
11899 
11900  if( !set->lp_checkstability )
11901  {
11902  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11903 
11904  if( success )
11905  return SCIP_OKAY;
11906  }
11907 
11908  /* reset scaling */
11909  SCIP_CALL( lpSetScaling(lp, scaling, &success) );
11910  assert(success);
11911  }
11912 
11913  /* solve again with opposite presolving and other simplex */
11914  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11915  if( success )
11916  {
11917  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11918  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11919  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11920 
11921  /* check for stability */
11922  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11923  return SCIP_OKAY;
11924 
11925  if( !set->lp_checkstability )
11926  {
11927  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11928 
11929  if( success )
11930  return SCIP_OKAY;
11931  }
11932 
11933  /* reset presolving */
11934  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11935  assert(success);
11936  }
11937 
11938  /* solve again with tighter feasibility tolerance, use other simplex this time */
11939  if( !tightprimfeastol || !tightdualfeastol )
11940  {
11941  success = FALSE;
11942  if( !tightprimfeastol )
11943  {
11944  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11945  }
11946 
11947  success2 = FALSE;
11948  if( !tightdualfeastol )
11949  {
11950  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11951  }
11952 
11953  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11954  if( success || success2 )
11955  {
11956  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11957  lpalgoName(lpalgo));
11958  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11959 
11960  /* check for stability */
11961  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11962  return SCIP_OKAY;
11963 
11964  if( !set->lp_checkstability )
11965  {
11966  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11967 
11968  if( success )
11969  return SCIP_OKAY;
11970  }
11971 
11972  /* reset feasibility tolerance */
11973  if( !tightprimfeastol )
11974  {
11975  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11976  }
11977  if( !tightdualfeastol )
11978  {
11979  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11980  }
11981  SCIP_UNUSED(success);
11982  }
11983  }
11984  }
11985 
11986  /* nothing worked -- exit with an LPERROR */
11987  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11988  *lperror = TRUE;
11989 
11990  return SCIP_OKAY;
11991 }
11992 
11993 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11994 static
11996  SCIP_LP* lp, /**< current LP data */
11997  SCIP_SET* set, /**< global SCIP settings */
11998  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11999  )
12000 {
12001  assert(lp != NULL);
12002  assert(set != NULL);
12003 
12004  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
12005  {
12006  if( !lp->adjustlpval && messagehdlr != NULL )
12007  {
12008  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
12009  lp->adjustlpval = TRUE;
12010  }
12011  lp->lpobjval = SCIPsetInfinity(set);
12012  }
12013  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
12014  {
12015  if( !lp->adjustlpval && messagehdlr != NULL )
12016  {
12017  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
12018  lp->adjustlpval = TRUE;
12019  }
12020  lp->lpobjval = -SCIPsetInfinity(set);
12021  }
12022 }
12023 
12024 /** solves the LP with the given algorithm and evaluates return status */
12025 static
12027  SCIP_LP* lp, /**< current LP data */
12028  SCIP_SET* set, /**< global SCIP settings */
12029  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12030  SCIP_STAT* stat, /**< problem statistics */
12031  SCIP_PROB* prob, /**< problem data */
12032  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12033  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12034  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12035  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12036  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12037  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12038  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12039  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12040  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12041  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12042  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12043  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12044  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12045  )
12046 {
12047  SCIP_Bool solvedprimal;
12048  SCIP_Bool solveddual;
12049  SCIP_Bool timelimit;
12050  int itlim;
12051 
12052  assert(lp != NULL);
12053  assert(lp->flushed);
12054  assert(set != NULL);
12055  assert(stat != NULL);
12056  assert(lperror != NULL);
12057 
12058  checkLinks(lp);
12059 
12060  solvedprimal = FALSE;
12061  solveddual = FALSE;
12062  timelimit = FALSE;
12063 
12064  /* select the basic iteration limit depending on whether this is a resolving call or not */
12065  itlim = ( resolve ? resolveitlim : harditlim );
12066 
12067  SOLVEAGAIN:
12068  /* call simplex */
12069  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12070  scaling, keepsol, &timelimit, lperror) );
12071  resolve = FALSE; /* only the first solve should be counted as resolving call */
12072  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12073  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12074 
12075  /* check, if an error occurred */
12076  if( *lperror )
12077  {
12078  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12079  lp->solved = FALSE;
12081  return SCIP_OKAY;
12082  }
12083 
12084  /* check, if a time limit was exceeded */
12085  if( timelimit )
12086  {
12087  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12088  lp->solved = TRUE;
12090  lp->lpobjval = -SCIPsetInfinity(set);
12091  return SCIP_OKAY;
12092  }
12093 
12094  /* only one should return true */
12095  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
12097 
12098  /* evaluate solution status */
12099  if( SCIPlpiIsOptimal(lp->lpi) )
12100  {
12101  assert(lp->primalfeasible);
12102  assert(lp->dualfeasible);
12104  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12105  adjustLPobjval(lp, set, messagehdlr);
12106 
12107  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
12108  {
12109  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12110  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12112  lp->lpobjval = SCIPsetInfinity(set);
12113  }
12114  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12115  * reached if the LP objective value is greater than the cutoff bound
12116  */
12117  assert(lpCutoffDisabled(set, prob) || lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT || SCIPsetIsInfinity(set, lp->cutoffbound)
12118  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12119  }
12120  else if( SCIPlpiIsObjlimExc(lp->lpi) )
12121  {
12122  assert(!lpCutoffDisabled(set, prob));
12123 
12124 #ifndef NDEBUG
12125  /* the LP solution objective should exceed the limit in this case; if this assert is triggered, it typically means
12126  * that the LP interface method SCIPlpiIsStable() lacks a check for this event and incorrectly returned TRUE */
12127  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12128  assert(!set->lp_checkstability || SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
12129 #endif
12130 
12132  lp->lpobjval = SCIPsetInfinity(set);
12133  }
12134  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12135  {
12136  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12137  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12138  {
12139  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12140  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12141  goto SOLVEAGAIN;
12142  }
12144  lp->lpobjval = SCIPsetInfinity(set);
12145  }
12146  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12147  {
12148  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12149  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12150  {
12151  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12152  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12153  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12154  goto SOLVEAGAIN;
12155  }
12157  lp->lpobjval = -SCIPsetInfinity(set);
12158  }
12159  else if( SCIPlpiIsIterlimExc(lp->lpi) )
12160  {
12161  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12162 
12163  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12164  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12165  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12166  adjustLPobjval(lp, set, NULL);
12167  else
12168  adjustLPobjval(lp, set, messagehdlr);
12169 
12171  }
12172  else if( SCIPlpiIsTimelimExc(lp->lpi) )
12173  {
12174  lp->lpobjval = -SCIPsetInfinity(set);
12176  }
12177  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12178  {
12179  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12180  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12181  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12182  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12183  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12184  goto SOLVEAGAIN;
12185  }
12186  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12187  {
12188  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12189  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12190  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12191  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12192  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12193  goto SOLVEAGAIN;
12194  }
12195  else
12196  {
12197  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12198  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12200  return SCIP_LPERROR;
12201  }
12202 
12203  lp->solved = TRUE;
12204 
12205  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12208 
12209  return SCIP_OKAY;
12210 }
12211 
12212 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12213 static
12215  SCIP_LP* lp, /**< current LP data */
12216  BMS_BLKMEM* blkmem, /**< block memory */
12217  SCIP_SET* set, /**< global SCIP settings */
12218  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12219  SCIP_STAT* stat, /**< problem statistics */
12220  SCIP_PROB* prob, /**< problem data */
12221  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12222  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12223  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12224  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12225  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12226  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12227  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12228  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12229  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12230  int scaling, /**< LP scaling (0: none, 1: normal, 2: aggressive) */
12231  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12232  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12233  )
12234 {
12235  SCIP_Bool resolve;
12236  char algo;
12237 
12238  assert(lp != NULL);
12239  assert(set != NULL);
12240  assert(lperror != NULL);
12241 
12242  /* flush changes to the LP solver */
12243  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12244  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12245 
12246  /* select LP algorithm to apply */
12247  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12248  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12249 
12250  switch( algo )
12251  {
12252  case 's':
12253  /* select simplex method */
12254  if( lp->dualfeasible || !lp->primalfeasible )
12255  {
12256  SCIPsetDebugMsg(set, "solving dual LP\n");
12257  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12258  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12259  }
12260  else
12261  {
12262  SCIPsetDebugMsg(set, "solving primal LP\n");
12263  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12264  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12265  }
12266  break;
12267 
12268  case 'p':
12269  SCIPsetDebugMsg(set, "solving primal LP\n");
12270  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12271  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12272  break;
12273 
12274  case 'd':
12275  SCIPsetDebugMsg(set, "solving dual LP\n");
12276  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12277  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12278  break;
12279 
12280  case 'b':
12281  SCIPsetDebugMsg(set, "solving barrier LP\n");
12282  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12283  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12284  break;
12285 
12286  case 'c':
12287  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12288  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12289  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12290  break;
12291 
12292  default:
12293  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12294  return SCIP_PARAMETERWRONGVAL;
12295  }
12296  assert(!(*lperror) || !lp->solved);
12297 
12298  return SCIP_OKAY;
12299 }
12300 
12301 #ifndef NDEBUG
12302 /** checks if the lazy bounds are valid */
12303 static
12305  SCIP_LP* lp, /**< LP data */
12306  SCIP_SET* set /**< global SCIP settings */
12307  )
12308 {
12309  SCIP_COL* col;
12310  int c;
12311 
12312  assert(lp->flushed);
12313 
12314  for( c = 0; c < lp->nlazycols; ++c )
12315  {
12316  col = lp->lazycols[c];
12317 
12318  /* in case lazy bounds are given, check that the primal solution satisfies them */
12319  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12320  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12321  }
12322 }
12323 #else
12324 #define checkLazyBounds(lp, set) /**/
12325 #endif
12326 
12327 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12328  * diving
12329  */
12330 static
12332  SCIP_LP* lp, /**< LP data */
12333  SCIP_SET* set /**< global SCIP settings */
12334  )
12335 {
12336  SCIP_COL* col;
12337  int c;
12338 
12339  assert(lp->nlazycols > 0);
12340 
12341  /* return, if we are in diving, and bounds were already applied
12342  * or if we are not in diving and bounds were not applied
12343  */
12344  if( lp->diving == lp->divinglazyapplied )
12345  return SCIP_OKAY;
12346 
12347  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12348  lp->diving, lp->divinglazyapplied);
12349 
12350  for( c = 0; c < lp->nlazycols; ++c )
12351  {
12352  col = lp->lazycols[c];
12353 
12354  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12355  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12356  {
12357  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12358  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12359  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12360 
12361  /* insert column in the chgcols list (if not already there) */
12362  SCIP_CALL( insertColChgcols(col, set, lp) );
12363 
12364  /* mark bound change in the column */
12365  col->lbchanged = TRUE;
12366  }
12367 
12368  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12369  if( !SCIPsetIsInfinity(set, col->lazyub) )
12370  {
12371  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12372  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12373  || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12374 
12375  /* insert column in the chgcols list (if not already there) */
12376  SCIP_CALL( insertColChgcols(col, set, lp) );
12377 
12378  /* mark bound change in the column */
12379  col->ubchanged = TRUE;
12380  }
12381  }
12382 
12383  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12384  * if not, we just removed them
12385  */
12386  lp->divinglazyapplied = lp->diving;
12387 
12388  return SCIP_OKAY;
12389 }
12390 
12391 /** returns the iteration limit for an LP resolving call */
12392 static
12394  SCIP_SET* set, /**< global SCIP settings */
12395  SCIP_STAT* stat, /**< dynamic problem statistics */
12396  int itlim /**< hard iteration limit */
12397  )
12398 {
12399  /* no limit set or average not yet reliable */
12400  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12401  return itlim;
12402  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12403  if( itlim == -1 )
12404  itlim = INT_MAX;
12405  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12406  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12407  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12408 }
12409 
12410 
12411 
12412 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12414  SCIP_LP* lp, /**< LP data */
12415  SCIP_SET* set, /**< global SCIP settings */
12416  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12417  BMS_BLKMEM* blkmem, /**< block memory buffers */
12418  SCIP_STAT* stat, /**< problem statistics */
12419  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12420  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12421  SCIP_PROB* prob, /**< problem data */
12422  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12423  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12424  * (limit is computed within the method w.r.t. the average LP iterations) */
12425  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12426  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12427  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12428  )
12429 {
12430  SCIP_RETCODE retcode;
12431  SCIP_Bool needprimalray;
12432  SCIP_Bool needdualray;
12433  int harditlim;
12434  int resolveitlim;
12435 
12436  assert(lp != NULL);
12437  assert(prob != NULL);
12438  assert(prob->nvars >= lp->ncols);
12439  assert(lperror != NULL);
12440 
12441  retcode = SCIP_OKAY;
12442  *lperror = FALSE;
12443 
12444  if( lp->flushed && lp->solved )
12445  {
12446  SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
12447  return SCIP_OKAY;
12448  }
12449 
12450  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12451  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12452 
12453  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12454  needprimalray = TRUE;
12455  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12456  || (set->conf_enable && set->conf_useinflp != 'o'));
12457 
12458  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12459  harditlim = (int) MIN(itlim, INT_MAX);
12460  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12461  assert(harditlim == -1 || (resolveitlim <= harditlim));
12462 
12463  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12464  * or removed from the LP (diving was ended)
12465  */
12466  if( lp->nlazycols > 0 )
12467  {
12468  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12469  * first resolve LP?
12470  */
12471  SCIP_CALL( updateLazyBounds(lp, set) );
12472  assert(lp->diving == lp->divinglazyapplied);
12473  }
12474 
12475  /* flush changes to the LP solver */
12476  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12477  assert(lp->flushed);
12478 
12479  /* 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
12480  * to run again anyway, since there seems to be some time left / the time limit was increased
12481  */
12482  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12483  {
12484  SCIP_Bool* primalfeaspointer;
12485  SCIP_Bool* dualfeaspointer;
12486  SCIP_Bool primalfeasible;
12487  SCIP_Bool dualfeasible;
12488  SCIP_Bool farkasvalid;
12489  SCIP_Bool rayfeasible;
12490  SCIP_Bool tightprimfeastol;
12491  SCIP_Bool tightdualfeastol;
12492  SCIP_Bool fromscratch;
12493  SCIP_Bool wasfromscratch;
12494  int scaling;
12495  SCIP_Longint oldnlps;
12496  int fastmip;
12497 
12498  /* set initial LP solver settings */
12499  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12500  tightprimfeastol = FALSE;
12501  tightdualfeastol = FALSE;
12502  fromscratch = FALSE;
12503  primalfeasible = FALSE;
12504  dualfeasible = FALSE;
12505  wasfromscratch = (stat->nlps == 0);
12506  scaling = set->lp_scaling;
12507 
12508  SOLVEAGAIN:
12509  /* solve the LP */
12510  oldnlps = stat->nlps;
12511  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12512  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12513  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12514  assert(!(*lperror) || !lp->solved);
12515 
12516  /* check for error */
12517  if( *lperror )
12518  {
12519  retcode = SCIP_OKAY;
12520  goto TERMINATE;
12521  }
12522 
12523  /* evaluate solution status */
12524  switch( SCIPlpGetSolstat(lp) )
12525  {
12527  /* get LP solution and possibly check the solution's feasibility again */
12528  if( set->lp_checkprimfeas )
12529  {
12530  primalfeaspointer = &primalfeasible;
12531  lp->primalchecked = TRUE;
12532  }
12533  else
12534  {
12535  /* believe in the primal feasibility of the LP solution */
12536  primalfeasible = TRUE;
12537  primalfeaspointer = NULL;
12538  lp->primalchecked = FALSE;
12539  }
12540  if( set->lp_checkdualfeas )
12541  {
12542  dualfeaspointer = &dualfeasible;
12543  lp->dualchecked = TRUE;
12544  }
12545  else
12546  {
12547  /* believe in the dual feasibility of the LP solution */
12548  dualfeasible = TRUE;
12549  dualfeaspointer = NULL;
12550  lp->dualchecked = FALSE;
12551  }
12552 
12553  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12554 
12555  /* in debug mode, check that lazy bounds (if present) are not violated */
12556  checkLazyBounds(lp, set);
12557 
12558  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12559  {
12560  /* update ages and remove obsolete columns and rows from LP */
12561  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12562  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12563  {
12564  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12565  }
12566 
12567  if( !lp->solved )
12568  {
12569  /* resolve LP after removing obsolete columns and rows */
12570  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12571  aging = FALSE; /* to prevent infinite loops */
12572  goto SOLVEAGAIN;
12573  }
12574  }
12575  if( !primalfeasible || !dualfeasible )
12576  {
12578 
12579  if( (fastmip > 0) && simplex )
12580  {
12581  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12582  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12583  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
12584  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12585  fastmip = 0;
12586  goto SOLVEAGAIN;
12587  }
12588  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12589  {
12590  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12591  * tolerance
12592  */
12593  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12594  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
12595  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12596  tightprimfeastol = tightprimfeastol || !primalfeasible;
12597  tightdualfeastol = tightdualfeastol || !dualfeasible;
12598  goto SOLVEAGAIN;
12599  }
12600  else if( !fromscratch && !wasfromscratch && simplex )
12601  {
12602  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12603  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12604  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
12605  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12606  fromscratch = TRUE;
12607  goto SOLVEAGAIN;
12608  }
12609  else
12610  {
12611  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12612  lp->solved = FALSE;
12614  *lperror = TRUE;
12615  }
12616  }
12617  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12618  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12619  lp->lpsolstat, lp->cutoffbound);
12620  break;
12621 
12623  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12624  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12625  {
12626  if( SCIPlpiHasDualRay(lp->lpi) )
12627  {
12628  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12629  }
12630  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12631  * with the primal simplex due to numerical problems) - treat this case like an LP error
12632  */
12633  else
12634  {
12635  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12636  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12637  lp->solved = FALSE;
12639  farkasvalid = FALSE;
12640  *lperror = TRUE;
12641  }
12642  }
12643  else
12644  farkasvalid = TRUE;
12645 
12646  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12647  if( !farkasvalid && !(*lperror) )
12648  {
12650 
12651  if( (fastmip > 0) && simplex )
12652  {
12653  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12654  * without FASTMIP
12655  */
12656  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12657  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12658  stat->nnodes, stat->nlps);
12659  fastmip = 0;
12660  goto SOLVEAGAIN;
12661  }
12662  else if( !tightdualfeastol )
12663  {
12664  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12665  * solve again with tighter feasibility tolerance
12666  */
12667  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12668  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12669  stat->nnodes, stat->nlps);
12670  tightdualfeastol = TRUE;
12671  goto SOLVEAGAIN;
12672  }
12673  else if( !fromscratch && simplex )
12674  {
12675  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12676  * from scratch
12677  */
12678  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12679  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12680  stat->nnodes, stat->nlps);
12681  fromscratch = TRUE;
12682  goto SOLVEAGAIN;
12683  }
12684  else
12685  {
12686  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12687  * helped forget about the LP at this node and mark it to be unsolved
12688  */
12689  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12690  lp->solved = FALSE;
12692  *lperror = TRUE;
12693  }
12694  }
12695 
12696  break;
12697 
12699  if( set->lp_checkprimfeas )
12700  {
12701  /* get unbounded LP solution and check the solution's feasibility again */
12702  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12703 
12704  lp->primalchecked = TRUE;
12705  }
12706  else
12707  {
12708  /* get unbounded LP solution believing in the feasibility of the LP solution */
12709  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12710 
12711  primalfeasible = TRUE;
12712  rayfeasible = TRUE;
12713  lp->primalchecked = FALSE;
12714  }
12715 
12716  /* in debug mode, check that lazy bounds (if present) are not violated */
12717  checkLazyBounds(lp, set);
12718 
12719  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12720  primalfeasible, rayfeasible);
12721 
12722  if( !primalfeasible || !rayfeasible )
12723  {
12725 
12726  if( (fastmip > 0) && simplex )
12727  {
12728  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12729  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12730  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
12731  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12732  fastmip = 0;
12733  goto SOLVEAGAIN;
12734  }
12735  else if( !tightprimfeastol )
12736  {
12737  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12738  * tolerance
12739  */
12740  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12741  "(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",
12742  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12743  tightprimfeastol = TRUE;
12744  goto SOLVEAGAIN;
12745  }
12746  else if( !fromscratch && simplex )
12747  {
12748  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12749  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12750  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
12751  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12752  fromscratch = TRUE;
12753  goto SOLVEAGAIN;
12754  }
12755  else if( scaling > 0 )
12756  {
12757  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without scaling */
12758  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12759  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving without scaling\n",
12760  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12761  scaling = 0;
12762  goto SOLVEAGAIN;
12763  }
12764  else
12765  {
12766  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12767  * forget about the LP at this node and mark it to be unsolved
12768  */
12769  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12770  lp->solved = FALSE;
12772  *lperror = TRUE;
12773  }
12774  }
12775 
12776  break;
12777 
12779  assert(!lpCutoffDisabled(set, prob));
12780  /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
12781  * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
12782  * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
12783  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12784  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12785  * FASTMIP and solve again. */
12786  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12787  {
12788  SCIP_LPI* lpi;
12789  SCIP_Real objval;
12790 
12791  lpi = SCIPlpGetLPI(lp);
12792 
12793  assert(lpi != NULL);
12794  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12795  * the assert by using !SCIPsetIsFeasNegative()
12796  */
12797  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12798 
12799  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12800 
12801  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12802  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12803  {
12804  SCIP_Real tmpcutoff;
12805  char tmppricingchar;
12806  SCIP_LPSOLSTAT solstat;
12807 
12808  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12809 
12810  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12811  fromscratch = FALSE;
12812 
12813  /* temporarily disable cutoffbound, which also disables the objective limit */
12814  tmpcutoff = lp->cutoffbound;
12815  lp->cutoffbound = SCIPlpiInfinity(lpi);
12816 
12817  /* set lp pricing strategy to steepest edge */
12818  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12819  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12820 
12821  /* resolve LP with an iteration limit of 1 */
12822  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12823  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12824 
12825  /* reinstall old cutoff bound and lp pricing strategy */
12826  lp->cutoffbound = tmpcutoff;
12827  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12828 
12829  /* get objective value */
12830  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12831 
12832  /* get solution status for the lp */
12833  solstat = SCIPlpGetSolstat(lp);
12834  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12835 
12836  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12837 
12838  /* the solution is still not exceeding the objective limit and the solving process
12839  * was stopped due to time or iteration limit, solve again with fastmip turned off
12840  */
12841  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12842  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12843  {
12845  if( !(*lperror) && (fastmip > 0) && simplex )
12846  {
12847  fastmip = 0;
12848  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12849  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, scaling, keepsol, lperror) );
12850 
12851  /* get objective value */
12852  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12853 
12854  /* get solution status for the lp */
12855  solstat = SCIPlpGetSolstat(lp);
12856 
12857  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12858  }
12859  }/*lint !e438*/
12860 
12861  /* check for lp errors */
12862  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12863  {
12864  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12865  lp->solved = FALSE;
12867 
12868  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12869  goto TERMINATE;
12870  }
12871 
12872  lp->solved = TRUE;
12873 
12874  /* optimal solution / objlimit / itlimit or timelimit, but objlimit exceeded */
12875  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12876  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12877  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12878  {
12879  /* get LP solution and possibly check the solution's feasibility again */
12880  if( set->lp_checkprimfeas )
12881  {
12882  primalfeaspointer = &primalfeasible;
12883  lp->primalchecked = TRUE;
12884  }
12885  else
12886  {
12887  /* believe in the primal feasibility of the LP solution */
12888  primalfeasible = TRUE;
12889  primalfeaspointer = NULL;
12890  lp->primalchecked = FALSE;
12891  }
12892  if( set->lp_checkdualfeas )
12893  {
12894  dualfeaspointer = &dualfeasible;
12895  lp->dualchecked = TRUE;
12896  }
12897  else
12898  {
12899  /* believe in the dual feasibility of the LP solution */
12900  dualfeasible = TRUE;
12901  dualfeaspointer = NULL;
12902  lp->dualchecked = FALSE;
12903  }
12904 
12905  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12906 
12907  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12908  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12909  {
12910  checkLazyBounds(lp, set);
12911  }
12912 
12913  /* if objective value is larger than the cutoff bound, set solution status to objective
12914  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12915  * this was already done in the lpSolve() method
12916  */
12917  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12918  {
12920  lp->lpobjval = SCIPsetInfinity(set);
12921  }
12922 
12923  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12924  * the cutoffbound; mark the LP to be unsolved
12925  */
12926  if( !primalfeasible || !dualfeasible
12927  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12928  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12929  {
12930  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12931  lp->solved = FALSE;
12933  *lperror = TRUE;
12934  }
12935 
12936  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12937  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12938  lp->lpsolstat, lp->cutoffbound);
12939  }
12940  /* infeasible solution */
12941  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12942  {
12943  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12944 
12945  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12946  {
12947  if( SCIPlpiHasDualRay(lp->lpi) )
12948  {
12949  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12950  }
12951  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12952  * with the primal simplex due to numerical problems) - treat this case like an LP error
12953  */
12954  else
12955  {
12956  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12957  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12958  lp->solved = FALSE;
12960  farkasvalid = FALSE;
12961  *lperror = TRUE;
12962  }
12963  }
12964  else
12965  farkasvalid = TRUE;
12966 
12967  if( !farkasvalid )
12968  {
12970 
12971  if( !tightprimfeastol )
12972  {
12973  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12974  * solve again with tighter feasibility tolerance
12975  */
12976  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12977  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12978  stat->nnodes, stat->nlps);
12979  tightprimfeastol = TRUE;
12980  goto SOLVEAGAIN;
12981  }
12982  else if( simplex )
12983  {
12984  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12985  * from scratch
12986  */
12987  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12988  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12989  stat->nnodes, stat->nlps);
12990  fromscratch = TRUE;
12991  goto SOLVEAGAIN;
12992  }
12993  else
12994  {
12995  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12996  * helped forget about the LP at this node and mark it to be unsolved
12997  */
12998  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12999  lp->solved = FALSE;
13001  *lperror = TRUE;
13002  }
13003  }
13004  }
13005  /* unbounded solution */
13006  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
13007  {
13008  if( set->lp_checkprimfeas )
13009  {
13010  /* get unbounded LP solution and check the solution's feasibility again */
13011  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
13012 
13013  lp->primalchecked = TRUE;
13014  }
13015  else
13016  {
13017  /* get unbounded LP solution believing in its feasibility */
13018  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
13019 
13020  primalfeasible = TRUE;
13021  rayfeasible = TRUE;
13022  lp->primalchecked = FALSE;
13023  }
13024 
13025  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
13026 
13027  /* in debug mode, check that lazy bounds (if present) are not violated */
13028  checkLazyBounds(lp, set);
13029 
13030  if( !primalfeasible || !rayfeasible )
13031  {
13032  /* unbounded solution is infeasible (this can happen due to numerical problems):
13033  * forget about the LP at this node and mark it to be unsolved
13034  *
13035  * @todo: like in the default LP solving evaluation, solve without fastmip,
13036  * with tighter feasibility tolerance and from scratch
13037  */
13038  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
13039  lp->solved = FALSE;
13041  *lperror = TRUE;
13042  }
13043  }
13044 
13045  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
13046  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
13048  }
13049  else
13050  {
13051  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
13052  }
13053  }
13054  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
13055  break;
13056 
13058  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13059  break;
13060 
13062  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13063 
13064  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13065  stat->nclockskipsleft = 0;
13066  if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
13067  {
13068  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13069  "you might consider switching the clock type of SCIP\n");
13070  stat->status = SCIP_STATUS_TIMELIMIT;
13071  }
13072  break;
13073 
13074  case SCIP_LPSOLSTAT_ERROR:
13076  SCIPerrorMessage("error in LP solver\n");
13077  retcode = SCIP_LPERROR;
13078  goto TERMINATE;
13079 
13080  default:
13081  SCIPerrorMessage("unknown LP solution status\n");
13082  retcode = SCIP_ERROR;
13083  goto TERMINATE;
13084  }
13085  }
13086  assert(!(*lperror) || !lp->solved);
13087 
13088  TERMINATE:
13089  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13090  * may happen that we continue to solve from scratch during strong branching */
13091  if( lp->lpifromscratch )
13092  {
13093  SCIP_Bool success;
13094  (void) lpSetFromscratch(lp, FALSE, &success);
13095  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13096  SCIP_UNUSED(success);
13097  }
13098 
13099  return retcode;
13100 }
13101 
13102 /** gets solution status of current LP */
13104  SCIP_LP* lp /**< current LP data */
13105  )
13106 {
13107  assert(lp != NULL);
13108  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
13109 
13110  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13111 }
13112 
13113 /** gets objective value of current LP
13114  *
13115  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13116  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13117  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13118  */
13120  SCIP_LP* lp, /**< current LP data */
13121  SCIP_SET* set, /**< global SCIP settings */
13122  SCIP_PROB* prob /**< problem data */
13123  )
13124 {
13125  assert(lp != NULL);
13126  assert(lp->solved);
13127  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13128  assert(set != NULL);
13129 
13130  if( !lp->flushed )
13131  return SCIP_INVALID;
13132  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
13133  return lp->lpobjval;
13134  else if( lp->looseobjvalinf > 0 )
13135  return -SCIPsetInfinity(set);
13136  else
13137  {
13138  /* recalculate the loose objective value, if needed */
13139  if( !lp->looseobjvalid )
13140  recomputeLooseObjectiveValue(lp, set, prob);
13141 
13142  return lp->lpobjval + lp->looseobjval;
13143  }
13144 }
13145 
13146 /** gets part of objective value of current LP that results from COLUMN variables only */
13148  SCIP_LP* lp /**< current LP data */
13149  )
13150 {
13151  assert(lp != NULL);
13152  assert(lp->solved);
13153 
13154  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13155 }
13156 
13157 /** gets part of objective value of current LP that results from LOOSE variables only */
13159  SCIP_LP* lp, /**< current LP data */
13160  SCIP_SET* set, /**< global SCIP settings */
13161  SCIP_PROB* prob /**< problem data */
13162  )
13163 {
13164  assert(lp != NULL);
13165  assert(lp->solved);
13166  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13167  assert(set != NULL);
13168 
13169  if( !lp->flushed )
13170  return SCIP_INVALID;
13171  else if( lp->looseobjvalinf > 0 )
13172  return -SCIPsetInfinity(set);
13173  else
13174  return getFiniteLooseObjval(lp, set, prob);
13175 }
13176 
13177 /** remembers the current LP objective value as root solution value */
13179  SCIP_LP* lp, /**< current LP data */
13180  SCIP_SET* set, /**< global SCIP settings */
13181  SCIP_PROB* prob /**< problem data */
13182  )
13183 {
13184  assert(lp != NULL);
13185 
13187  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13188 }
13189 
13190 /** invalidates the root LP solution value */
13192  SCIP_LP* lp /**< current LP data */
13193  )
13194 {
13195  assert(lp != NULL);
13196 
13197  lp->rootlpobjval = SCIP_INVALID;
13199 }
13200 
13201 /** recomputes local and global pseudo objective values */
13203  SCIP_LP* lp, /**< current LP data */
13204  SCIP_SET* set, /**< global SCIP settings */
13205  SCIP_PROB* prob /**< problem data */
13206  )
13207 {
13208  SCIP_VAR** vars;
13209  int nvars;
13210  int v;
13211 
13212  assert(lp != NULL);
13213  assert(set != NULL);
13214  assert(prob != NULL);
13215 
13216  vars = prob->vars;
13217  nvars = prob->nvars;
13218 
13219  lp->glbpseudoobjvalinf = 0;
13220  lp->glbpseudoobjval = 0.0;
13221 
13222  lp->pseudoobjvalinf = 0;
13223  lp->pseudoobjval = 0.0;
13224 
13225  for( v = 0; v < nvars; ++v )
13226  {
13227  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13228 
13229  if( SCIPsetIsPositive(set, obj) )
13230  {
13231  /* update the global pseudo objective value */
13232  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13233  ++(lp->glbpseudoobjvalinf);
13234  else
13235  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13236 
13237  /* update the local pseudo objective value */
13238  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13239  ++(lp->pseudoobjvalinf);
13240  else
13241  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13242  }
13243 
13244  if( SCIPsetIsNegative(set, obj) )
13245  {
13246  /* update the global pseudo objective value */
13247  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13248  ++(lp->glbpseudoobjvalinf);
13249  else
13250  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13251 
13252  /* update the local pseudo objective value */
13253  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13254  ++(lp->pseudoobjvalinf);
13255  else
13256  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13257  }
13258  }
13259 
13260  /* the recomputed values are reliable */
13262  lp->glbpseudoobjvalid = TRUE;
13263  lp->relpseudoobjval = lp->pseudoobjval;
13264  lp->pseudoobjvalid = TRUE;
13265 }
13266 
13267 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13268  * global bound
13269  */
13271  SCIP_LP* lp, /**< current LP data */
13272  SCIP_SET* set, /**< global SCIP settings */
13273  SCIP_PROB* prob /**< problem data */
13274  )
13275 {
13276  assert(lp != NULL);
13277  assert(lp->glbpseudoobjvalinf >= 0);
13278  assert(set != NULL);
13279 
13280  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13281  return -SCIPsetInfinity(set);
13282  else
13283  {
13284  /* recalculate the global pseudo solution value, if needed */
13285  if( !lp->glbpseudoobjvalid )
13286  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13287 
13288  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13289  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13290  return -SCIPsetInfinity(set);
13291 
13292  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13293  return SCIPsetInfinity(set);
13294 
13295  return lp->glbpseudoobjval;
13296  }
13297 }
13298 
13299 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13300  * objective function) local bound
13301  */
13303  SCIP_LP* lp, /**< current LP data */
13304  SCIP_SET* set, /**< global SCIP settings */
13305  SCIP_PROB* prob /**< problem data */
13306  )
13307 {
13308  assert(lp != NULL);
13309  assert(lp->pseudoobjvalinf >= 0);
13310  assert(set != NULL);
13311 
13312  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13313  return -SCIPsetInfinity(set);
13314  else
13315  {
13316  /* recalculate the pseudo solution value, if needed */
13317  if( !lp->pseudoobjvalid )
13318  recomputePseudoObjectiveValue(lp, set, prob);
13319 
13320  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13321  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13322  return -SCIPsetInfinity(set);
13323 
13324  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13325  return SCIPsetInfinity(set);
13326 
13327  return lp->pseudoobjval;
13328  }
13329 }
13330 
13331 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13333  SCIP_LP* lp, /**< current LP data */
13334  SCIP_SET* set, /**< global SCIP settings */
13335  SCIP_PROB* prob, /**< problem data */
13336  SCIP_VAR* var, /**< problem variable */
13337  SCIP_Real oldbound, /**< old value for bound */
13338  SCIP_Real newbound, /**< new value for bound */
13339  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13340  )
13341 {
13342  SCIP_Real pseudoobjval;
13343  int pseudoobjvalinf;
13344  SCIP_Real obj;
13345 
13346  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13347  pseudoobjvalinf = lp->pseudoobjvalinf;
13348  obj = SCIPvarGetObj(var);
13349  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13350  {
13351  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13352  pseudoobjvalinf--;
13353  else
13354  pseudoobjval -= oldbound * obj;
13355  assert(pseudoobjvalinf >= 0);
13356  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13357  pseudoobjvalinf++;
13358  else
13359  pseudoobjval += newbound * obj;
13360  }
13361  assert(pseudoobjvalinf >= 0);
13362 
13363  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13364  return -SCIPsetInfinity(set);
13365  else
13366  return pseudoobjval;
13367 }
13368 
13369 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13370  * perform calculations with interval arithmetic to get an exact lower bound
13371  */
13373  SCIP_LP* lp, /**< current LP data */
13374  SCIP_SET* set, /**< global SCIP settings */
13375  SCIP_VAR* var, /**< problem variable */
13376  SCIP_Real oldbound, /**< old value for bound */
13377  SCIP_Real newbound, /**< new value for bound */
13378  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13379  )
13380 {
13381  SCIP_Real pseudoobjval;
13382  int pseudoobjvalinf;
13383  SCIP_Real obj;
13384 
13385  assert(lp->pseudoobjvalid);
13386 
13387  pseudoobjval = lp->pseudoobjval;
13388  pseudoobjvalinf = lp->pseudoobjvalinf;
13389  obj = SCIPvarGetObj(var);
13390  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13391  {
13392  SCIP_INTERVAL objint;
13393  SCIP_INTERVAL bd;
13394  SCIP_INTERVAL prod;
13395  SCIP_INTERVAL psval;
13396 
13397  SCIPintervalSet(&psval, pseudoobjval);
13398  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13399 
13400  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13401  pseudoobjvalinf--;
13402  else
13403  {
13404  SCIPintervalSet(&bd, oldbound);
13405  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13406  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13407  }
13408  assert(pseudoobjvalinf >= 0);
13409  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13410  pseudoobjvalinf++;
13411  else
13412  {
13413  SCIPintervalSet(&bd, newbound);
13414  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13415  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13416  }
13417 
13418  pseudoobjval = SCIPintervalGetInf(psval);
13419  }
13420  assert(pseudoobjvalinf >= 0);
13421 
13422  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13423  return -SCIPsetInfinity(set);
13424  else
13425  return pseudoobjval;
13426 }
13427 
13428 /** compute the objective delta due the new objective coefficient */
13429 static
13431  SCIP_SET* set, /**< global SCIP settings */
13432  SCIP_Real oldobj, /**< old objective value of variable */
13433  SCIP_Real newobj, /**< new objective value of variable */
13434  SCIP_Real lb, /**< lower bound of variable */
13435  SCIP_Real ub, /**< upper bound of variable */
13436  SCIP_Real* deltaval, /**< pointer to store the delta value */
13437  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13438  )
13439 {
13440  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13441  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13442  assert(!SCIPsetIsInfinity(set, lb));
13443  assert(!SCIPsetIsInfinity(set, -ub));
13444  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13445 
13446  (*deltaval) = 0.0;
13447  (*deltainf) = 0;
13448 
13449  if( SCIPsetIsPositive(set, oldobj) )
13450  {
13451  /* sign of objective did not change */
13452  if( SCIPsetIsPositive(set, newobj) )
13453  {
13454  /* if the bound is finite, calculate the deltaval */
13455  if( !SCIPsetIsInfinity(set, -lb) )
13456  (*deltaval) = lb * (newobj - oldobj);
13457  }
13458  /* sign of objective did change, so the best bound does change */
13459  else if( SCIPsetIsNegative(set, newobj) )
13460  {
13461  if( SCIPsetIsInfinity(set, -lb) )
13462  {
13463  /* old best bound was infinite while new one is not */
13464  if( !SCIPsetIsInfinity(set, ub) )
13465  {
13466  (*deltainf) = -1;
13467  (*deltaval) = ub * newobj;
13468  }
13469  }
13470  else
13471  {
13472  /* new best bound is infinite while old one was not */
13473  if( SCIPsetIsInfinity(set, ub) )
13474  {
13475  (*deltainf) = 1;
13476  (*deltaval) = -lb * oldobj;
13477  }
13478  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13479  else
13480  {
13481  (*deltaval) = (ub * newobj) - (lb * oldobj);
13482  }
13483  }
13484  }
13485  /* new objective is 0.0 */
13486  else
13487  {
13488  if( SCIPsetIsInfinity(set, -lb) )
13489  (*deltainf) = -1;
13490  else
13491  (*deltaval) = -lb * oldobj;
13492  }
13493  }
13494  else if( SCIPsetIsNegative(set, oldobj) )
13495  {
13496  /* sign of objective did not change */
13497  if( SCIPsetIsNegative(set, newobj) )
13498  {
13499  /* if the bound is finite, calculate the deltaval */
13500  if( !SCIPsetIsInfinity(set, ub) )
13501  (*deltaval) = ub * (newobj - oldobj);
13502  }
13503  /* sign of objective did change, so the best bound does change */
13504  else if( SCIPsetIsPositive(set, newobj) )
13505  {
13506  if( SCIPsetIsInfinity(set, ub) )
13507  {
13508  /* old best bound was infinite while new one is not */
13509  if( !SCIPsetIsInfinity(set, -lb) )
13510  {
13511  (*deltainf) = -1;
13512  (*deltaval) = lb * newobj;
13513  }
13514  }
13515  else
13516  {
13517  /* new best bound is infinite while old one was not */
13518  if( SCIPsetIsInfinity(set, -lb) )
13519  {
13520  (*deltainf) = 1;
13521  (*deltaval) = -ub * oldobj;
13522  }
13523  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13524  else
13525  {
13526  (*deltaval) = (lb * newobj) - (ub * oldobj);
13527  }
13528  }
13529  }
13530  /* new objective is 0.0 */
13531  else
13532  {
13533  if( SCIPsetIsInfinity(set, ub) )
13534  (*deltainf) = -1;
13535  else
13536  (*deltaval) = -ub * oldobj;
13537  }
13538  }
13539  /* old objective was 0.0 */
13540  else
13541  {
13542  if( SCIPsetIsNegative(set, newobj) )
13543  {
13544  if( SCIPsetIsInfinity(set, ub) )
13545  (*deltainf) = 1;
13546  else
13547  (*deltaval) = ub * newobj;
13548  }
13549  else if( SCIPsetIsPositive(set, newobj) )
13550  {
13551  if( SCIPsetIsInfinity(set, -lb) )
13552  (*deltainf) = 1;
13553  else
13554  (*deltaval) = lb * newobj;
13555  }
13556  }
13557 }
13558 
13559 /** compute the objective delta due the new lower bound */
13560 static
13562  SCIP_SET* set, /**< global SCIP settings */
13563  SCIP_Real obj, /**< objective value of variable */
13564  SCIP_Real oldlb, /**< old lower bound of variable */
13565  SCIP_Real newlb, /**< new lower bound of variable */
13566  SCIP_Real* deltaval, /**< pointer to store the delta value */
13567  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13568  )
13569 {
13570  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13571  assert(!SCIPsetIsInfinity(set, oldlb));
13572  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13573  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13574 
13575  if( SCIPsetIsInfinity(set, -oldlb) )
13576  {
13577  if( !SCIPsetIsInfinity(set, newlb) )
13578  {
13579  (*deltainf) = -1;
13580  (*deltaval) = newlb * obj;
13581  }
13582  else
13583  {
13584  (*deltainf) = 0;
13585  (*deltaval) = 0.0;
13586  }
13587  }
13588  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13589  {
13590  (*deltainf) = 1;
13591  (*deltaval) = -oldlb * obj;
13592  }
13593  else
13594  {
13595  (*deltainf) = 0;
13596  (*deltaval) = obj * (newlb - oldlb);
13597  }
13598 }
13599 
13600 /** compute the objective delta due the new upper bound */
13601 static
13603  SCIP_SET* set, /**< global SCIP settings */
13604  SCIP_Real obj, /**< objective value of variable */
13605  SCIP_Real oldub, /**< old upper bound of variable */
13606  SCIP_Real newub, /**< new upper bound of variable */
13607  SCIP_Real* deltaval, /**< pointer to store the delta value */
13608  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13609  )
13610 {
13611  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13612  assert(!SCIPsetIsInfinity(set, -oldub));
13613  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13614  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13615 
13616  if( SCIPsetIsInfinity(set, oldub) )
13617  {
13618  if( !SCIPsetIsInfinity(set, -newub) )
13619  {
13620  (*deltainf) = -1;
13621  (*deltaval) = newub * obj;
13622  }
13623  else
13624  {
13625  (*deltainf) = 0;
13626  (*deltaval) = 0.0;
13627  }
13628  }
13629  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13630  {
13631  (*deltainf) = 1;
13632  (*deltaval) = -oldub * obj;
13633  }
13634  else
13635  {
13636  (*deltainf) = 0;
13637  (*deltaval) = obj * (newub - oldub);
13638  }
13639 }
13640 
13641 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13642 static
13644  SCIP_LP* lp, /**< current LP data */
13645  SCIP_SET* set, /**< global SCIP settings */
13646  SCIP_VAR* var, /**< problem variable that changed */
13647  SCIP_Real deltaval, /**< delta value in the objective function */
13648  int deltainf, /**< delta value for the number of variables with infinite best bound */
13649  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13650  SCIP_Bool loose, /**< should the loose objective value be updated? */
13651  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13652  )
13653 {
13654  assert(lp != NULL);
13655  assert(lp->looseobjvalinf >= 0);
13656  assert(lp->pseudoobjvalinf >= 0);
13657  assert(lp->glbpseudoobjvalinf >= 0);
13658 
13659  /* update the pseudo objective value */
13660  if( local )
13661  {
13662  lp->pseudoobjvalinf += deltainf;
13663  if( lp->pseudoobjvalid )
13664  {
13665  lp->pseudoobjval += deltaval;
13666 
13667  /* if the absolute value was increased, this is regarded as reliable,
13668  * otherwise, we check whether we can still trust the updated value
13669  */
13670  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13671  lp->relpseudoobjval = lp->pseudoobjval;
13672  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13673  lp->pseudoobjvalid = FALSE;
13674  }
13675 
13676  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13678  loose = TRUE;
13679  }
13680  /* update the loose objective value */
13681  if( loose )
13682  {
13683  lp->looseobjvalinf += deltainf;
13684 
13685  if( deltaval != 0.0 && lp->looseobjvalid )
13686  {
13687  lp->looseobjval += deltaval;
13688 
13689  /* if the absolute value was increased, this is regarded as reliable,
13690  * otherwise, we check whether we can still trust the updated value
13691  */
13692  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13693  lp->rellooseobjval = lp->looseobjval;
13694  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13695  lp->looseobjvalid = FALSE;
13696  }
13697  }
13698  /* update the root pseudo objective values */
13699  if( global )
13700  {
13701  lp->glbpseudoobjvalinf += deltainf;
13702  if( lp->glbpseudoobjvalid )
13703  {
13704  lp->glbpseudoobjval += deltaval;
13705 
13706  /* if the absolute value was increased, this is regarded as reliable,
13707  * otherwise, we check whether we can still trust the updated value
13708  */
13712  lp->glbpseudoobjvalid = FALSE;
13713  }
13714  }
13715 
13716  assert(lp->looseobjvalinf >= 0);
13717  assert(lp->pseudoobjvalinf >= 0);
13718  assert(lp->glbpseudoobjvalinf >= 0);
13719 }
13720 
13721 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13722  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13723  */
13724 static
13726  SCIP_LP* lp, /**< current LP data */
13727  SCIP_SET* set, /**< global SCIP settings */
13728  SCIP_VAR* var, /**< problem variable that changed */
13729  SCIP_Real oldobj, /**< old objective value of variable */
13730  SCIP_Real oldlb, /**< old objective value of variable */
13731  SCIP_Real oldub, /**< old objective value of variable */
13732  SCIP_Real newobj, /**< new objective value of variable */
13733  SCIP_Real newlb, /**< new objective value of variable */
13734  SCIP_Real newub /**< new objective value of variable */
13735  )
13736 {
13737  SCIP_INTERVAL deltaval;
13738  SCIP_INTERVAL bd;
13739  SCIP_INTERVAL obj;
13740  SCIP_INTERVAL prod;
13741  SCIP_INTERVAL psval;
13742  int deltainf;
13743 
13744  assert(lp != NULL);
13745  assert(lp->pseudoobjvalinf >= 0);
13746  assert(lp->looseobjvalinf >= 0);
13747  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13748  assert(!SCIPsetIsInfinity(set, oldlb));
13749  assert(!SCIPsetIsInfinity(set, -oldub));
13750  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13751  assert(!SCIPsetIsInfinity(set, newlb));
13752  assert(!SCIPsetIsInfinity(set, -newub));
13753  assert(var != NULL);
13754 
13756  {
13757  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13758  return SCIP_INVALIDDATA;
13759  }
13760 
13761  assert(SCIPvarGetProbindex(var) >= 0);
13762 
13763  SCIPintervalSet(&deltaval, 0.0);
13764  deltainf = 0;
13765 
13766  /* subtract old pseudo objective value */
13767  if( oldobj > 0.0 )
13768  {
13769  if( SCIPsetIsInfinity(set, -oldlb) )
13770  deltainf--;
13771  else
13772  {
13773  SCIPintervalSet(&bd, oldlb);
13774  SCIPintervalSet(&obj, oldobj);
13775  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13776  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13777  }
13778  }
13779  else if( oldobj < 0.0 )
13780  {
13781  if( SCIPsetIsInfinity(set, oldub) )
13782  deltainf--;
13783  else
13784  {
13785  SCIPintervalSet(&bd, oldub);
13786  SCIPintervalSet(&obj, oldobj);
13787  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13788  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13789  }
13790  }
13791 
13792  /* add new pseudo objective value */
13793  if( newobj > 0.0 )
13794  {
13795  if( SCIPsetIsInfinity(set, -newlb) )
13796  deltainf++;
13797  else
13798  {
13799  SCIPintervalSet(&bd, newlb);
13800  SCIPintervalSet(&obj, newobj);
13801  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13802  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13803  }
13804  }
13805  else if( newobj < 0.0 )
13806  {
13807  if( SCIPsetIsInfinity(set, newub) )
13808  deltainf++;
13809  else
13810  {
13811  SCIPintervalSet(&bd, newub);
13812  SCIPintervalSet(&obj, newobj);
13813  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13814  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13815  }
13816  }
13817 
13818  /* update the pseudo and loose objective values */
13819  SCIPintervalSet(&psval, lp->pseudoobjval);
13820  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13821  lp->pseudoobjval = SCIPintervalGetInf(psval);
13822  lp->pseudoobjvalinf += deltainf;
13824  {
13825  SCIPintervalSet(&psval, lp->looseobjval);
13826  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13827  lp->looseobjval = SCIPintervalGetInf(psval);
13828  lp->looseobjvalinf += deltainf;
13829  }
13830 
13831  assert(lp->pseudoobjvalinf >= 0);
13832  assert(lp->looseobjvalinf >= 0);
13833 
13834  return SCIP_OKAY;
13835 }
13836 
13837 /** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
13839  SCIP_LP* lp, /**< current LP data */
13840  SCIP_SET* set, /**< global SCIP settings */
13841  SCIP_VAR* var, /**< problem variable that changed */
13842  SCIP_Real oldobj, /**< old objective coefficient of variable */
13843  SCIP_Real newobj /**< new objective coefficient of variable */
13844  )
13845 {
13846  assert(set != NULL);
13847  assert(var != NULL);
13848 
13849  if( set->misc_exactsolve )
13850  {
13851  if( oldobj != newobj ) /*lint !e777*/
13852  {
13853  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13854  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13855  }
13856  }
13857  else
13858  {
13859  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13860  {
13861  SCIP_Real deltaval;
13862  int deltainf;
13863 
13865  assert(SCIPvarGetProbindex(var) >= 0);
13866 
13867  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13868  * domain of the variable are the same
13869  */
13870  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13871  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13872 
13873  /* compute the pseudo objective delta due the new objective coefficient */
13874  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13875 
13876  /* update the local pseudo objective value */
13877  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13878 
13879  /* compute the pseudo objective delta due the new objective coefficient */
13880  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13881 
13882  /* update the global pseudo objective value */
13883  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13884  }
13885  }
13886 
13887  return SCIP_OKAY;
13888 }
13889 
13890 
13891 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13893  SCIP_LP* lp, /**< current LP data */
13894  SCIP_SET* set, /**< global SCIP settings */
13895  SCIP_VAR* var, /**< problem variable that changed */
13896  SCIP_Real oldlb, /**< old lower bound of variable */
13897  SCIP_Real newlb /**< new lower bound of variable */
13898  )
13899 {
13900  assert(set != NULL);
13901  assert(var != NULL);
13902 
13903  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13904  {
13905  SCIP_Real deltaval;
13906  int deltainf;
13907 
13908  /* compute the pseudo objective delta due the new lower bound */
13909  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13910 
13911  /* update the root pseudo objective values */
13912  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13913  }
13914 
13915  return SCIP_OKAY;
13916 }
13917 
13918 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13920  SCIP_LP* lp, /**< current LP data */
13921  SCIP_SET* set, /**< global SCIP settings */
13922  SCIP_VAR* var, /**< problem variable that changed */
13923  SCIP_Real oldlb, /**< old lower bound of variable */
13924  SCIP_Real newlb /**< new lower bound of variable */
13925  )
13926 {
13927  assert(set != NULL);
13928  assert(var != NULL);
13929 
13930  if( set->misc_exactsolve )
13931  {
13932  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13933  {
13934  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13935  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13936  }
13937  }
13938  else
13939  {
13940  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13941  {
13942  SCIP_Real deltaval;
13943  int deltainf;
13944 
13946  assert(SCIPvarGetProbindex(var) >= 0);
13947 
13948  /* compute the pseudo objective delta due the new lower bound */
13949  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13950 
13951  /* update the pseudo and loose objective values */
13952  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13953  }
13954  }
13955 
13956  return SCIP_OKAY;
13957 }
13958 
13959 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13961  SCIP_LP* lp, /**< current LP data */
13962  SCIP_SET* set, /**< global SCIP settings */
13963  SCIP_VAR* var, /**< problem variable that changed */
13964  SCIP_Real oldub, /**< old upper bound of variable */
13965  SCIP_Real newub /**< new upper bound of variable */
13966  )
13967 {
13968  assert(set != NULL);
13969  assert(var != NULL);
13970 
13971  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13972  {
13973  SCIP_Real deltaval;
13974  int deltainf;
13975 
13976  /* compute the pseudo objective delta due the new upper bound */
13977  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13978 
13979  /* update the root pseudo objective values */
13980  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13981  }
13982 
13983  return SCIP_OKAY;
13984 }
13985 
13986 /** updates current pseudo objective value for a change in a variable's upper bound */
13988  SCIP_LP* lp, /**< current LP data */
13989  SCIP_SET* set, /**< global SCIP settings */
13990  SCIP_VAR* var, /**< problem variable that changed */
13991  SCIP_Real oldub, /**< old upper bound of variable */
13992  SCIP_Real newub /**< new upper bound of variable */
13993  )
13994 {
13995  assert(set != NULL);
13996  assert(var != NULL);
13997 
13998  if( set->misc_exactsolve )
13999  {
14000  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
14001  {
14002  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
14003  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
14004  }
14005  }
14006  else
14007  {
14008  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
14009  {
14010  SCIP_Real deltaval;
14011  int deltainf;
14012 
14014  assert(SCIPvarGetProbindex(var) >= 0);
14015 
14016  /* compute the pseudo objective delta due the new upper bound */
14017  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
14018 
14019  /* update the pseudo and loose objective values */
14020  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14021  }
14022  }
14023 
14024  return SCIP_OKAY;
14025 }
14026 
14027 /** informs LP, that given variable was added to the problem */
14029  SCIP_LP* lp, /**< current LP data */
14030  SCIP_SET* set, /**< global SCIP settings */
14031  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
14032  )
14033 {
14034  assert(lp != NULL);
14036  assert(SCIPvarGetProbindex(var) >= 0);
14037 
14038  /* add the variable to the loose objective value sum */
14039  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
14040 
14041  /* update the loose variables counter */
14043  lp->nloosevars++;
14044 
14045  return SCIP_OKAY;
14046 }
14047 
14048 /** informs LP, that given variable is to be deleted from the problem */
14050  SCIP_LP* lp, /**< current LP data */
14051  SCIP_SET* set, /**< global SCIP settings */
14052  SCIP_VAR* var /**< variable that will be deleted from the problem */
14053  )
14054 {
14055  assert(lp != NULL);
14057  assert(SCIPvarGetProbindex(var) >= 0);
14058 
14059  /* subtract the variable from the loose objective value sum */
14060  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
14061 
14062  /* update the loose variables counter */
14064  {
14065  SCIPlpDecNLoosevars(lp);
14066  }
14067 
14068  return SCIP_OKAY;
14069 }
14070 
14071 /** informs LP, that given formerly loose problem variable is now a column variable */
14072 static
14074  SCIP_LP* lp, /**< current LP data */
14075  SCIP_SET* set, /**< global SCIP settings */
14076  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14077  )
14078 {
14079  SCIP_Real obj;
14080  SCIP_Real lb;
14081  SCIP_Real ub;
14082 
14083  assert(lp != NULL);
14084  assert(lp->nloosevars > 0);
14085  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14086  assert(SCIPvarGetProbindex(var) >= 0);
14087  assert(lp->looseobjvalinf >= 0);
14088 
14089  obj = SCIPvarGetObj(var);
14090 
14091  /* update loose objective value */
14092  if( SCIPsetIsPositive(set, obj) )
14093  {
14094  lb = SCIPvarGetLbLocal(var);
14095  if( SCIPsetIsInfinity(set, -lb) )
14096  lp->looseobjvalinf--;
14097  else
14098  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14099  }
14100  else if( SCIPsetIsNegative(set, obj) )
14101  {
14102  ub = SCIPvarGetUbLocal(var);
14103  if( SCIPsetIsInfinity(set, ub) )
14104  lp->looseobjvalinf--;
14105  else
14106  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14107  }
14108 
14109  SCIPlpDecNLoosevars(lp);
14110 
14111  assert(lp->looseobjvalinf >= 0);
14112 
14113  return SCIP_OKAY;
14114 }
14115 
14116 /** informs LP, that given formerly loose problem variable is now a column variable
14117  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14118  */
14119 static
14121  SCIP_LP* lp, /**< current LP data */
14122  SCIP_SET* set, /**< global SCIP settings */
14123  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14124  )
14125 {
14126  SCIP_INTERVAL bd;
14127  SCIP_INTERVAL ob;
14128  SCIP_INTERVAL prod;
14129  SCIP_INTERVAL loose;
14130  SCIP_Real obj;
14131  SCIP_Real lb;
14132  SCIP_Real ub;
14133 
14134  assert(lp != NULL);
14135  assert(lp->nloosevars > 0);
14136  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14137  assert(SCIPvarGetProbindex(var) >= 0);
14138 
14139  obj = SCIPvarGetObj(var);
14140 
14141  SCIPintervalSet(&loose, lp->looseobjval);
14142 
14143  /* update loose objective value corresponding to the deletion of variable */
14144  if( obj > 0.0 )
14145  {
14146  lb = SCIPvarGetLbLocal(var);
14147  if( SCIPsetIsInfinity(set, -lb) )
14148  lp->looseobjvalinf--;
14149  else
14150  {
14151  SCIPintervalSet(&bd, lb);
14152  SCIPintervalSet(&ob, obj);
14153  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14154  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14155  }
14156  }
14157  else if( SCIPsetIsNegative(set, obj) )
14158  {
14159  ub = SCIPvarGetUbLocal(var);
14160  if( SCIPsetIsInfinity(set, ub) )
14161  lp->looseobjvalinf--;
14162  else
14163  {
14164  SCIPintervalSet(&bd, ub);
14165  SCIPintervalSet(&ob, obj);
14166  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14167  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14168  }
14169  }
14170  lp->nloosevars--;
14171 
14172  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14173  if( lp->nloosevars == 0 )
14174  {
14175  assert(lp->looseobjvalinf == 0);
14176  lp->looseobjval = 0.0;
14177  }
14178  else
14179  lp->looseobjval = SCIPintervalGetInf(loose);
14180 
14181  return SCIP_OKAY;
14182 }
14183 
14184 /** informs LP, that given formerly loose problem variable is now a column variable */
14186  SCIP_LP* lp, /**< current LP data */
14187  SCIP_SET* set, /**< global SCIP settings */
14188  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14189  )
14190 {
14191  assert(set != NULL);
14192 
14193  if( set->misc_exactsolve )
14194  {
14195  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
14196  }
14197  else
14198  {
14199  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
14200  }
14201 
14202  return SCIP_OKAY;
14203 }
14204 
14205 /** informs LP, that given formerly column problem variable is now again a loose variable */
14206 static
14208  SCIP_LP* lp, /**< current LP data */
14209  SCIP_SET* set, /**< global SCIP settings */
14210  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14211  )
14212 {
14213  SCIP_Real obj;
14214  SCIP_Real lb;
14215  SCIP_Real ub;
14216 
14217  assert(lp != NULL);
14218  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14219  assert(SCIPvarGetProbindex(var) >= 0);
14220  assert(lp->looseobjvalinf >= 0);
14221 
14222  obj = SCIPvarGetObj(var);
14223 
14224  /* update loose objective value corresponding to the addition of variable */
14225  if( SCIPsetIsPositive(set, obj) )
14226  {
14227  lb = SCIPvarGetLbLocal(var);
14228  if( SCIPsetIsInfinity(set, -lb) )
14229  lp->looseobjvalinf++;
14230  else
14231  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14232  }
14233  else if( SCIPsetIsNegative(set, obj) )
14234  {
14235  ub = SCIPvarGetUbLocal(var);
14236  if( SCIPsetIsInfinity(set, ub) )
14237  lp->looseobjvalinf++;
14238  else
14239  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14240  }
14241  lp->nloosevars++;
14242 
14243  assert(lp->looseobjvalinf >= 0);
14244 
14245  return SCIP_OKAY;
14246 }
14247 
14248 /** informs LP, that given formerly column problem variable is now again a loose variable
14249  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14250  */
14251 static
14253  SCIP_LP* lp, /**< current LP data */
14254  SCIP_SET* set, /**< global SCIP settings */
14255  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14256  )
14257 {
14258  SCIP_INTERVAL bd;
14259  SCIP_INTERVAL ob;
14260  SCIP_INTERVAL prod;
14261  SCIP_INTERVAL loose;
14262  SCIP_Real obj;
14263  SCIP_Real lb;
14264  SCIP_Real ub;
14265 
14266  assert(lp != NULL);
14267  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14268  assert(SCIPvarGetProbindex(var) >= 0);
14269 
14270  obj = SCIPvarGetObj(var);
14271 
14272  SCIPintervalSet(&loose, lp->looseobjval);
14273 
14274  /* update loose objective value corresponding to the deletion of variable */
14275  if( obj > 0.0 )
14276  {
14277  lb = SCIPvarGetLbLocal(var);
14278  if( SCIPsetIsInfinity(set, -lb) )
14279  lp->looseobjvalinf++;
14280  else
14281  {
14282  SCIPintervalSet(&bd, lb);
14283  SCIPintervalSet(&ob, obj);
14284  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14285  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14286  }
14287  }
14288  else if( SCIPsetIsNegative(set, obj) )
14289  {
14290  ub = SCIPvarGetUbLocal(var);
14291  if( SCIPsetIsInfinity(set, ub) )
14292  lp->looseobjvalinf++;
14293  else
14294  {
14295  SCIPintervalSet(&bd, ub);
14296  SCIPintervalSet(&ob, obj);
14297  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14298  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14299  }
14300  }
14301  lp->nloosevars++;
14302 
14303  lp->looseobjval = SCIPintervalGetInf(loose);
14304 
14305  return SCIP_OKAY;
14306 }
14307 
14308 /** informs LP, that given formerly column problem variable is now again a loose variable */
14310  SCIP_LP* lp, /**< current LP data */
14311  SCIP_SET* set, /**< global SCIP settings */
14312  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14313  )
14314 {
14315  assert(set != NULL);
14316 
14317  if( set->misc_exactsolve )
14318  {
14319  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14320  }
14321  else
14322  {
14323  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14324  }
14325 
14326  return SCIP_OKAY;
14327 }
14328 
14329 /** decrease the number of loose variables by one */
14331  SCIP_LP* lp /**< current LP data */
14332  )
14333 {
14334  assert(lp != NULL);
14335  assert(lp->nloosevars > 0);
14336 
14337  lp->nloosevars--;
14338 
14339  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14340  if( lp->nloosevars == 0 )
14341  {
14342  assert(lp->looseobjvalinf == 0);
14343  lp->looseobjval = 0.0;
14344  }
14345 }
14346 
14347 /** stores the LP solution in the columns and rows */
14349  SCIP_LP* lp, /**< current LP data */
14350  SCIP_SET* set, /**< global SCIP settings */
14351  SCIP_STAT* stat, /**< problem statistics */
14352  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14353  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14354  )
14355 {
14356  SCIP_COL** lpicols;
14357  SCIP_ROW** lpirows;
14358  SCIP_Real* primsol;
14359  SCIP_Real* dualsol;
14360  SCIP_Real* activity = NULL;
14361  SCIP_Real* redcost;
14362  SCIP_Real primalbound;
14363  SCIP_Real dualbound;
14364  SCIP_Bool stillprimalfeasible;
14365  SCIP_Bool stilldualfeasible;
14366  int* cstat;
14367  int* rstat;
14368  SCIP_Longint lpcount;
14369  int nlpicols;
14370  int nlpirows;
14371  int c;
14372  int r;
14373 
14374  assert(lp != NULL);
14375  assert(lp->flushed);
14376  assert(lp->solved);
14377  assert(set != NULL);
14378  assert(stat != NULL);
14379  assert(lp->validsollp <= stat->lpcount);
14380 
14381  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
14382 
14383  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14384  * corresponding flag immediately to FALSE to skip all checks
14385  */
14386  if( primalfeasible == NULL )
14387  stillprimalfeasible = FALSE;
14388  else
14389  {
14390  *primalfeasible = TRUE;
14391  stillprimalfeasible = TRUE;
14392  }
14393  if( dualfeasible == NULL )
14394  stilldualfeasible = FALSE;
14395  else
14396  {
14397  *dualfeasible = TRUE;
14398  stilldualfeasible = TRUE;
14399  }
14400 
14401  /* check if the values are already calculated */
14402  if( lp->validsollp == stat->lpcount )
14403  return SCIP_OKAY;
14404  lp->validsollp = stat->lpcount;
14405 
14406  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14407  stat->lpcount, SCIPlpGetSolstat(lp));
14408 
14409  lpicols = lp->lpicols;
14410  lpirows = lp->lpirows;
14411  nlpicols = lp->nlpicols;
14412  nlpirows = lp->nlpirows;
14413  lpcount = stat->lpcount;
14414 
14415  /* get temporary memory */
14416  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14417  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14418 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14419  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14420 #endif
14421  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14422  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14423  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14424 
14425  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14426  if( lp->solisbasic )
14427  {
14428  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14429  }
14430  else
14431  {
14432  BMSclearMemoryArray(cstat, nlpicols);
14433  BMSclearMemoryArray(rstat, nlpirows);
14434  }
14435 
14436  primalbound = 0.0;
14437  dualbound = 0.0;
14438 
14439  /* copy primal solution and reduced costs into columns */
14440  for( c = 0; c < nlpicols; ++c )
14441  {
14442  assert( 0 <= cstat[c] && cstat[c] < 4 );
14443  lpicols[c]->primsol = primsol[c];
14444  if( !SCIPisFinite(lpicols[c]->primsol) )
14445  {
14446  /* calculating with nan or +/-inf can have many unexpected effects
14447  * thus change the solution here to a reasonable value (0.0) and declare it as neither primal nor dual feasible
14448  * this should trigger a resolve of the LP, or a stop with an LP error
14449  */
14450  stillprimalfeasible = FALSE;
14451  stilldualfeasible = FALSE;
14452  lpicols[c]->primsol = 0.0;
14453  SCIPsetDebugMsg(set, " col <%s>: primsol=%.9f is not finite\n", SCIPvarGetName(lpicols[c]->var), primsol[c]);
14454  }
14455  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14456  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14457  lpicols[c]->redcost = redcost[c];
14458  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14459  lpicols[c]->validredcostlp = lpcount;
14460  if( stillprimalfeasible )
14461  {
14462  stillprimalfeasible =
14463  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
14464  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
14465  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14466  }
14467  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14468  {
14469  double compslack;
14470 
14471  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14472  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14473  * variables, which would magnify even the tiniest violation in the dual multiplier
14474  */
14475  if( stilldualfeasible )
14476  {
14477  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14478  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14479  }
14480  if( stilldualfeasible )
14481  {
14482  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14483  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14484  }
14485 
14486  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14487  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14488  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14489  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14490  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14491  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14492  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14493  dualfeasible != NULL ? stilldualfeasible : TRUE);
14494  }
14495  else
14496  {
14497  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14498  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14499  {
14500  lpicols[c]->redcost = 0.0;
14501  }
14502 
14503  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14504  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14505  * bounds, its reduced cost must be zero
14506  */
14507  if( stilldualfeasible
14508  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
14509  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14510  if( stilldualfeasible
14511  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
14512  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14513 
14514  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14515  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14516  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14517  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14518  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14519  !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14520  !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14521  dualfeasible != NULL ? stilldualfeasible : TRUE);
14522  }
14523 
14524  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14525  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14526  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14527  */
14528  if( stilldualfeasible )
14529  {
14530  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14531  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14532  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14533  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14534  }
14535  }
14536 
14537  /* copy dual solution and activities into rows */
14538  for( r = 0; r < nlpirows; ++r )
14539  {
14540  assert( 0 <= rstat[r] && rstat[r] < 4 );
14541  lpirows[r]->dualsol = dualsol[r];
14542 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14543  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14544 #else
14545  /* calculate row activity if invalid */
14546  if( lpirows[r]->validactivitylp != stat->lpcount )
14547  SCIProwRecalcLPActivity(lpirows[r], stat);
14548 #endif
14549  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14550  lpirows[r]->validactivitylp = lpcount;
14551  if( stillprimalfeasible )
14552  {
14553  stillprimalfeasible =
14554  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14555  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14556  }
14557  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14558  {
14559  double compslack;
14560 
14561  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14562  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14563  * variables, which would magnify even the tiniest violation in the dual multiplier
14564  */
14565  if( stilldualfeasible )
14566  {
14567  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14568  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14569  }
14570  if( stilldualfeasible )
14571  {
14572  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14573  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14574  }
14575 
14576  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14577  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14578  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14579  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14580  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14581  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14582  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14583  dualfeasible != NULL ? stilldualfeasible : TRUE);
14584  }
14585  else
14586  {
14587  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14588  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14589  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14590  */
14591  if( stilldualfeasible &&
14592  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
14593  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14594  if( stilldualfeasible &&
14595  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
14596  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14597 
14598  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14599  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14600  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14601  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14602  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14603  !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14604  !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14605  dualfeasible != NULL ? stilldualfeasible : TRUE);
14606  }
14607 
14608  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14609  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14610  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14611  */
14612  if( stilldualfeasible )
14613  {
14614  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14615  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14616  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14617  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14618  }
14619  }
14620 
14621  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14622  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14623  * infinity
14624  */
14625  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14626  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14627  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14628  {
14629  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14630  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14631  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14632  }
14633 
14634  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14635  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14636  */
14637  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14638  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14639  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14640  {
14641  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14642  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14643  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14644  }
14645 
14646  if( primalfeasible != NULL )
14647  *primalfeasible = stillprimalfeasible;
14648  if( dualfeasible != NULL )
14649  *dualfeasible = stilldualfeasible;
14650 
14651  /* free temporary memory */
14652  SCIPsetFreeBufferArray(set, &rstat);
14653  SCIPsetFreeBufferArray(set, &cstat);
14654  SCIPsetFreeBufferArray(set, &redcost);
14655 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14656  SCIPsetFreeBufferArray(set, &activity);
14657 #endif
14658  SCIPsetFreeBufferArray(set, &dualsol);
14659  SCIPsetFreeBufferArray(set, &primsol);
14660 
14661  return SCIP_OKAY;
14662 }
14663 
14664 /** stores LP solution with infinite objective value in the columns and rows */
14666  SCIP_LP* lp, /**< current LP data */
14667  SCIP_SET* set, /**< global SCIP settings */
14668  SCIP_STAT* stat, /**< problem statistics */
14669  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14670  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14671  )
14672 {
14673  SCIP_COL** lpicols;
14674  SCIP_ROW** lpirows;
14675  SCIP_Real* primsol;
14676  SCIP_Real* activity;
14677  SCIP_Real* ray;
14678  SCIP_Real rayobjval;
14679  SCIP_Real rayscale;
14680  SCIP_Longint lpcount;
14681  SCIP_COL* col;
14682  int nlpicols;
14683  int nlpirows;
14684  int c;
14685  int r;
14686 
14687  assert(lp != NULL);
14688  assert(lp->flushed);
14689  assert(lp->solved);
14690  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14691  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14692  assert(set != NULL);
14693  assert(stat != NULL);
14694  assert(lp->validsollp <= stat->lpcount);
14695 
14696  if( primalfeasible != NULL )
14697  *primalfeasible = TRUE;
14698  if( rayfeasible != NULL )
14699  *rayfeasible = TRUE;
14700 
14701  /* check if the values are already calculated */
14702  if( lp->validsollp == stat->lpcount )
14703  return SCIP_OKAY;
14704  lp->validsollp = stat->lpcount;
14705 
14706  /* check if the LP solver is able to provide a primal unbounded ray */
14707  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14708  {
14709  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness.\n");
14710  return SCIP_LPERROR;
14711  }
14712 
14713  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14714 
14715  /* get temporary memory */
14716  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14717  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14718  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14719 
14720  /* get primal unbounded ray */
14721  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14722 
14723  lpicols = lp->lpicols;
14724  lpirows = lp->lpirows;
14725  nlpicols = lp->nlpicols;
14726  nlpirows = lp->nlpirows;
14727  lpcount = stat->lpcount;
14728 
14729  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14730  rayobjval = 0.0;
14731  for( c = 0; c < nlpicols; ++c )
14732  {
14733  assert(lpicols[c] != NULL);
14734  assert(lpicols[c]->var != NULL);
14735 
14736  col = lpicols[c];
14737 
14738  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14739  if( rayfeasible != NULL )
14740  {
14741  *rayfeasible = *rayfeasible
14742  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14743  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14744  }
14745 
14746  if( ! SCIPsetIsZero(set, ray[c]) )
14747  rayobjval += ray[c] * col->obj;
14748 
14749  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14750  * heuristically try to construct a primal solution.
14751  */
14752  primsol[c] = 0.0;
14753  if( SCIPsetIsFeasZero(set, ray[c]) )
14754  {
14755  /* if the ray component is 0, we try to satisfy as many rows as possible */
14756  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14757  primsol[c] = col->lb;
14758  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14759  primsol[c] = col->ub;
14760  }
14761 
14762  /* make sure we respect the bounds */
14763  primsol[c] = MAX(primsol[c], col->lb);
14764  primsol[c] = MIN(primsol[c], col->ub);
14765 
14766  assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
14767  }
14768 
14769  /* check feasibility of heuristic primal solution */
14770  for( r = 0; r < nlpirows; ++r )
14771  {
14772  SCIP_Real act;
14773  SCIP_ROW* row;
14774 
14775  row = lpirows[r];
14776  assert( row != NULL );
14777  act = row->constant;
14778 
14779  for( c = 0; c < row->nlpcols; ++c )
14780  {
14781  col = row->cols[c];
14782 
14783  assert( col != NULL );
14784  assert( col->lppos >= 0 );
14785  assert( row->linkpos[c] >= 0 );
14786  assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
14787 
14788  act += row->vals[c] * primsol[col->lppos];
14789  }
14790 
14791  if( row->nunlinked > 0 )
14792  {
14793  for( c = row->nlpcols; c < row->len; ++c )
14794  {
14795  col = row->cols[c];
14796  assert( col != NULL );
14797 
14798  if( col->lppos >= 0 )
14799  act += row->vals[c] * primsol[col->lppos];
14800  }
14801  }
14802 
14803  /* check feasibility */
14804  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
14805  (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
14806  break;
14807  }
14808 
14809  /* if heuristic primal solution is not feasible, try to obtain solution from LPI */
14810  if( r < nlpirows )
14811  {
14812  /* get primal feasible point */
14813  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
14814 
14815  /* check bounds of primal solution */
14816  if( primalfeasible != NULL )
14817  {
14818  assert( *primalfeasible );
14819  for( c = 0; c < nlpicols; ++c )
14820  {
14821  assert( lpicols[c] != NULL );
14822  assert( lpicols[c]->var != NULL );
14823 
14824  /* check whether primal solution satisfies the bounds; note that we also ensure that the primal
14825  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined */
14826  if( SCIPsetIsInfinity(set, REALABS(primsol[c])) || SCIPlpIsFeasLT(set, lp, primsol[c], lpicols[c]->lb) ||
14827  SCIPlpIsFeasGT(set, lp, primsol[c], lpicols[c]->ub) )
14828  {
14829  *primalfeasible = FALSE;
14830  break;
14831  }
14832  }
14833  }
14834  }
14835 
14836  /* compute activity and check feasibility of primal solution and ray */
14837  for( r = 0; r < nlpirows; ++r )
14838  {
14839  SCIP_Real primact;
14840  SCIP_Real rayact = 0.0;
14841  SCIP_ROW* row;
14842 
14843  row = lpirows[r];
14844  assert( row != NULL );
14845 
14846  primact = row->constant;
14847 
14848  for( c = 0; c < row->nlpcols; ++c )
14849  {
14850  col = row->cols[c];
14851 
14852  assert( col != NULL );
14853  assert( col->lppos >= 0 );
14854  assert( row->linkpos[c] >= 0 );
14855  assert( primsol[col->lppos] != SCIP_INVALID ); /*lint !e777*/
14856 
14857  primact += row->vals[c] * primsol[col->lppos];
14858  rayact += row->vals[c] * ray[col->lppos];
14859  }
14860 
14861  if( row->nunlinked > 0 )
14862  {
14863  for( c = row->nlpcols; c < row->len; ++c )
14864  {
14865  col = row->cols[c];
14866  assert( col != NULL );
14867 
14868  if( col->lppos >= 0 )
14869  {
14870  primact += row->vals[c] * primsol[col->lppos];
14871  rayact += row->vals[c] * ray[col->lppos];
14872  }
14873  }
14874  }
14875 
14876  /* check feasibility of primal solution */
14877  if( primalfeasible != NULL && *primalfeasible )
14878  {
14879  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, primact, row->lhs) ) ||
14880  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, primact, row->rhs) ) )
14881  *primalfeasible = FALSE;
14882  }
14883 
14884  /* check feasibility of ray */
14885  if( rayfeasible != NULL && *rayfeasible )
14886  {
14887  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, rayact, 0.0) ) ||
14888  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, rayact, 0.0) ) )
14889  *rayfeasible = FALSE;
14890  }
14891 
14892  /* store activity of primal solution */
14893  activity[r] = primact;
14894  }
14895 
14896  if( primalfeasible != NULL && !(*primalfeasible) )
14897  {
14898  /* if the finite point is already infeasible, we do not have to add the ray */
14899  rayscale = 0.0;
14900  }
14901  else if( rayfeasible != NULL && !(*rayfeasible) )
14902  {
14903  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14904  rayscale = 0.0;
14905  }
14906  else if( !SCIPsetIsNegative(set, rayobjval) )
14907  {
14908  /* due to numerical problems, the objective of the ray might be nonnegative
14909  *
14910  * @todo How to check for negative objective value here?
14911  */
14912  if( rayfeasible != NULL )
14913  *rayfeasible = FALSE;
14914 
14915  rayscale = 0.0;
14916  }
14917  else
14918  {
14919  assert(rayobjval != 0.0);
14920 
14921  /* scale the ray, such that the resulting point has infinite objective value */
14922  rayscale = -2.0 * SCIPsetInfinity(set) / rayobjval;
14923  assert(SCIPsetIsFeasPositive(set, rayscale));
14924 
14925  /* ensure that unbounded point does not violate the bounds of the variables */
14926  for( c = 0; c < nlpicols; ++c )
14927  {
14928  if( SCIPsetIsPositive(set, ray[c]) )
14929  {
14930  if( !SCIPsetIsInfinity(set, primsol[c]) )
14931  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c]) / ray[c]);
14932  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14933  else
14934  {
14935  assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
14936  rayscale = MIN(rayscale, 1.0 / ray[c]);
14937  }
14938  }
14939  else if( SCIPsetIsNegative(set, ray[c]) )
14940  {
14941  if( !SCIPsetIsInfinity(set, -primsol[c]) )
14942  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c]) / ray[c]);
14943  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14944  else
14945  {
14946  assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
14947  rayscale = MIN(rayscale, -1.0 / ray[c]);
14948  }
14949  }
14950 
14951  assert(SCIPsetIsFeasPositive(set, rayscale));
14952  }
14953  }
14954 
14955  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14956 
14957  /* calculate the unbounded point: x' = x + rayscale * ray */
14958  /* Note: We do not check the feasibility of the unbounded solution, because it will likely be infeasible due to the
14959  * typically large values in scaling. */
14960  for( c = 0; c < nlpicols; ++c )
14961  {
14962  if( SCIPsetIsZero(set, ray[c]) )
14963  lpicols[c]->primsol = primsol[c];
14964  else
14965  {
14966  SCIP_Real primsolval;
14967  primsolval = primsol[c] + rayscale * ray[c];
14968  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14969  }
14970  lpicols[c]->redcost = SCIP_INVALID;
14971  lpicols[c]->validredcostlp = -1;
14972  }
14973 
14974  /* transfer solution */
14975  for( r = 0; r < nlpirows; ++r )
14976  {
14977  lpirows[r]->dualsol = SCIP_INVALID;
14978  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14979  lpirows[r]->validactivitylp = lpcount;
14980  }
14981 
14982  /* free temporary memory */
14983  SCIPsetFreeBufferArray(set, &ray);
14984  SCIPsetFreeBufferArray(set, &activity);
14985  SCIPsetFreeBufferArray(set, &primsol);
14986 
14987  return SCIP_OKAY;
14988 }
14989 
14990 /** returns primal ray proving the unboundedness of the current LP */
14992  SCIP_LP* lp, /**< current LP data */
14993  SCIP_SET* set, /**< global SCIP settings */
14994  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14995  * so the size of this array should be at least number of active variables
14996  * (all entries have to be initialized to 0 before) */
14997  )
14998 {
14999  SCIP_COL** lpicols;
15000  SCIP_Real* lpiray;
15001  SCIP_VAR* var;
15002  int nlpicols;
15003  int c;
15004 
15005  assert(lp != NULL);
15006  assert(set != NULL);
15007  assert(ray != NULL);
15008  assert(lp->flushed);
15009  assert(lp->solved);
15010  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
15011  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
15012 
15013  /* check if the LP solver is able to provide a primal unbounded ray */
15014  if( !SCIPlpiHasPrimalRay(lp->lpi) )
15015  {
15016  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
15017  return SCIP_LPERROR;
15018  }
15019 
15020  /* get temporary memory */
15021  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
15022 
15023  SCIPsetDebugMsg(set, "getting primal ray values\n");
15024 
15025  /* get primal unbounded ray */
15026  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
15027 
15028  lpicols = lp->lpicols;
15029  nlpicols = lp->nlpicols;
15030 
15031  /* store the ray values of active problem variables */
15032  for( c = 0; c < nlpicols; c++ )
15033  {
15034  assert(lpicols[c] != NULL);
15035 
15036  var = lpicols[c]->var;
15037  assert(var != NULL);
15038  assert(SCIPvarGetProbindex(var) != -1);
15039  ray[SCIPvarGetProbindex(var)] = lpiray[c];
15040  }
15041 
15042  SCIPsetFreeBufferArray(set, &lpiray);
15043 
15044  return SCIP_OKAY;
15045 }
15046 
15047 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
15048  * lp/checkfarkas = TRUE.
15049  *
15050  * @note the check will not be performed if @p valid is NULL.
15051  */
15053  SCIP_LP* lp, /**< current LP data */
15054  SCIP_SET* set, /**< global SCIP settings */
15055  SCIP_STAT* stat, /**< problem statistics */
15056  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
15057  )
15058 {
15059  SCIP_COL** lpicols;
15060  SCIP_ROW** lpirows;
15061  SCIP_Real* dualfarkas;
15062  SCIP_Real* farkascoefs;
15063  SCIP_Real farkaslhs;
15064  SCIP_Real maxactivity;
15065  SCIP_Bool checkfarkas;
15066  int nlpicols;
15067  int nlpirows;
15068  int c;
15069  int r;
15070 
15071  assert(lp != NULL);
15072  assert(lp->flushed);
15073  assert(lp->solved);
15074  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
15075  assert(set != NULL);
15076  assert(stat != NULL);
15077  assert(lp->validfarkaslp <= stat->lpcount);
15078 
15079  if( valid != NULL )
15080  *valid = TRUE;
15081 
15082  /* check if the values are already calculated */
15083  if( lp->validfarkaslp == stat->lpcount )
15084  return SCIP_OKAY;
15085  lp->validfarkaslp = stat->lpcount;
15086 
15087  farkascoefs = NULL;
15088  maxactivity = 0.0;
15089  farkaslhs = 0.0;
15090 
15091  checkfarkas = (set->lp_checkfarkas && valid != NULL);
15092 
15093  /* get temporary memory */
15094  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
15095 
15096  if( checkfarkas )
15097  {
15098  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
15099  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
15100  }
15101 
15102  /* get dual Farkas infeasibility proof */
15103  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
15104 
15105  lpicols = lp->lpicols;
15106  lpirows = lp->lpirows;
15107  nlpicols = lp->nlpicols;
15108  nlpirows = lp->nlpirows;
15109 
15110  /* store infeasibility proof in rows */
15111  SCIPsetDebugMsg(set, "LP is infeasible:\n");
15112  for( r = 0; r < nlpirows; ++r )
15113  {
15114  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
15115  lpirows[r]->dualfarkas = dualfarkas[r];
15116  lpirows[r]->dualsol = SCIP_INVALID;
15117  lpirows[r]->activity = 0.0;
15118  lpirows[r]->validactivitylp = -1L;
15119  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
15120 
15121  if( checkfarkas )
15122  {
15123  assert(farkascoefs != NULL);
15124 
15125  /* the infeasibility proof would be invalid if
15126  * (i) dualfarkas[r] > 0 and lhs = -inf
15127  * (ii) dualfarkas[r] < 0 and rhs = inf
15128  * however, due to numerics we accept slightly negative / positive values
15129  */
15130  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15131  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15132  {
15133  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15134  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15135 
15136  if( valid != NULL )
15137  *valid = FALSE;
15138 
15139  goto TERMINATE;
15140  }
15141 
15142  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15143  * within tolerances (see above) but slighty positive / negative
15144  */
15145  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15146  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15147  continue;
15148 
15149  /* iterate over all columns and scale with dual solution */
15150  for( c = 0; c < lpirows[r]->len; c++ )
15151  {
15152  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15153 
15154  if( pos == -1 )
15155  continue;
15156 
15157  assert(pos >= 0 && pos < nlpicols);
15158 
15159  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15160  }
15161 
15162  /* the row contributes with its left-hand side to the proof */
15163  if( dualfarkas[r] > 0.0 )
15164  {
15165  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15166 
15167  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
15168  }
15169  /* the row contributes with its right-hand side to the proof */
15170  else if( dualfarkas[r] < 0.0 )
15171  {
15172  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15173 
15174  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
15175  }
15176  }
15177  }
15178 
15179  /* set columns as invalid */
15180  for( c = 0; c < nlpicols; ++c )
15181  {
15182  lpicols[c]->primsol = SCIP_INVALID;
15183  lpicols[c]->redcost = SCIP_INVALID;
15184  lpicols[c]->validredcostlp = -1L;
15185  lpicols[c]->validfarkaslp = -1L;
15186 
15187  if( checkfarkas )
15188  {
15189  assert(farkascoefs != NULL);
15190  assert(SCIPcolGetLPPos(lpicols[c]) == c);
15191 
15192  /* skip coefficients that are too close to zero */
15193  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
15194  continue;
15195 
15196  /* calculate the maximal activity */
15197  if( farkascoefs[c] > 0.0 )
15198  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
15199  else
15200  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
15201  }
15202  }
15203 
15204  /* check whether the farkasproof is valid
15205  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
15206  * in that case, we declare the Farkas proof to be invalid.
15207  */
15208  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
15209  {
15210  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15211 
15212  if( valid != NULL )
15213  *valid = FALSE;
15214  }
15215 
15216  TERMINATE:
15217  /* free temporary memory */
15218  if( checkfarkas )
15219  SCIPsetFreeBufferArray(set, &farkascoefs);
15220 
15221  SCIPsetFreeBufferArray(set, &dualfarkas);
15222 
15223  return SCIP_OKAY;
15224 }
15225 
15226 /** get number of iterations used in last LP solve */
15228  SCIP_LP* lp, /**< current LP data */
15229  int* iterations /**< pointer to store the iteration count */
15230  )
15231 {
15232  assert(lp != NULL);
15233 
15234  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15235 
15236  return SCIP_OKAY;
15237 }
15238 
15239 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15240  * resets age of non-zero columns and sharp rows
15241  */
15243  SCIP_LP* lp, /**< current LP data */
15244  SCIP_STAT* stat /**< problem statistics */
15245  )
15246 {
15247  SCIP_COL** lpicols;
15248  SCIP_ROW** lpirows;
15249  int nlpicols;
15250  int nlpirows;
15251  int c;
15252  int r;
15253 
15254  assert(lp != NULL);
15255  assert(lp->flushed);
15256  assert(lp->solved);
15257  assert(lp->nlpicols == lp->ncols);
15258  assert(lp->nlpirows == lp->nrows);
15259  assert(stat != NULL);
15260  assert(lp->validsollp == stat->lpcount);
15261 
15262  SCIPdebugMessage("updating LP ages\n");
15263 
15264  lpicols = lp->lpicols;
15265  lpirows = lp->lpirows;
15266  nlpicols = lp->nlpicols;
15267  nlpirows = lp->nlpirows;
15268 
15269  for( c = 0; c < nlpicols; ++c )
15270  {
15271  assert(lpicols[c] == lp->cols[c]);
15272  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15273  lpicols[c]->age++;
15274  else
15275  lpicols[c]->age = 0;
15276  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15277  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15278  }
15279 
15280  for( r = 0; r < nlpirows; ++r )
15281  {
15282  lpirows[r]->nlpsaftercreation++;
15283  assert(lpirows[r] == lp->rows[r]);
15284 
15285  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15286  {
15287  lpirows[r]->age++;
15288  }
15289  else
15290  {
15291  lpirows[r]->activeinlpcounter++;
15292  lpirows[r]->age = 0;
15293  }
15294  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15295  }
15296 
15297  return SCIP_OKAY;
15298 }
15299 
15300 /* deletes the marked columns from the LP and the LP interface */
15301 static
15303  SCIP_LP* lp, /**< current LP data */
15304  SCIP_SET* set, /**< global SCIP settings */
15305  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15306  )
15307 {
15308  SCIP_COL* col;
15309  int ncols;
15310  int c;
15311 
15312  assert(lp != NULL);
15313  assert(lp->flushed);
15314  assert(lp->ncols == lp->nlpicols);
15315  assert(!lp->diving);
15316  assert(coldstat != NULL);
15317  assert(lp->nlazycols <= lp->ncols);
15318 
15319  ncols = lp->ncols;
15320 
15321  /* delete columns in LP solver */
15322  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15323 
15324  /* update LP data respectively */
15325  for( c = 0; c < ncols; ++c )
15326  {
15327  col = lp->cols[c];
15328  assert(col != NULL);
15329  assert(col == lp->lpicols[c]);
15330  assert(coldstat[c] <= c);
15331  col->lppos = coldstat[c];
15332  if( coldstat[c] == -1 )
15333  {
15334  assert(col->removable);
15335 
15336  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15337  * function vector norms
15338  */
15339  markColDeleted(col);
15340  colUpdateDelLP(col, set);
15341  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15342  col->lpdepth = -1;
15343 
15344  lp->cols[c] = NULL;
15345  lp->lpicols[c] = NULL;
15346  lp->ncols--;
15347  lp->nremovablecols--;
15348  lp->nlpicols--;
15349  }
15350  else if( coldstat[c] < c )
15351  {
15352  assert(lp->cols[coldstat[c]] == NULL);
15353  assert(lp->lpicols[coldstat[c]] == NULL);
15354  lp->cols[coldstat[c]] = col;
15355  lp->lpicols[coldstat[c]] = col;
15356  lp->cols[coldstat[c]]->lppos = coldstat[c];
15357  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15358  lp->cols[c] = NULL;
15359  lp->lpicols[c] = NULL;
15360  }
15361  }
15362 
15363  /* remove columns which are deleted from the lazy column array */
15364  c = 0;
15365  while( c < lp->nlazycols )
15366  {
15367  if( lp->lazycols[c]->lpipos < 0 )
15368  {
15369  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15370  lp->nlazycols--;
15371  }
15372  else
15373  c++;
15374  }
15375 
15376  /* mark LP to be unsolved */
15377  if( lp->ncols < ncols )
15378  {
15379  assert(lp->ncols == lp->nlpicols);
15380  assert(lp->nchgcols == 0);
15381  assert(lp->flushed);
15382 
15383  lp->lpifirstchgcol = lp->nlpicols;
15384 
15385  /* mark the current solution invalid */
15386  lp->solved = FALSE;
15387  lp->primalfeasible = FALSE;
15388  lp->primalchecked = FALSE;
15389  lp->lpobjval = SCIP_INVALID;
15391  }
15392 
15393  checkLazyColArray(lp, set);
15394  checkLinks(lp);
15395 
15396  return SCIP_OKAY;
15397 }
15398 
15399 /* deletes the marked rows from the LP and the LP interface */
15400 static
15402  SCIP_LP* lp, /**< current LP data */
15403  BMS_BLKMEM* blkmem, /**< block memory buffers */
15404  SCIP_SET* set, /**< global SCIP settings */
15405  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15406  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15407  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15408  )
15409 {
15410  SCIP_ROW* row;
15411  int nrows;
15412  int r;
15413 
15414  assert(lp != NULL);
15415  assert(lp->flushed);
15416  assert(lp->nrows == lp->nlpirows);
15417  assert(!lp->diving);
15418  assert(rowdstat != NULL);
15419 
15420  nrows = lp->nrows;
15421 
15422  /* delete rows in LP solver */
15423  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15424 
15425  /* update LP data respectively */
15426  for( r = 0; r < nrows; ++r )
15427  {
15428  row = lp->rows[r];
15429  assert(row == lp->lpirows[r]);
15430  assert(rowdstat[r] <= r);
15431  assert(row != NULL);
15432  row->lppos = rowdstat[r];
15433  if( rowdstat[r] == -1 )
15434  {
15435  if( row->removable )
15436  lp->nremovablerows--;
15437 
15438  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15439  markRowDeleted(row);
15440  rowUpdateDelLP(row);
15441  row->lpdepth = -1;
15442 
15443  /* check, if row deletion events are tracked
15444  * if so, issue ROWDELETEDLP event
15445  */
15446  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15447  {
15448  SCIP_EVENT* event;
15449 
15450  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15451  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15452  }
15453 
15454  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15455  SCIProwUnlock(lp->rows[r]);
15456  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15457  assert(lp->lpirows[r] == NULL);
15458  assert(lp->rows[r] == NULL);
15459  lp->nrows--;
15460  lp->nlpirows--;
15461  }
15462  else if( rowdstat[r] < r )
15463  {
15464  assert(lp->rows[rowdstat[r]] == NULL);
15465  assert(lp->lpirows[rowdstat[r]] == NULL);
15466  lp->rows[rowdstat[r]] = row;
15467  lp->lpirows[rowdstat[r]] = row;
15468  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15469  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15470  lp->rows[r] = NULL;
15471  lp->lpirows[r] = NULL;
15472  }
15473  }
15474 
15475  /* mark LP to be unsolved */
15476  if( lp->nrows < nrows )
15477  {
15478  assert(lp->nrows == lp->nlpirows);
15479  assert(lp->nchgrows == 0);
15480  assert(lp->flushed);
15481 
15482  lp->lpifirstchgrow = lp->nlpirows;
15483 
15484  /* mark the current solution invalid */
15485  lp->solved = FALSE;
15486  lp->dualfeasible = FALSE;
15487  lp->dualchecked = FALSE;
15488  lp->lpobjval = SCIP_INVALID;
15490  }
15491 
15492  checkLinks(lp);
15493 
15494  return SCIP_OKAY;
15495 }
15496 
15497 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15498 static
15500  SCIP_LP* lp, /**< current LP data */
15501  SCIP_SET* set, /**< global SCIP settings */
15502  SCIP_STAT* stat, /**< problem statistics */
15503  int firstcol /**< first column to check for clean up */
15504  )
15505 {
15506  SCIP_COL** cols;
15507 #ifndef NDEBUG
15508  SCIP_COL** lpicols;
15509 #endif
15510  int* coldstat;
15511  int ncols;
15512  int ndelcols;
15513  int c;
15514 
15515  assert(lp != NULL);
15516  assert(lp->flushed);
15517  assert(lp->ncols == lp->nlpicols);
15518  assert(lp->nremovablecols <= lp->ncols);
15519  assert(!lp->diving);
15520  assert(set != NULL);
15521  assert(stat != NULL);
15522 
15523  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15524  return SCIP_OKAY;
15525 
15526  ncols = lp->ncols;
15527  cols = lp->cols;
15528 #ifndef NDEBUG
15529  lpicols = lp->lpicols;
15530 #endif
15531 
15532  /* get temporary memory */
15533  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15534 
15535  /* mark obsolete columns to be deleted */
15536  ndelcols = 0;
15537  BMSclearMemoryArray(coldstat, ncols);
15538  for( c = firstcol; c < ncols; ++c )
15539  {
15540  assert(cols[c] == lpicols[c]);
15541  assert(cols[c]->lppos == c);
15542  assert(cols[c]->lpipos == c);
15543  if( cols[c]->removable
15544  && 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 */
15545  && cols[c]->age > set->lp_colagelimit
15547  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15548  {
15549  assert(cols[c]->primsol == 0.0);
15550  coldstat[c] = 1;
15551  ndelcols++;
15552  cols[c]->obsoletenode = stat->nnodes;
15553  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15554  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15555  }
15556  }
15557 
15558  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15559 
15560  /* delete the marked columns in the LP solver interface, update the LP respectively */
15561  if( ndelcols > 0 )
15562  {
15563  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15564  }
15565  assert(lp->ncols == ncols - ndelcols);
15566 
15567  /* release temporary memory */
15568  SCIPsetFreeBufferArray(set, &coldstat);
15569 
15570  return SCIP_OKAY;
15571 }
15572 
15573 /** removes all basic rows, that are too old, beginning with the given firstrow */
15574 static
15576  SCIP_LP* lp, /**< current LP data */
15577  BMS_BLKMEM* blkmem, /**< block memory buffers */
15578  SCIP_SET* set, /**< global SCIP settings */
15579  SCIP_STAT* stat, /**< problem statistics */
15580  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15581  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15582  int firstrow /**< first row to check for clean up */
15583  )
15584 {
15585  SCIP_ROW** rows;
15586 #ifndef NDEBUG
15587  SCIP_ROW** lpirows;
15588 #endif
15589  int* rowdstat;
15590  int nrows;
15591  int ndelrows;
15592  int r;
15593 
15594  assert(lp != NULL);
15595  assert(lp->flushed);
15596  assert(lp->nrows == lp->nlpirows);
15597  assert(lp->nremovablerows <= lp->nrows);
15598  assert(!lp->diving);
15599  assert(set != NULL);
15600  assert(stat != NULL);
15601 
15602  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15603  return SCIP_OKAY;
15604 
15605  nrows = lp->nrows;
15606  rows = lp->rows;
15607 #ifndef NDEBUG
15608  lpirows = lp->lpirows;
15609 #endif
15610 
15611  /* get temporary memory */
15612  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15613 
15614  /* mark obsolete rows to be deleted */
15615  ndelrows = 0;
15616  BMSclearMemoryArray(rowdstat, nrows);
15617  for( r = firstrow; r < nrows; ++r )
15618  {
15619  assert(rows[r] == lpirows[r]);
15620  assert(rows[r]->lppos == r);
15621  assert(rows[r]->lpipos == r);
15622  if( rows[r]->removable
15623  && 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 */
15624  && rows[r]->age > set->lp_rowagelimit
15626  {
15627  rowdstat[r] = 1;
15628  ndelrows++;
15629  rows[r]->obsoletenode = stat->nnodes;
15630  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15631  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15632  }
15633  }
15634 
15635  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15636 
15637  /* delete the marked rows in the LP solver interface, update the LP respectively */
15638  if( ndelrows > 0 )
15639  {
15640  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15641  }
15642  assert(lp->nrows == nrows - ndelrows);
15643 
15644  /* release temporary memory */
15645  SCIPsetFreeBufferArray(set, &rowdstat);
15646 
15647  return SCIP_OKAY;
15648 }
15649 
15650 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15652  SCIP_LP* lp, /**< current LP data */
15653  BMS_BLKMEM* blkmem, /**< block memory buffers */
15654  SCIP_SET* set, /**< global SCIP settings */
15655  SCIP_STAT* stat, /**< problem statistics */
15656  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15657  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15658  )
15659 {
15660  assert(lp != NULL);
15661  assert(lp->solved);
15662  assert(!lp->diving);
15664  assert(set != NULL);
15665 
15666  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15667  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15668 
15669  if( lp->firstnewcol < lp->ncols )
15670  {
15671  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15672  }
15673  if( lp->firstnewrow < lp->nrows )
15674  {
15675  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15676  }
15677 
15678  return SCIP_OKAY;
15679 }
15680 
15681 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15683  SCIP_LP* lp, /**< current LP data */
15684  BMS_BLKMEM* blkmem, /**< block memory buffers */
15685  SCIP_SET* set, /**< global SCIP settings */
15686  SCIP_STAT* stat, /**< problem statistics */
15687  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15688  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15689  )
15690 {
15691  assert(lp != NULL);
15692  assert(lp->solved);
15693  assert(!lp->diving);
15695  assert(set != NULL);
15696 
15697  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15698 
15699  if( 0 < lp->ncols )
15700  {
15701  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15702  }
15703  if( 0 < lp->nrows )
15704  {
15705  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15706  }
15707 
15708  return SCIP_OKAY;
15709 }
15710 
15711 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15712 static
15714  SCIP_LP* lp, /**< current LP data */
15715  SCIP_SET* set, /**< global SCIP settings */
15716  SCIP_STAT* stat, /**< problem statistics */
15717  int firstcol /**< first column to check for clean up */
15718  )
15719 {
15720  SCIP_COL** cols;
15721  SCIP_COL** lpicols;
15722  int* coldstat;
15723  int ncols;
15724  int ndelcols;
15725  int c;
15726 
15727  assert(lp != NULL);
15728  assert(lp->flushed);
15729  assert(lp->ncols == lp->nlpicols);
15730  assert(!lp->diving);
15731  assert(stat != NULL);
15732  assert(lp->validsollp == stat->lpcount);
15733  assert(0 <= firstcol && firstcol < lp->ncols);
15734 
15735  if( lp->nremovablecols == 0 || !lp->solisbasic )
15736  return SCIP_OKAY;
15737 
15738  ncols = lp->ncols;
15739  cols = lp->cols;
15740  lpicols = lp->lpicols;
15741 
15742  /* get temporary memory */
15743  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15744 
15745  /* mark unused columns to be deleted */
15746  ndelcols = 0;
15747  BMSclearMemoryArray(coldstat, ncols);
15748  for( c = firstcol; c < ncols; ++c )
15749  {
15750  assert(cols[c] == lpicols[c]);
15751  assert(cols[c]->lppos == c);
15752  assert(cols[c]->lpipos == c);
15753  if( lpicols[c]->removable
15754  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15755  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15756  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15757  {
15758  coldstat[c] = 1;
15759  ndelcols++;
15760  }
15761  }
15762 
15763  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15764 
15765  /* delete the marked columns in the LP solver interface, update the LP respectively */
15766  if( ndelcols > 0 )
15767  {
15768  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15769  }
15770  assert(lp->ncols == ncols - ndelcols);
15771 
15772  /* release temporary memory */
15773  SCIPsetFreeBufferArray(set, &coldstat);
15774 
15775  return SCIP_OKAY;
15776 }
15777 
15778 /** removes all basic rows beginning with the given firstrow */
15779 static
15781  SCIP_LP* lp, /**< current LP data */
15782  BMS_BLKMEM* blkmem, /**< block memory buffers */
15783  SCIP_SET* set, /**< global SCIP settings */
15784  SCIP_STAT* stat, /**< problem statistics */
15785  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15786  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15787  int firstrow /**< first row to check for clean up */
15788  )
15789 {
15790 #ifndef NDEBUG
15791  SCIP_ROW** rows;
15792 #endif
15793  SCIP_ROW** lpirows;
15794  int* rowdstat;
15795  int nrows;
15796  int ndelrows;
15797  int r;
15798 
15799  assert(lp != NULL);
15800  assert(lp->flushed);
15801  assert(lp->ncols == lp->nlpicols);
15802  assert(lp->nrows == lp->nlpirows);
15803  assert(!lp->diving);
15804  assert(stat != NULL);
15805  assert(lp->validsollp == stat->lpcount);
15806  assert(0 <= firstrow && firstrow < lp->nrows);
15807 
15808  if( lp->nremovablerows == 0 || !lp->solisbasic )
15809  return SCIP_OKAY;
15810 
15811 #ifndef NDEBUG
15812  rows = lp->rows;
15813 #endif
15814  nrows = lp->nrows;
15815  lpirows = lp->lpirows;
15816 
15817  /* get temporary memory */
15818  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15819 
15820  /* mark unused rows to be deleted */
15821  ndelrows = 0;
15822  BMSclearMemoryArray(rowdstat, nrows);
15823  for( r = firstrow; r < nrows; ++r )
15824  {
15825  assert(rows[r] == lpirows[r]);
15826  assert(rows[r]->lppos == r);
15827  assert(rows[r]->lpipos == r);
15828  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15829  {
15830  rowdstat[r] = 1;
15831  ndelrows++;
15832  }
15833  }
15834 
15835  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15836 
15837  /* delete the marked rows in the LP solver interface, update the LP respectively */
15838  if( ndelrows > 0 )
15839  {
15840  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15841  }
15842  assert(lp->nrows == nrows - ndelrows);
15843 
15844  /* release temporary memory */
15845  SCIPsetFreeBufferArray(set, &rowdstat);
15846 
15847  return SCIP_OKAY;
15848 }
15849 
15850 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15852  SCIP_LP* lp, /**< current LP data */
15853  BMS_BLKMEM* blkmem, /**< block memory buffers */
15854  SCIP_SET* set, /**< global SCIP settings */
15855  SCIP_STAT* stat, /**< problem statistics */
15856  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15857  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15858  SCIP_Bool root /**< are we at the root node? */
15859  )
15860 {
15861  SCIP_Bool cleanupcols;
15862  SCIP_Bool cleanuprows;
15863 
15864  assert(lp != NULL);
15865  assert(lp->solved);
15866  assert(!lp->diving);
15868  assert(set != NULL);
15869 
15870  /* check, if we want to clean up the columns and rows */
15871  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15872  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15873 
15874  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15875  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15876 
15877  if( cleanupcols && lp->firstnewcol < lp->ncols )
15878  {
15879  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15880  }
15881  if( cleanuprows && lp->firstnewrow < lp->nrows )
15882  {
15883  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15884  }
15885 
15886  return SCIP_OKAY;
15887 }
15888 
15889 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15891  SCIP_LP* lp, /**< current LP data */
15892  BMS_BLKMEM* blkmem, /**< block memory buffers */
15893  SCIP_SET* set, /**< global SCIP settings */
15894  SCIP_STAT* stat, /**< problem statistics */
15895  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15896  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15897  SCIP_Bool root /**< are we at the root node? */
15898  )
15899 {
15900  SCIP_Bool cleanupcols;
15901  SCIP_Bool cleanuprows;
15902 
15903  assert(lp != NULL);
15904  assert(lp->solved);
15905  assert(!lp->diving);
15907  assert(set != NULL);
15908 
15909  /* check, if we want to clean up the columns and rows */
15910  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15911  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15912 
15913  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15914  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15915 
15916  if( cleanupcols && 0 < lp->ncols )
15917  {
15918  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15919  }
15920  if( cleanuprows && 0 < lp->nrows )
15921  {
15922  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15923  }
15924 
15925  return SCIP_OKAY;
15926 }
15927 
15928 /** removes all redundant rows that were added at the current node */
15930  SCIP_LP* lp, /**< current LP data */
15931  BMS_BLKMEM* blkmem, /**< block memory buffers */
15932  SCIP_SET* set, /**< global SCIP settings */
15933  SCIP_STAT* stat, /**< problem statistics */
15934  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15935  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15936  )
15937 {
15938 #ifndef NDEBUG
15939  SCIP_ROW** rows;
15940 #endif
15941  SCIP_ROW** lpirows;
15942  int* rowdstat;
15943  int nrows;
15944  int ndelrows;
15945  int r;
15946 
15947  assert(lp != NULL);
15948  assert(lp->flushed);
15949  assert(lp->ncols == lp->nlpicols);
15950  assert(lp->nrows == lp->nlpirows);
15951  assert(!lp->diving);
15952  assert(stat != NULL);
15953  assert(lp->validsollp == stat->lpcount);
15954  assert(lp->firstnewrow <= lp->nrows);
15955 
15956  if( lp->firstnewrow == lp->nrows )
15957  return SCIP_OKAY;
15958 
15959 #ifndef NDEBUG
15960  rows = lp->rows;
15961 #endif
15962  nrows = lp->nrows;
15963  lpirows = lp->lpirows;
15964 
15965  /* get temporary memory */
15966  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15967 
15968  /* mark redundant rows to be deleted (only delete basic rows!) */
15969  ndelrows = 0;
15970  BMSclearMemoryArray(rowdstat, nrows);
15971  for( r = lp->firstnewrow; r < nrows; ++r )
15972  {
15973  assert(rows[r] == lpirows[r]);
15974  assert(rows[r]->lppos == r);
15975  assert(rows[r]->lpipos == r);
15976  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15977  && SCIProwIsRedundant(lpirows[r], set, stat) )
15978  {
15979  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15980  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15981  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15982  rowdstat[r] = 1;
15983  ndelrows++;
15984  }
15985  }
15986 
15987  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15988 
15989  /* delete the marked rows in the LP solver interface, update the LP respectively */
15990  if( ndelrows > 0 )
15991  {
15992  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15993  }
15994  assert(lp->nrows == nrows - ndelrows);
15995 
15996  /* release temporary memory */
15997  SCIPsetFreeBufferArray(set, &rowdstat);
15998 
15999  return SCIP_OKAY;
16000 }
16001 
16002 /** initiates LP diving */
16004  SCIP_LP* lp, /**< current LP data */
16005  BMS_BLKMEM* blkmem, /**< block memory */
16006  SCIP_SET* set, /**< global SCIP settings */
16007  SCIP_STAT* stat /**< problem statistics */
16008  )
16009 {
16010  int c;
16011  int r;
16012 
16013  assert(lp != NULL);
16014  assert(lp->flushed || !lp->solved);
16015  assert(!lp->diving);
16016  assert(!lp->probing);
16017  assert(lp->divelpistate == NULL);
16018  assert(lp->divelpwasprimfeas);
16019  assert(lp->divelpwasdualfeas);
16020  assert(lp->validsollp <= stat->lpcount);
16021  assert(blkmem != NULL);
16022  assert(set != NULL);
16023  assert(lp->ndivechgsides == 0);
16024 
16025  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
16026  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
16027 
16028 #ifndef NDEBUG
16029  for( c = 0; c < lp->ncols; ++c )
16030  {
16031  assert(lp->cols[c] != NULL);
16032  assert(lp->cols[c]->var != NULL);
16033  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16034  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16035  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16036  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16037  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16038  }
16039 #endif
16040 
16041  /* save current LPI state (basis information) */
16042  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
16044  lp->divelpwasdualfeas = lp->dualfeasible;
16047 
16048  /* save current LP values dependent on the solution */
16049  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
16050  assert(lp->storedsolvals != NULL);
16051  if( !set->lp_resolverestore && lp->solved )
16052  {
16053  SCIP_Bool store = TRUE;
16054 
16055  switch ( lp->lpsolstat )
16056  {
16058  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16059  assert(lp->validsollp == stat->lpcount);
16060  break;
16062  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
16063  assert(lp->validsollp == stat->lpcount);
16064  break;
16068  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16069  assert(lp->validsollp == stat->lpcount);
16070  break;
16072  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
16073  break;
16075  case SCIP_LPSOLSTAT_ERROR:
16076  default:
16077  store = FALSE;
16078  }
16079 
16080  if ( store )
16081  {
16082  for( c = 0; c < lp->ncols; ++c )
16083  {
16084  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
16085  }
16086  for( r = 0; r < lp->nrows; ++r )
16087  {
16089  }
16090  }
16091  }
16092 
16093  /* store LPI iteration limit */
16095 
16096  /* remember the number of domain changes */
16097  lp->divenolddomchgs = stat->domchgcount;
16098 
16099  /* store current number of rows */
16100  lp->ndivingrows = lp->nrows;
16101 
16102  /* switch to diving mode */
16103  lp->diving = TRUE;
16104 
16105  return SCIP_OKAY;
16106 }
16107 
16108 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
16110  SCIP_LP* lp, /**< current LP data */
16111  BMS_BLKMEM* blkmem, /**< block memory */
16112  SCIP_SET* set, /**< global SCIP settings */
16113  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16114  SCIP_STAT* stat, /**< problem statistics */
16115  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16116  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16117  SCIP_PROB* prob, /**< problem data */
16118  SCIP_VAR** vars, /**< array with all active variables */
16119  int nvars /**< number of active variables */
16120  )
16121 {
16122  SCIP_VAR* var;
16123  int v;
16124 
16125  assert(lp != NULL);
16126  assert(lp->diving);
16127  assert(blkmem != NULL);
16128  assert(nvars == 0 || vars != NULL);
16129 
16130  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16131 
16132  /* reset all columns' objective values and bounds to its original values */
16133  for( v = 0; v < nvars; ++v )
16134  {
16135  var = vars[v];
16136  assert(var != NULL);
16138  {
16139  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
16140  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
16141  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
16142  }
16143  }
16144 
16145  /* remove rows which were added in diving mode */
16146  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16147 
16148  /* undo changes to left hand sides and right hand sides */
16149  while( lp->ndivechgsides > 0 )
16150  {
16151  SCIP_Real oldside;
16152  SCIP_SIDETYPE sidetype;
16153  SCIP_ROW* row;
16154 
16155  lp->ndivechgsides--;
16156  oldside = lp->divechgsides[lp->ndivechgsides];
16157  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16158  row = lp->divechgrows[lp->ndivechgsides];
16159 
16160  if( sidetype == SCIP_SIDETYPE_LEFT )
16161  {
16162  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16163  }
16164  else
16165  {
16166  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16167  }
16168  }
16169 
16170  /* restore LPI iteration limit */
16172 
16173  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16174  * happens
16175  */
16176  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lp->divelpistate,
16178  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16179  lp->divelpwasprimfeas = TRUE;
16180  lp->divelpwasdualfeas = TRUE;
16181  lp->divelpwasprimchecked = TRUE;
16182  lp->divelpwasdualchecked = TRUE;
16183  assert(lp->divelpistate == NULL);
16184 
16185  /* switch to standard (non-diving) mode */
16186  lp->diving = FALSE;
16187  lp->divingobjchg = FALSE;
16188 
16189  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16190  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16191  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16192  * the parameter resolverestore to TRUE
16193  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16194  */
16195  assert(lp->storedsolvals != NULL);
16196  if( lp->storedsolvals->lpissolved
16197  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16198  {
16199  SCIP_Bool lperror;
16200 
16201  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
16202  if( lperror )
16203  {
16204  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16205  lp->resolvelperror = TRUE;
16206  }
16211  {
16212  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16213  "LP was not resolved to a sufficient status after diving\n");
16214  lp->resolvelperror = TRUE;
16215  }
16216  }
16217  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16218  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16219  * re-solve as above can lead to a different LP status
16220  */
16221  else
16222  {
16223  int c;
16224  int r;
16225 
16226  /* if there are lazy bounds, remove them from the LP */
16227  if( lp->nlazycols > 0 )
16228  {
16229  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16230  * first resolve LP?
16231  */
16232  SCIP_CALL( updateLazyBounds(lp, set) );
16233  assert(lp->diving == lp->divinglazyapplied);
16234 
16235  /* flush changes to the LP solver */
16236  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
16237  }
16238 
16239  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
16240  SCIPstatIncrement(stat, set, lpcount);
16241 
16242  /* restore LP solution values in lp data, columns and rows */
16243  if( lp->storedsolvals->lpissolved &&
16250  )
16251  {
16252  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16253 
16254  for( c = 0; c < lp->ncols; ++c )
16255  {
16256  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16257  }
16258  for( r = 0; r < lp->nrows; ++r )
16259  {
16260  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16261  }
16262  }
16263  else
16264  {
16265  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16266  }
16267  }
16268 
16269 #ifndef NDEBUG
16270  {
16271  int c;
16272  for( c = 0; c < lp->ncols; ++c )
16273  {
16274  assert(lp->cols[c] != NULL);
16275  assert(lp->cols[c]->var != NULL);
16276  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16277  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16278  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16279  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16280  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16281  }
16282  }
16283 #endif
16284 
16285  return SCIP_OKAY;
16286 }
16287 
16288 #define DIVESTACKGROWFACT 1.5
16289 
16290 /** records a current row side such that any change will be undone after diving */
16292  SCIP_LP* lp, /**< LP data object */
16293  SCIP_ROW* row, /**< row affected by the change */
16294  SCIP_SIDETYPE sidetype /**< side type */
16295  )
16296 {
16297  assert(lp != NULL);
16298  assert(row != NULL);
16299 
16300  if( lp->ndivechgsides == lp->divechgsidessize )
16301  {
16303  }
16304  assert(lp->ndivechgsides < lp->divechgsidessize);
16305 
16306  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16307  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16308  lp->divechgrows[lp->ndivechgsides] = row;
16309  lp->ndivechgsides++;
16310 
16311  return SCIP_OKAY;
16312 }
16313 
16314 /** informs the LP that probing mode was initiated */
16316  SCIP_LP* lp /**< current LP data */
16317  )
16318 {
16319  assert(lp != NULL);
16320  assert(!lp->probing);
16321  assert(!lp->strongbranching);
16322  assert(!lp->strongbranchprobing);
16323 
16324  lp->probing = TRUE;
16325 
16326  return SCIP_OKAY;
16327 }
16328 
16329 /** informs the LP that probing mode was finished */
16331  SCIP_LP* lp /**< current LP data */
16332  )
16333 {
16334  assert(lp != NULL);
16335  assert(lp->probing);
16336  assert(!lp->strongbranching);
16337  assert(!lp->strongbranchprobing);
16338 
16339  lp->probing = FALSE;
16340 
16341  return SCIP_OKAY;
16342 }
16343 
16344 /** informs the LP that the probing mode is now used for strongbranching */
16346  SCIP_LP* lp /**< current LP data */
16347  )
16348 {
16349  assert(lp != NULL);
16350  assert(lp->probing);
16351  assert(!lp->strongbranching);
16352  assert(!lp->strongbranchprobing);
16353 
16354  lp->strongbranchprobing = TRUE;
16355 }
16356 
16357 /** informs the LP that the probing mode is not used for strongbranching anymore */
16359  SCIP_LP* lp /**< current LP data */
16360  )
16361 {
16362  assert(lp != NULL);
16363  assert(lp->probing);
16364  assert(!lp->strongbranching);
16365  assert(lp->strongbranchprobing);
16366 
16367  lp->strongbranchprobing = FALSE;
16368 }
16369 
16370 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16371  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16372  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16373  * we have only left hand sides):
16374  * min{cx | b <= Ax, lb <= x <= ub}
16375  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16376  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16377  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16378  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16379  */
16380 static
16382  SCIP_LP* lp, /**< current LP data */
16383  SCIP_SET* set, /**< global SCIP settings */
16384  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16385  SCIP_Real* bound /**< result of interval arithmetic minimization */
16386  )
16387 {
16388  SCIP_INTERVAL* yinter;
16389  SCIP_INTERVAL b;
16390  SCIP_INTERVAL ytb;
16391  SCIP_INTERVAL prod;
16392  SCIP_INTERVAL diff;
16393  SCIP_INTERVAL x;
16394  SCIP_INTERVAL minprod;
16395  SCIP_INTERVAL a;
16396  SCIP_ROW* row;
16397  SCIP_COL* col;
16398  SCIP_Real y;
16399  SCIP_Real c;
16400  int i;
16401  int j;
16402 
16403  assert(lp != NULL);
16404  assert(lp->solved);
16405  assert(set != NULL);
16406  assert(bound != NULL);
16407 
16408  /* allocate buffer for storing y in interval arithmetic */
16409  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16410 
16411  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16412  SCIPintervalSet(&ytb, 0.0);
16413  for( j = 0; j < lp->nrows; ++j )
16414  {
16415  row = lp->rows[j];
16416  assert(row != NULL);
16417 
16418  y = (usefarkas ? row->dualfarkas : row->dualsol);
16419 
16420  if( SCIPsetIsFeasPositive(set, y) )
16421  {
16422  SCIPintervalSet(&yinter[j], y);
16423  SCIPintervalSet(&b, row->lhs - row->constant);
16424  }
16425  else if( SCIPsetIsFeasNegative(set, y) )
16426  {
16427  SCIPintervalSet(&yinter[j], y);
16428  SCIPintervalSet(&b, row->rhs - row->constant);
16429  }
16430  else
16431  {
16432  SCIPintervalSet(&yinter[j], 0.0);
16433  SCIPintervalSet(&b, 0.0);
16434  }
16435 
16436  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16437  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16438  }
16439 
16440  /* calculate min{(c^T - y^TA)x} */
16441  SCIPintervalSet(&minprod, 0.0);
16442  for( j = 0; j < lp->ncols; ++j )
16443  {
16444  col = lp->cols[j];
16445  assert(col != NULL);
16446  assert(col->nunlinked == 0);
16447 
16449 
16450  c = usefarkas ? 0.0 : col->obj;
16451  SCIPintervalSet(&diff, c);
16452 
16453  for( i = 0; i < col->nlprows; ++i )
16454  {
16455  assert(col->rows[i] != NULL);
16456  assert(col->rows[i]->lppos >= 0);
16457  assert(col->linkpos[i] >= 0);
16458  SCIPintervalSet(&a, col->vals[i]);
16459  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16460  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16461  }
16462 
16463 #ifndef NDEBUG
16464  for( i = col->nlprows; i < col->len; ++i )
16465  {
16466  assert(col->rows[i] != NULL);
16467  assert(col->rows[i]->lppos == -1);
16468  assert(col->rows[i]->dualsol == 0.0);
16469  assert(col->rows[i]->dualfarkas == 0.0);
16470  assert(col->linkpos[i] >= 0);
16471  }
16472 #endif
16473 
16474  SCIPintervalSetBounds(&x, col->lb, col->ub);
16475  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16476  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16477  }
16478 
16479  /* add y^Tb */
16480  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16481 
16482  /* free buffer for storing y in interval arithmetic */
16483  SCIPsetFreeBufferArray(set, &yinter);
16484 
16485  *bound = SCIPintervalGetInf(minprod);
16486 
16487  return SCIP_OKAY;
16488 }
16489 
16490 /** gets proven lower (dual) bound of last LP solution */
16492  SCIP_LP* lp, /**< current LP data */
16493  SCIP_SET* set, /**< global SCIP settings */
16494  SCIP_Real* bound /**< pointer to store proven dual bound */
16495  )
16496 {
16497  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16498 
16499  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16500 
16501  return SCIP_OKAY;
16502 }
16503 
16504 /** gets proven dual bound of last LP solution */
16506  SCIP_LP* lp, /**< current LP data */
16507  SCIP_SET* set, /**< global SCIP settings */
16508  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16509  )
16510 {
16511  SCIP_Real bound;
16512 
16513  assert(proved != NULL);
16514 
16515  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16516 
16517  *proved = (bound > 0.0);
16518 
16519  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16520 
16521  return SCIP_OKAY;
16522 }
16523 
16524 
16525 
16526 /** writes LP to a file */
16528  SCIP_LP* lp, /**< current LP data */
16529  const char* fname /**< file name */
16530  )
16531 {
16532  assert(lp != NULL);
16533  assert(lp->flushed);
16534  assert(fname != NULL);
16535 
16536  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16537 
16538  return SCIP_OKAY;
16539 }
16540 
16541 /** writes MIP relaxation of the current B&B node to a file */
16543  SCIP_LP* lp, /**< current LP data */
16544  SCIP_SET* set, /**< global SCIP settings */
16545  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16546  const char* fname, /**< file name */
16547  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16548  * troubles with reserved symbols? */
16549  SCIP_Bool origobj, /**< should the original objective function be used? */
16550  SCIP_OBJSENSE objsense, /**< objective sense */
16551  SCIP_Real objscale, /**< objective scaling factor */
16552  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16553  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16554  )
16555 {
16556  FILE* file;
16557  int i;
16558  int j;
16559  char rowname[SCIP_MAXSTRLEN];
16560  SCIP_Real coeff;
16561 
16562  assert(lp != NULL);
16563  assert(lp->flushed);
16564  assert(fname != NULL);
16565 
16566  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16567  file = fopen(fname, "w");
16568  if( file == NULL )
16569  {
16570  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16571  SCIPprintSysError(fname);
16572  return SCIP_FILECREATEERROR;
16573  }
16574 
16575  /* print comments */
16576  if( genericnames )
16577  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16578  else
16579  {
16580  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16581  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16582  }
16583 
16584  if( origobj && objoffset != 0.0 )
16585  {
16586  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16587  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16588  }
16589 
16590  /* print objective function */
16591  /**@note the transformed problem in SCIP is always a minimization problem */
16592  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16593  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16594  else
16595  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16596 
16597  /* print objective */
16598  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16599  j = 0;
16600  for( i = 0; i < lp->ncols; ++i )
16601  {
16602  if( lp->cols[i]->obj != 0.0 )
16603  {
16604  coeff = lp->cols[i]->obj;
16605  if( origobj )
16606  {
16607  coeff *= (SCIP_Real) objsense;
16608  coeff *= objscale;
16609  }
16610 
16611  if( genericnames )
16612  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16613  else
16614  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16615 
16616  ++j;
16617  if( j % 10 == 0 )
16618  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16619  }
16620  }
16621  /* add artificial variable 'objoffset' to transfer objective offset */
16622  if( origobj && objoffset != 0.0 )
16623  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16624 
16625  /* print constraint section */
16626  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16627  for( i = 0; i < lp->nrows; i++ )
16628  {
16629  char type = 'i';
16630 
16631  /* skip removable rows if we want to write them as lazy constraints */
16632  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16633  continue;
16634 
16635  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16636  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16637  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16638  * type 'i' means: lhs and rhs are both infinite */
16639  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16640  type = 'r';
16641  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16642  type = 'l';
16643  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16644  type = 'e';
16645  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16646  type = 'b';
16647 
16648  /* print name of row */
16649  if( genericnames )
16650  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16651  else
16652  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16653 
16654  WRITEROW:
16655  switch( type )
16656  {
16657  case 'r':
16658  case 'l':
16659  case 'e':
16660  if( strlen(rowname) > 0 )
16661  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16662  break;
16663  case 'i':
16664  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16665  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16666  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16667  type = 'b';
16668  /*lint -fallthrough*/
16669  case 'b':
16670  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16671  break;
16672  default:
16673  assert(type == 'B');
16674  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16675  break;
16676  }
16677 
16678  /* print coefficients and variables */
16679  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16680  {
16681  if( genericnames )
16682  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16683  else
16684  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16685 
16686  if( (j+1) % 10 == 0 )
16687  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16688  }
16689 
16690  /* print right hand side */
16691  switch( type )
16692  {
16693  case 'b':
16694  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16695  type = 'B';
16696  goto WRITEROW;
16697  case 'l':
16698  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16699  break;
16700  case 'B':
16701  case 'r':
16702  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16703  break;
16704  case 'e':
16705  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16706  break;
16707  default:
16708  SCIPerrorMessage("Undefined row type!\n");
16709  fclose(file);
16710  return SCIP_ERROR;
16711  }
16712  }
16713 
16714  if ( lazyconss )
16715  {
16716  /* print lazy constraint section */
16717  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16718  for( i = 0; i < lp->nrows; i++ )
16719  {
16720  char type = 'i';
16721 
16722  /* skip non-removable rows if we want to write lazy constraints */
16723  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16724  continue;
16725 
16726  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16727  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16728  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16729  * type 'i' means: lhs and rhs are both infinite */
16730  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16731  type = 'r';
16732  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16733  type = 'l';
16734  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16735  type = 'e';
16736  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16737  type = 'b';
16738 
16739  /* print name of row */
16740  if( genericnames )
16741  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16742  else
16743  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16744 
16745  WRITELAZYROW:
16746  switch( type )
16747  {
16748  case 'r':
16749  case 'l':
16750  case 'e':
16751  if( strlen(rowname) > 0 )
16752  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16753  break;
16754  case 'i':
16755  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16756  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16757  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16758  type = 'b';
16759  /*lint -fallthrough*/
16760  case 'b':
16761  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16762  break;
16763  default:
16764  assert(type == 'B');
16765  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16766  break;
16767  }
16768 
16769  /* print coefficients and variables */
16770  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16771  {
16772  if( genericnames )
16773  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16774  else
16775  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16776 
16777  if( (j+1) % 10 == 0 )
16778  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16779  }
16780 
16781  /* print right hand side */
16782  switch( type )
16783  {
16784  case 'b':
16785  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16786  type = 'B';
16787  goto WRITELAZYROW;
16788  case 'l':
16789  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16790  break;
16791  case 'B':
16792  case 'r':
16793  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16794  break;
16795  case 'e':
16796  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16797  break;
16798  default:
16799  SCIPerrorMessage("Undefined row type!\n");
16800  fclose(file);
16801  return SCIP_ERROR;
16802  }
16803  }
16804  }
16805 
16806  /* print variable bounds */
16807  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16808  for( i = 0; i < lp->ncols; ++i )
16809  {
16810  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16811  {
16812  /* print lower bound as far this one is not infinity */
16813  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16814  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16815 
16816  /* print variable name */
16817  if( genericnames )
16818  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16819  else
16820  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16821 
16822  /* print upper bound as far this one is not infinity */
16823  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16824  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16825  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16826  }
16827  }
16828  if( origobj && objoffset != 0.0 )
16829  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16830 
16831  /* print integer variables */
16832  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16833  j = 0;
16834  for( i = 0; i < lp->ncols; ++i )
16835  {
16836  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16837  {
16838  /* print variable name */
16839  if( genericnames )
16840  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16841  else
16842  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16843 
16844  j++;
16845  if( j % 10 == 0 )
16846  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16847  }
16848  }
16849 
16850  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16851  fclose(file);
16852 
16853  return SCIP_OKAY;
16854 }
16855 
16856 /*
16857  * simple functions implemented as defines
16858  */
16859 
16860 /* In debug mode, the following methods are implemented as function calls to ensure
16861  * type validity.
16862  * In optimized mode, the methods are implemented as defines to improve performance.
16863  * However, we want to have them in the library anyways, so we have to undef the defines.
16864  */
16865 
16866 #undef SCIPcolGetObj
16867 #undef SCIPcolGetLb
16868 #undef SCIPcolGetUb
16869 #undef SCIPcolGetBestBound
16870 #undef SCIPcolGetPrimsol
16871 #undef SCIPcolGetMinPrimsol
16872 #undef SCIPcolGetMaxPrimsol
16873 #undef SCIPcolGetBasisStatus
16874 #undef SCIPcolGetVar
16875 #undef SCIPcolGetIndex
16876 #undef SCIPcolGetVarProbindex
16877 #undef SCIPcolIsIntegral
16878 #undef SCIPcolIsRemovable
16879 #undef SCIPcolGetLPPos
16880 #undef SCIPcolGetLPDepth
16881 #undef SCIPcolIsInLP
16882 #undef SCIPcolGetNNonz
16883 #undef SCIPcolGetNLPNonz
16884 #undef SCIPcolGetRows
16885 #undef SCIPcolGetVals
16886 #undef SCIPcolGetStrongbranchNode
16887 #undef SCIPcolGetNStrongbranchs
16888 #undef SCIPcolGetAge
16889 #undef SCIPboundtypeOpposite
16890 #undef SCIProwGetNNonz
16891 #undef SCIProwGetNLPNonz
16892 #undef SCIProwGetCols
16893 #undef SCIProwGetVals
16894 #undef SCIProwGetConstant
16895 #undef SCIProwGetNorm
16896 #undef SCIProwGetSumNorm
16897 #undef SCIProwGetLhs
16898 #undef SCIProwGetRhs
16899 #undef SCIProwGetDualsol
16900 #undef SCIProwGetDualfarkas
16901 #undef SCIProwGetBasisStatus
16902 #undef SCIProwGetName
16903 #undef SCIProwGetIndex
16904 #undef SCIProwGetAge
16905 #undef SCIProwGetRank
16906 #undef SCIProwIsIntegral
16907 #undef SCIProwIsLocal
16908 #undef SCIProwIsModifiable
16909 #undef SCIProwIsRemovable
16910 #undef SCIProwGetOrigintype
16911 #undef SCIProwGetOriginCons
16912 #undef SCIProwGetOriginConshdlr
16913 #undef SCIProwGetOriginSepa
16914 #undef SCIProwIsInGlobalCutpool
16915 #undef SCIProwGetLPPos
16916 #undef SCIProwGetLPDepth
16917 #undef SCIProwIsInLP
16918 #undef SCIProwGetActiveLPCount
16919 #undef SCIProwGetNLPsAfterCreation
16920 #undef SCIProwChgRank
16921 #undef SCIPlpGetCols
16922 #undef SCIPlpGetNCols
16923 #undef SCIPlpGetRows
16924 #undef SCIPlpGetNRows
16925 #undef SCIPlpGetNewcols
16926 #undef SCIPlpGetNNewcols
16927 #undef SCIPlpGetNewrows
16928 #undef SCIPlpGetNNewrows
16929 #undef SCIPlpGetObjNorm
16930 #undef SCIPlpGetRootObjval
16931 #undef SCIPlpGetRootColumnObjval
16932 #undef SCIPlpGetRootLooseObjval
16933 #undef SCIPlpGetLPI
16934 #undef SCIPlpSetIsRelax
16935 #undef SCIPlpIsRelax
16936 #undef SCIPlpIsSolved
16937 #undef SCIPlpIsSolBasic
16938 #undef SCIPlpDiving
16939 #undef SCIPlpDivingObjChanged
16940 #undef SCIPlpMarkDivingObjChanged
16941 #undef SCIPlpUnmarkDivingObjChanged
16942 #undef SCIPlpDivingRowsChanged
16943 #undef SCIPlpIsFeasEQ
16944 #undef SCIPlpIsFeasLT
16945 #undef SCIPlpIsFeasLE
16946 #undef SCIPlpIsFeasGT
16947 #undef SCIPlpIsFeasGE
16948 #undef SCIPlpIsFeasZero
16949 #undef SCIPlpIsFeasPositive
16950 #undef SCIPlpIsFeasNegative
16951 
16952 /** gets objective value of column */
16954  SCIP_COL* col /**< LP column */
16955  )
16956 {
16957  assert(col != NULL);
16958 
16959  return col->obj;
16960 }
16961 
16962 /** gets lower bound of column */
16964  SCIP_COL* col /**< LP column */
16965  )
16966 {
16967  assert(col != NULL);
16968 
16969  return col->lb;
16970 }
16971 
16972 /** gets upper bound of column */
16974  SCIP_COL* col /**< LP column */
16975  )
16976 {
16977  assert(col != NULL);
16978 
16979  return col->ub;
16980 }
16981 
16982 /** gets best bound of column with respect to the objective function */
16984  SCIP_COL* col /**< LP column */
16985  )
16986 {
16987  assert(col != NULL);
16988 
16989  if( col->obj >= 0.0 )
16990  return col->lb;
16991  else
16992  return col->ub;
16993 }
16994 
16995 /** gets the primal LP solution of a column */
16997  SCIP_COL* col /**< LP column */
16998  )
16999 {
17000  assert(col != NULL);
17001 
17002  if( col->lppos >= 0 )
17003  return col->primsol;
17004  else
17005  return 0.0;
17006 }
17007 
17008 /** gets the minimal LP solution value, this column ever assumed */
17010  SCIP_COL* col /**< LP column */
17011  )
17012 {
17013  assert(col != NULL);
17014 
17015  return col->minprimsol;
17016 }
17017 
17018 /** gets the maximal LP solution value, this column ever assumed */
17020  SCIP_COL* col /**< LP column */
17021  )
17022 {
17023  assert(col != NULL);
17024 
17025  return col->maxprimsol;
17026 }
17027 
17028 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17029  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
17030  */
17032  SCIP_COL* col /**< LP column */
17033  )
17034 {
17035  assert(col != NULL);
17036  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
17037 
17038  return (SCIP_BASESTAT)col->basisstatus;
17039 }
17040 
17041 /** gets variable this column represents */
17043  SCIP_COL* col /**< LP column */
17044  )
17045 {
17046  assert(col != NULL);
17047 
17048  return col->var;
17049 }
17050 
17051 /** gets unique index of col */
17053  SCIP_COL* col /**< LP col */
17054  )
17055 {
17056  assert(col != NULL);
17057 
17058  return col->index;
17059 }
17060 
17061 /** gets probindex of corresponding variable */
17063  SCIP_COL* col /**< LP col */
17064  )
17065 {
17066  assert(col != NULL);
17067 
17068  return col->var_probindex;
17069 }
17070 
17071 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
17073  SCIP_COL* col /**< LP column */
17074  )
17075 {
17076  assert(col != NULL);
17077  assert(SCIPvarIsIntegral(col->var) == col->integral);
17078 
17079  return col->integral;
17080 }
17081 
17082 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
17084  SCIP_COL* col /**< LP column */
17085  )
17086 {
17087  assert(col != NULL);
17088 
17089  return col->removable;
17090 }
17091 
17092 /** gets position of column in current LP, or -1 if it is not in LP */
17094  SCIP_COL* col /**< LP column */
17095  )
17096 {
17097  assert(col != NULL);
17098  assert((col->lppos == -1) == (col->lpdepth == -1));
17099 
17100  return col->lppos;
17101 }
17102 
17103 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
17105  SCIP_COL* col /**< LP column */
17106  )
17107 {
17108  assert(col != NULL);
17109  assert((col->lppos == -1) == (col->lpdepth == -1));
17110 
17111  return col->lpdepth;
17112 }
17113 
17114 /** returns TRUE iff column is member of current LP */
17116  SCIP_COL* col /**< LP column */
17117  )
17118 {
17119  assert(col != NULL);
17120  assert((col->lppos == -1) == (col->lpdepth == -1));
17121 
17122  return (col->lppos >= 0);
17123 }
17124 
17125 /** get number of nonzero entries in column vector */
17127  SCIP_COL* col /**< LP column */
17128  )
17129 {
17130  assert(col != NULL);
17131 
17132  return col->len;
17133 }
17134 
17135 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
17136  *
17137  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17138  * 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
17139  */
17141  SCIP_COL* col /**< LP column */
17142  )
17143 {
17144  assert(col != NULL);
17145  assert(col->nunlinked == 0);
17146 
17147  return col->nlprows;
17148 }
17149 
17150 /** gets array with rows of nonzero entries */
17152  SCIP_COL* col /**< LP column */
17153  )
17154 {
17155  assert(col != NULL);
17156 
17157  return col->rows;
17158 }
17159 
17160 /** gets array with coefficients of nonzero entries */
17162  SCIP_COL* col /**< LP column */
17163  )
17164 {
17165  assert(col != NULL);
17166 
17167  return col->vals;
17168 }
17169 
17170 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
17171  * given column, or -1 if strong branching was never applied to the column in current run
17172  */
17174  SCIP_COL* col /**< LP column */
17175  )
17176 {
17177  assert(col != NULL);
17178 
17179  return col->sbnode;
17180 }
17181 
17182 /** gets number of times, strong branching was applied in current run on the given column */
17184  SCIP_COL* col /**< LP column */
17185  )
17186 {
17187  assert(col != NULL);
17188 
17189  return col->nsbcalls;
17190 }
17191 
17192 /** 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 */
17194  SCIP_COL* col /**< LP column */
17195  )
17196 {
17197  assert(col != NULL);
17198 
17199  return col->age;
17200 }
17201 
17202 /** gets opposite bound type of given bound type */
17204  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17205  )
17206 {
17207  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17208 
17210 }
17211 
17212 /** get number of nonzero entries in row vector */
17214  SCIP_ROW* row /**< LP row */
17215  )
17216 {
17217  assert(row != NULL);
17218 
17219  return row->len;
17220 }
17221 
17222 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17223  *
17224  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17225  * 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
17226  */
17228  SCIP_ROW* row /**< LP row */
17229  )
17230 {
17231  assert(row != NULL);
17232  assert(row->nunlinked == 0);
17233 
17234  return row->nlpcols;
17235 }
17236 
17237 /** gets array with columns of nonzero entries */
17239  SCIP_ROW* row /**< LP row */
17240  )
17241 {
17242  assert(row != NULL);
17243 
17244  return row->cols;
17245 }
17246 
17247 /** gets array with coefficients of nonzero entries */
17249  SCIP_ROW* row /**< LP row */
17250  )
17251 {
17252  assert(row != NULL);
17253 
17254  return row->vals;
17255 }
17256 
17257 /** gets constant shift of row */
17259  SCIP_ROW* row /**< LP row */
17260  )
17261 {
17262  assert(row != NULL);
17263 
17264  return row->constant;
17265 }
17266 
17267 /** gets Euclidean norm of row vector */
17269  SCIP_ROW* row /**< LP row */
17270  )
17271 {
17272  assert(row != NULL);
17273 
17274  checkRowSqrnorm(row);
17275 
17276  return sqrt(row->sqrnorm);
17277 }
17278 
17279 /** gets sum norm of row vector (sum of absolute values of coefficients) */
17281  SCIP_ROW* row /**< LP row */
17282  )
17283 {
17284  assert(row != NULL);
17285 
17286  checkRowSumnorm(row);
17287 
17288  return row->sumnorm;
17289 }
17290 
17291 /** returns the left hand side of the row */
17293  SCIP_ROW* row /**< LP row */
17294  )
17295 {
17296  assert(row != NULL);
17297 
17298  return row->lhs;
17299 }
17300 
17301 /** returns the right hand side of the row */
17303  SCIP_ROW* row /**< LP row */
17304  )
17305 {
17306  assert(row != NULL);
17307 
17308  return row->rhs;
17309 }
17310 
17311 /** gets the dual LP solution of a row */
17313  SCIP_ROW* row /**< LP row */
17314  )
17315 {
17316  assert(row != NULL);
17317 
17318  if( row->lppos >= 0 )
17319  return row->dualsol;
17320  else
17321  return 0.0;
17322 }
17323 
17324 /** gets the dual Farkas coefficient of a row in an infeasible LP */
17326  SCIP_ROW* row /**< LP row */
17327  )
17328 {
17329  assert(row != NULL);
17330 
17331  if( row->lppos >= 0 )
17332  return row->dualfarkas;
17333  else
17334  return 0.0;
17335 }
17336 
17337 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17338  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17339  */
17341  SCIP_ROW* row /**< LP row */
17342  )
17343 {
17344  assert(row != NULL);
17345  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17346 
17347  return (SCIP_BASESTAT)row->basisstatus;
17348 }
17349 
17350 /** returns the name of the row */
17351 const char* SCIProwGetName(
17352  SCIP_ROW* row /**< LP row */
17353  )
17354 {
17355  assert(row != NULL);
17356 
17357  return row->name;
17358 }
17359 
17360 /** gets unique index of row */
17362  SCIP_ROW* row /**< LP row */
17363  )
17364 {
17365  assert(row != NULL);
17366 
17367  return row->index;
17368 }
17369 
17370 /** gets age of row */
17372  SCIP_ROW* row /**< LP row */
17373  )
17374 {
17375  assert(row != NULL);
17376 
17377  return row->age;
17378 }
17379 
17380 /** gets rank of row */
17382  SCIP_ROW* row /**< LP row */
17383  )
17384 {
17385  assert(row != NULL);
17386 
17387  return row->rank;
17388 }
17389 
17390 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17392  SCIP_ROW* row /**< LP row */
17393  )
17394 {
17395  assert(row != NULL);
17396 
17397  return row->integral;
17398 }
17399 
17400 /** returns TRUE iff row is only valid locally */
17402  SCIP_ROW* row /**< LP row */
17403  )
17404 {
17405  assert(row != NULL);
17406 
17407  return row->local;
17408 }
17409 
17410 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17412  SCIP_ROW* row /**< LP row */
17413  )
17414 {
17415  assert(row != NULL);
17416 
17417  return row->modifiable;
17418 }
17419 
17420 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17422  SCIP_ROW* row /**< LP row */
17423  )
17424 {
17425  assert(row != NULL);
17426 
17427  return row->removable;
17428 }
17429 
17430 /** returns type of origin that created the row */
17432  SCIP_ROW* row /**< LP row */
17433  )
17434 {
17435  assert( row != NULL );
17436 
17437  return (SCIP_ROWORIGINTYPE) row->origintype;
17438 }
17439 
17440 /** returns origin constraint that created the row (NULL if not available) */
17442  SCIP_ROW* row /**< LP row */
17443  )
17444 {
17445  assert( row != NULL );
17446 
17448  {
17449  assert( row->origin != NULL );
17450  return (SCIP_CONS*) row->origin;
17451  }
17452  return NULL;
17453 }
17454 
17455 /** returns origin constraint handler that created the row (NULL if not available) */
17457  SCIP_ROW* row /**< LP row */
17458  )
17459 {
17460  assert( row != NULL );
17461 
17463  {
17464  assert( row->origin != NULL );
17465  return (SCIP_CONSHDLR*) row->origin;
17466  }
17468  {
17469  assert(row->origin != NULL);
17470  return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17471  }
17472  return NULL;
17473 }
17474 
17475 /** returns origin separator that created the row (NULL if not available) */
17477  SCIP_ROW* row /**< LP row */
17478  )
17479 {
17480  assert( row != NULL );
17481 
17483  {
17484  assert( row->origin != NULL );
17485  return (SCIP_SEPA*) row->origin;
17486  }
17487  return NULL;
17488 }
17489 
17490 /** returns TRUE iff row is member of the global cut pool */
17492  SCIP_ROW* row /**< LP row */
17493  )
17494 {
17495  assert(row != NULL);
17496 
17497  return row->inglobalcutpool;
17498 }
17499 
17500 /** gets position of row in current LP, or -1 if it is not in LP */
17502  SCIP_ROW* row /**< LP row */
17503  )
17504 {
17505  assert(row != NULL);
17506  assert((row->lppos == -1) == (row->lpdepth == -1));
17507 
17508  return row->lppos;
17509 }
17510 
17511 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17513  SCIP_ROW* row /**< LP row */
17514  )
17515 {
17516  assert(row != NULL);
17517  assert((row->lppos == -1) == (row->lpdepth == -1));
17518 
17519  return row->lpdepth;
17520 }
17521 
17522 /** returns TRUE iff row is member of current LP */
17524  SCIP_ROW* row /**< LP row */
17525  )
17526 {
17527  assert(row != NULL);
17528  assert((row->lppos == -1) == (row->lpdepth == -1));
17529 
17530  return (row->lppos >= 0);
17531 }
17532 
17533 /** changes the rank of LP row */
17535  SCIP_ROW* row, /**< LP row */
17536  int rank /**< new value for rank */
17537  )
17538 {
17539  assert(row != NULL);
17540 
17541  row->rank = rank;
17542 }
17543 
17544 /** returns the number of times that this row has been sharp in an optimal LP solution */
17546  SCIP_ROW* row /**< row */
17547  )
17548 {
17549  assert(row != NULL);
17550 
17551  return row->activeinlpcounter;
17552 }
17553 
17554 /** returns the number of LPs since this row has been created */
17556  SCIP_ROW* row /**< row */
17557  )
17558 {
17559  assert(row != NULL);
17560 
17561  return row->nlpsaftercreation;
17562 }
17563 
17564 /** gets array with columns of the LP */
17566  SCIP_LP* lp /**< current LP data */
17567  )
17568 {
17569  assert(lp != NULL);
17570 
17571  return lp->cols;
17572 }
17573 
17574 /** gets current number of columns in LP */
17576  SCIP_LP* lp /**< current LP data */
17577  )
17578 {
17579  assert(lp != NULL);
17580 
17581  return lp->ncols;
17582 }
17583 
17584 /** gets current number of unfixed columns in LP */
17586  SCIP_LP* lp, /**< current LP data */
17587  SCIP_Real eps /**< numerical tolerance */
17588  )
17589 {
17590  SCIP_COL** lpcols;
17591  int nlpcols;
17592  int nunfixedcols;
17593  int c;
17594 
17595  assert(lp != NULL);
17596  assert(eps > 0.0);
17597 
17598  lpcols = lp->cols;
17599  nlpcols = lp->ncols;
17600 
17601  nunfixedcols = 0;
17602  for( c = 0; c < nlpcols; ++c )
17603  {
17604  if( lpcols[c]->ub - lpcols[c]->lb > eps )
17605  ++nunfixedcols;
17606  }
17607 
17608  return nunfixedcols;
17609 }
17610 
17611 /** gets array with rows of the LP */
17613  SCIP_LP* lp /**< current LP data */
17614  )
17615 {
17616  assert(lp != NULL);
17617 
17618  return lp->rows;
17619 }
17620 
17621 /** gets current number of rows in LP */
17623  SCIP_LP* lp /**< current LP data */
17624  )
17625 {
17626  assert(lp != NULL);
17627 
17628  return lp->nrows;
17629 }
17630 
17631 /** gets array with newly added columns after the last mark */
17633  SCIP_LP* lp /**< current LP data */
17634  )
17635 {
17636  assert(lp != NULL);
17637  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17638 
17639  return &(lp->cols[lp->firstnewcol]);
17640 }
17641 
17642 /** gets number of newly added columns after the last mark */
17644  SCIP_LP* lp /**< current LP data */
17645  )
17646 {
17647  assert(lp != NULL);
17648  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17649 
17650  return lp->ncols - lp->firstnewcol;
17651 }
17652 
17653 /** gets array with newly added rows after the last mark */
17655  SCIP_LP* lp /**< current LP data */
17656  )
17657 {
17658  assert(lp != NULL);
17659  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17660 
17661  return &(lp->rows[lp->firstnewrow]);
17662 }
17663 
17664 /** gets number of newly added rows after the last mark */
17666  SCIP_LP* lp /**< current LP data */
17667  )
17668 {
17669  assert(lp != NULL);
17670  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17671 
17672  return lp->nrows - lp->firstnewrow;
17673 }
17674 
17675 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17677  SCIP_SET* set, /**< global SCIP settings */
17678  SCIP_LP* lp /**< LP data */
17679  )
17680 {
17681  if( lp->objsqrnormunreliable )
17682  {
17683  SCIP_COL** cols;
17684  int c;
17685 
17686  cols = lp->cols;
17687  assert(cols != NULL || lp->ncols == 0);
17688 
17689  lp->objsqrnorm = 0.0;
17690 
17691  for( c = lp->ncols - 1; c >= 0; --c )
17692  {
17693  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17694  }
17695  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17696 
17697  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17698  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17699 
17701  }
17702  return;
17703 }
17704 
17705 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17706  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17708  SCIP_LP* lp /**< LP data */
17709  )
17710 {
17711  assert(lp != NULL);
17712  assert(!lp->objsqrnormunreliable);
17713  assert(lp->objsqrnorm >= 0.0);
17714 
17715  return sqrt(lp->objsqrnorm);
17716 }
17717 
17718 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17720  SCIP_LP* lp, /**< LP data */
17721  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17722  )
17723 {
17724  assert(lp != NULL);
17725 
17726  lp->rootlpisrelax = isrelax;
17727 }
17728 
17729 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17731  SCIP_LP* lp /**< LP data */
17732  )
17733 {
17734  assert(lp != NULL);
17735 
17736  return lp->rootlpisrelax;
17737 }
17738 
17739 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17741  SCIP_LP* lp /**< LP data */
17742  )
17743 {
17744  assert(lp != NULL);
17745 
17746  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17747 }
17748 
17749 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17750  * returns SCIP_INVALID if the root node LP was not (yet) solved
17751  */
17753  SCIP_LP* lp /**< LP data */
17754  )
17755 {
17756  assert(lp != NULL);
17757 
17758  return lp->rootlpobjval;
17759 }
17760 
17761 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17762  * returns SCIP_INVALID if the root node LP was not (yet) solved
17763  */
17765  SCIP_LP* lp /**< LP data */
17766  )
17767 {
17768  assert(lp != NULL);
17769 
17770  return lp->rootlooseobjval;
17771 }
17772 
17773 /** gets the LP solver interface */
17775  SCIP_LP* lp /**< current LP data */
17776  )
17777 {
17778  assert(lp != NULL);
17779 
17780  return lp->lpi;
17781 }
17782 
17783 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17785  SCIP_LP* lp, /**< LP data */
17786  SCIP_Bool relax /**< is the current lp a relaxation? */
17787  )
17788 {
17789  assert(lp != NULL);
17790 
17791  lp->isrelax = relax;
17792 }
17793 
17794 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17795  * solution value a valid local lower bound?
17796  */
17798  SCIP_LP* lp /**< LP data */
17799  )
17800 {
17801  assert(lp != NULL);
17802 
17803  return lp->isrelax;
17804 }
17805 
17806 /** returns whether the current LP is flushed and solved */
17808  SCIP_LP* lp /**< current LP data */
17809  )
17810 {
17811  assert(lp != NULL);
17812 
17813  return lp->flushed && lp->solved;
17814 }
17815 
17816 /** return whether the current LP solution passed the primal feasibility check */
17818  SCIP_LP* lp /**< current LP data */
17819  )
17820 {
17821  assert(lp != NULL);
17822 
17823  return (lp->primalchecked && lp->primalfeasible);
17824 }
17825 
17826 /** return whether the current LP solution passed the dual feasibility check */
17828  SCIP_LP* lp /**< current LP data */
17829  )
17830 {
17831  assert(lp != NULL);
17832 
17833  return (lp->dualchecked && lp->dualfeasible);
17834 }
17835 
17836 /** returns whether the current LP solution is a basic solution */
17838  SCIP_LP* lp /**< current LP data */
17839  )
17840 {
17841  assert(lp != NULL);
17842 
17843  return lp->solisbasic;
17844 }
17845 
17846 /** returns whether the LP is in diving mode */
17848  SCIP_LP* lp /**< current LP data */
17849  )
17850 {
17851  assert(lp != NULL);
17852 
17853  return lp->diving;
17854 }
17855 
17856 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17858  SCIP_LP* lp /**< current LP data */
17859  )
17860 {
17861  assert(lp != NULL);
17862 
17863  return lp->divingobjchg;
17864 }
17865 
17866 /** marks the diving LP to have a changed objective function */
17868  SCIP_LP* lp /**< current LP data */
17869  )
17870 {
17871  assert(lp != NULL);
17872  assert(lp->diving || lp->probing);
17873 
17874  lp->divingobjchg = TRUE;
17875 }
17876 
17877 /** marks the diving LP to not have a changed objective function anymore */
17879  SCIP_LP* lp /**< current LP data */
17880  )
17881 {
17882  assert(lp != NULL);
17883  assert(lp->diving || lp->probing);
17884 
17885  lp->divingobjchg = FALSE;
17886 }
17887 
17888 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17890  SCIP_LP* lp /**< current LP data */
17891  )
17892 {
17893  assert(lp != NULL);
17894  assert(lp->diving || lp->ndivechgsides == 0);
17895 
17896  return (lp->ndivechgsides > 0);
17897 }
17898 
17899 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17900 static
17902  SCIP_LPI* lpi, /**< auxiliary LP interface */
17903  SCIP_SET* set, /**< global SCIP settings */
17904  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17905  SCIP_LP* lp, /**< LP data */
17906  SCIP_PROB* prob, /**< problem data */
17907  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17908  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17909  SCIP_Real timelimit, /**< time limit for LP solver */
17910  int iterlimit, /**< iteration limit for LP solver */
17911  SCIP_Real* point, /**< array to store relative interior point on exit */
17912  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17913  )
17914 {
17915  SCIP_RETCODE retcode;
17916  SCIP_Real* primal;
17917  SCIP_Real* obj;
17918  SCIP_Real* lb;
17919  SCIP_Real* ub;
17920  SCIP_Real* matvals;
17921  SCIP_Real* matlhs;
17922  SCIP_Real* matrhs;
17923  SCIP_Real objval;
17924  SCIP_Real alpha;
17925  int* matinds;
17926  int* matbeg;
17927 #ifndef NDEBUG
17928  int nslacks;
17929 #endif
17930  int nnewcols;
17931  int ntotnonz = 0;
17932  int ntotrows = 0;
17933  int matrowidx;
17934  int matidx;
17935  int cnt;
17936  int j;
17937  int i;
17938 
17939  assert(lpi != NULL);
17940 
17941  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
17942  if( retcode != SCIP_OKAY )
17943  {
17944  /* stop execution on error, since result is likely to be unsuable */
17945  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17946  return SCIP_LPERROR;
17947  }
17948 
17950  if( retcode != SCIP_OKAY )
17951  {
17952  /* stop execution on error, since result is likely to be unsuable */
17953  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17954  return SCIP_LPERROR;
17955  }
17956 
17957  /* get storage */
17958  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17959  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17960  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17961  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17962 
17963  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17964  for( j = 0; j < lp->ncols; ++j )
17965  {
17966  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17967  obj[j] = 0.0;
17968  lb[j] = -SCIPlpiInfinity(lpi);
17969  ub[j] = SCIPlpiInfinity(lpi);
17970  /* note: we could also use the original bounds - free variables seem to be faster. */
17971  }
17972 
17973  /* add artificial alpha variable */
17974  nnewcols = lp->ncols;
17975  obj[nnewcols] = 0.0;
17976  lb[nnewcols] = 1.0;
17977  ub[nnewcols] = SCIPlpiInfinity(lpi);
17978  ++nnewcols;
17979 
17980  /* create slacks for rows */
17981  for( i = 0; i < lp->nrows; ++i )
17982  {
17983  SCIP_ROW* row;
17984 
17985  row = lp->rows[i];
17986  assert( row != NULL );
17987 
17988  if( SCIProwIsModifiable(row) )
17989  continue;
17990 
17991  /* make sure row is sorted */
17992  rowSortLP(row);
17993  assert( row->lpcolssorted );
17994 
17995  /* check whether we have an equation */
17996  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17997  {
17998  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17999  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
18000  ntotnonz += row->nlpcols + 1;
18001  ++ntotrows;
18002  }
18003  else
18004  {
18005  /* otherwise add slacks for each side if necessary */
18006  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
18007  {
18008  if ( relaxrows )
18009  {
18010  lb[nnewcols] = 0.0;
18011  ub[nnewcols] = 1.0;
18012  obj[nnewcols++] = 1.0;
18013  ntotnonz += row->nlpcols + 2;
18014  }
18015  else
18016  ntotnonz += row->nlpcols + 1;
18017  ++ntotrows;
18018  }
18019  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
18020  {
18021  if ( relaxrows )
18022  {
18023  lb[nnewcols] = 0.0;
18024  ub[nnewcols] = 1.0;
18025  obj[nnewcols++] = 1.0;
18026  ntotnonz += row->nlpcols + 2;
18027  }
18028  else
18029  ntotnonz += row->nlpcols + 1;
18030  ++ntotrows;
18031  }
18032  }
18033  }
18034 
18035  /* create slacks for objective cutoff row */
18036  if( inclobjcutoff && relaxrows )
18037  {
18038  /* add slacks for right hand side */
18039  lb[nnewcols] = 0.0;
18040  ub[nnewcols] = 1.0;
18041  obj[nnewcols++] = 1.0;
18042  ntotnonz += lp->ncols + 2;
18043  ++ntotrows;
18044  }
18045 
18046  /* create slacks for bounds */
18047  for( j = 0; j < lp->ncols; ++j )
18048  {
18049  SCIP_COL* col;
18050 
18051  col = lp->cols[j];
18052  assert( col != NULL );
18053 
18054  /* no slacks for fixed variables */
18055  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18056  {
18057  ++ntotrows;
18058  ntotnonz += 2;
18059  }
18060  else
18061  {
18062  /* add slacks for each bound if necessary */
18063  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
18064  {
18065  lb[nnewcols] = 0.0;
18066  ub[nnewcols] = 1.0;
18067  obj[nnewcols++] = 1.0;
18068  ntotnonz += 3;
18069  ++ntotrows;
18070  }
18071  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
18072  {
18073  lb[nnewcols] = 0.0;
18074  ub[nnewcols] = 1.0;
18075  obj[nnewcols++] = 1.0;
18076  ntotnonz += 3;
18077  ++ntotrows;
18078  }
18079  }
18080  }
18081 #ifndef NDEBUG
18082  nslacks = nnewcols - lp->ncols - 1;
18083  assert( nslacks >= 0 );
18084  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
18085 #endif
18086 
18087  /* add columns */
18088  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
18089 
18090  /* free storage */
18091  SCIPsetFreeBufferArray(set, &obj);
18092  SCIPsetFreeBufferArray(set, &ub);
18093  SCIPsetFreeBufferArray(set, &lb);
18094 
18095  /* prepare storage for rows */
18096  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
18097  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
18098  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
18099  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
18100  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
18101 
18102  /* create rows arising from original rows */
18103  cnt = 0;
18104  matrowidx = 0;
18105  matidx = 0;
18106  for( i = 0; i < lp->nrows; ++i )
18107  {
18108  SCIP_ROW* row;
18109  SCIP_COL** rowcols;
18110  SCIP_Real* rowvals;
18111  SCIP_Real lhs;
18112  SCIP_Real rhs;
18113  int nnonz;
18114 
18115  row = lp->rows[i];
18116  assert( row != NULL );
18117 
18118  if( SCIProwIsModifiable(row) )
18119  continue;
18120  assert( row->lpcolssorted );
18121 
18122  /* get row data */
18123  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18124  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18125  nnonz = row->nlpcols;
18126  assert( nnonz <= lp->ncols );
18127  rowcols = row->cols;
18128  rowvals = row->vals;
18129 
18130  /* if we have an equation */
18131  if( SCIPsetIsEQ(set, lhs, rhs) )
18132  {
18133  /* set up indices */
18134  matbeg[matrowidx] = matidx;
18135  for( j = 0; j < nnonz; ++j )
18136  {
18137  assert( rowcols[j] != NULL );
18138  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18139  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18140  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18141  matinds[matidx] = rowcols[j]->lppos;
18142  matvals[matidx++] = rowvals[j];
18143  assert( matidx <= ntotnonz );
18144  }
18145 
18146  /* add artificial variable */
18147  if ( ! SCIPsetIsZero(set, rhs) )
18148  {
18149  matinds[matidx] = lp->ncols;
18150  matvals[matidx++] = -rhs;
18151  assert( matidx <= ntotnonz );
18152  }
18153 
18154  matlhs[matrowidx] = 0.0;
18155  matrhs[matrowidx++] = 0.0;
18156  assert( matrowidx <= ntotrows );
18157  }
18158  else
18159  {
18160  SCIP_Real abslhs = REALABS(lhs);
18161  SCIP_Real absrhs = REALABS(rhs);
18162 
18163  assert(!SCIPsetIsEQ(set, lhs, rhs));
18164 
18165  /* treat lhs */
18166  if( !SCIPsetIsInfinity(set, abslhs) )
18167  {
18168  /* set up indices */
18169  matbeg[matrowidx] = matidx;
18170  for( j = 0; j < nnonz; ++j )
18171  {
18172  assert( rowcols[j] != NULL );
18173  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18174  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18175  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18176  matinds[matidx] = rowcols[j]->lppos;
18177  matvals[matidx++] = rowvals[j];
18178  assert( matidx <= ntotnonz );
18179  }
18180 
18181  /* add artificial variable */
18182  if ( ! SCIPsetIsZero(set, lhs) )
18183  {
18184  matinds[matidx] = lp->ncols;
18185  matvals[matidx++] = -lhs;
18186  assert( matidx <= ntotnonz );
18187  }
18188 
18189  if( relaxrows )
18190  {
18191  /* add slack variable */
18192  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18193  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18194  assert( matidx <= ntotnonz );
18195  ++cnt;
18196  }
18197 
18198  matlhs[matrowidx] = 0.0;
18199  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18200  assert( matrowidx <= ntotrows );
18201  }
18202 
18203  /* treat rhs */
18204  if( !SCIPsetIsInfinity(set, absrhs) )
18205  {
18206  /* set up indices */
18207  matbeg[matrowidx] = matidx;
18208  for( j = 0; j < nnonz; ++j )
18209  {
18210  assert( rowcols[j] != NULL );
18211  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18212  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18213  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18214  matinds[matidx] = rowcols[j]->lppos;
18215  matvals[matidx++] = rowvals[j];
18216  assert( matidx <= ntotnonz );
18217  }
18218 
18219  /* add artificial variable */
18220  if ( ! SCIPsetIsZero(set, rhs) )
18221  {
18222  matinds[matidx] = lp->ncols;
18223  matvals[matidx++] = -rhs;
18224  assert( matidx <= ntotnonz );
18225  }
18226 
18227  if( relaxrows )
18228  {
18229  /* add slack variable */
18230  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18231  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18232  ++cnt;
18233  }
18234 
18235  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18236  matrhs[matrowidx++] = 0.0;
18237  assert( matrowidx <= ntotrows );
18238  }
18239  }
18240  }
18241 
18242  /* create row arising from objective cutoff */
18243  if( inclobjcutoff )
18244  {
18245  SCIP_Real rhs;
18246 
18247  /* get row data */
18248  assert(lp->looseobjvalinf == 0);
18249  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18250 
18251  /* set up indices and coefficients */
18252  matbeg[matrowidx] = matidx;
18253  for( j = 0; j < lp->ncols; ++j )
18254  {
18255  assert( lp->cols[j] != NULL );
18256  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18257  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18258 
18259  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18260  {
18261  matinds[matidx] = lp->cols[j]->lppos;
18262  matvals[matidx++] = lp->cols[j]->obj;
18263  assert( matidx <= ntotnonz );
18264  }
18265  }
18266 
18267  /* treat rhs */
18268 
18269  /* add artificial variable */
18270  if ( ! SCIPsetIsZero(set, rhs) )
18271  {
18272  matinds[matidx] = lp->ncols;
18273  matvals[matidx++] = -rhs;
18274  assert( matidx <= ntotnonz );
18275  }
18276 
18277  if( relaxrows )
18278  {
18279  SCIP_Real absrhs = REALABS(rhs);
18280 
18281  /* add slack variable */
18282  matvals[matidx] = MAX(1.0, absrhs);
18283  matinds[matidx++] = lp->ncols + 1 + cnt;
18284  assert( matidx <= ntotnonz );
18285  ++cnt;
18286  }
18287  matlhs[matrowidx] = -SCIPsetInfinity(set);
18288  matrhs[matrowidx++] = 0.0;
18289  assert( matrowidx <= ntotrows );
18290  }
18291 
18292  /* create rows arising from bounds */
18293  for( j = 0; j < lp->ncols; ++j )
18294  {
18295  SCIP_COL* col;
18296  SCIP_Real abscollb;
18297  SCIP_Real abscolub;
18298 
18299  col = lp->cols[j];
18300  assert( col != NULL );
18301  assert( col->lppos == j );
18302 
18303  /* fixed variable */
18304  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18305  {
18306  /* set up index of column */
18307  matbeg[matrowidx] = matidx;
18308 
18309  matinds[matidx] = j;
18310  matvals[matidx++] = 1.0;
18311  assert( matidx <= ntotnonz );
18312 
18313  /* add artificial variable */
18314  if ( ! SCIPsetIsZero(set, col->ub) )
18315  {
18316  matinds[matidx] = lp->ncols;
18317  matvals[matidx++] = -col->ub;
18318  assert( matidx <= ntotnonz );
18319  }
18320 
18321  matlhs[matrowidx] = 0.0;
18322  matrhs[matrowidx++] = 0.0;
18323  assert( matrowidx <= ntotrows );
18324 
18325  continue;
18326  }
18327 
18328  abscollb = REALABS(col->lb);
18329  abscolub = REALABS(col->ub);
18330 
18331  /* lower bound */
18332  if ( ! SCIPsetIsInfinity(set, abscollb) )
18333  {
18334  /* set up index of column */
18335  matbeg[matrowidx] = matidx;
18336 
18337  matinds[matidx] = j;
18338  matvals[matidx++] = 1.0;
18339  assert( matidx <= ntotnonz );
18340 
18341  /* add artificial variable */
18342  if ( ! SCIPsetIsZero(set, col->lb) )
18343  {
18344  matinds[matidx] = lp->ncols;
18345  matvals[matidx++] = -col->lb;
18346  assert( matidx <= ntotnonz );
18347  }
18348 
18349  /* add slack variable */
18350  matvals[matidx] = -MAX(1.0, abscollb);
18351  matinds[matidx++] = lp->ncols + 1 + cnt;
18352  assert( matidx <= ntotnonz );
18353  ++cnt;
18354 
18355  matlhs[matrowidx] = 0.0;
18356  matrhs[matrowidx++] = SCIPsetInfinity(set);
18357  assert( matrowidx <= ntotrows );
18358  }
18359 
18360  /* upper bound */
18361  if ( ! SCIPsetIsInfinity(set, abscolub) )
18362  {
18363  /* set up index of column */
18364  matbeg[matrowidx] = matidx;
18365 
18366  matinds[matidx] = j;
18367  matvals[matidx++] = 1.0;
18368  assert( matidx <= ntotnonz );
18369 
18370  /* add artificial variable */
18371  if ( ! SCIPsetIsZero(set, col->ub) )
18372  {
18373  matinds[matidx] = lp->ncols;
18374  matvals[matidx++] = -col->ub;
18375  assert( matidx <= ntotnonz );
18376  }
18377 
18378  /* add slack variable */
18379  matvals[matidx] = MAX(1.0, abscolub);
18380  matinds[matidx++] = lp->ncols + 1 + cnt;
18381  assert( matidx <= ntotnonz );
18382  ++cnt;
18383 
18384  matlhs[matrowidx] = -SCIPsetInfinity(set);
18385  matrhs[matrowidx++] = 0.0;
18386  assert( matrowidx <= ntotrows );
18387  }
18388  }
18389  assert( cnt == nslacks );
18390  assert( matrowidx == ntotrows );
18391 
18392  /* add rows */
18393  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18394 
18395  SCIPsetFreeBufferArray(set, &matrhs);
18396  SCIPsetFreeBufferArray(set, &matlhs);
18397  SCIPsetFreeBufferArray(set, &matbeg);
18398  SCIPsetFreeBufferArray(set, &matvals);
18399  SCIPsetFreeBufferArray(set, &matinds);
18400 
18401 #ifdef SCIP_OUTPUT
18402  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18403 #endif
18404 
18405 #ifndef NDEBUG
18406  {
18407  int ncols;
18408  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18409  assert( ncols == nnewcols );
18410  }
18411 #endif
18412 
18413  /* set time limit */
18414  if( SCIPsetIsInfinity(set, timelimit) )
18415  timelimit = SCIPlpiInfinity(lpi);
18416  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18417 
18418  /* check, if parameter is unknown */
18419  if( retcode == SCIP_PARAMETERUNKNOWN )
18420  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18421  else if ( retcode != SCIP_OKAY )
18422  return retcode;
18423 
18424  /* set iteration limit */
18425  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18426 
18427  /* check, if parameter is unknown */
18428  if( retcode == SCIP_PARAMETERUNKNOWN )
18429  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18430  else if ( retcode != SCIP_OKAY )
18431  return retcode;
18432 
18433  /* solve and store point */
18434  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18435  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18436 
18437 #ifndef NDEBUG
18438  if ( SCIPlpiIsIterlimExc(lpi) )
18439  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18440  if ( SCIPlpiIsTimelimExc(lpi) )
18441  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18442 #endif
18443 
18444  if( SCIPlpiIsOptimal(lpi) )
18445  {
18446  /* get primal solution */
18447  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18448  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18449  alpha = primal[lp->ncols];
18450  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18451 
18452  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18453 
18454  /* construct relative interior point */
18455  for( j = 0; j < lp->ncols; ++j )
18456  point[j] = primal[j]/alpha;
18457 
18458 #ifdef SCIP_DEBUG
18459  /* check whether the point is a relative interior point */
18460  cnt = 0;
18461  if( relaxrows )
18462  {
18463  for( i = 0; i < lp->nrows; ++i )
18464  {
18465  SCIP_ROW* row;
18466  SCIP_COL** rowcols;
18467  SCIP_Real* rowvals;
18468  SCIP_Real lhs;
18469  SCIP_Real rhs;
18470  SCIP_Real sum;
18471  int nnonz;
18472 
18473  row = lp->rows[i];
18474  assert( row != NULL );
18475 
18476  /* get row data */
18477  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18478  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18479  nnonz = row->nlpcols;
18480  assert( nnonz <= lp->ncols );
18481  rowcols = row->cols;
18482  rowvals = row->vals;
18483 
18484  sum = 0.0;
18485  for( j = 0; j < nnonz; ++j )
18486  sum += rowvals[j] * primal[rowcols[j]->lppos];
18487  sum /= alpha;
18488 
18489  /* if we have an equation */
18490  if( SCIPsetIsEQ(set, lhs, rhs) )
18491  {
18492  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18493  }
18494  else
18495  {
18496  /* treat lhs */
18497  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18498  {
18499  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18500  ++cnt;
18501  }
18502  /* treat rhs */
18503  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18504  {
18505  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18506  ++cnt;
18507  }
18508  }
18509  }
18510  if( inclobjcutoff )
18511  {
18512  SCIP_Real sum;
18513 #ifndef NDEBUG
18514  SCIP_Real rhs;
18515 
18516  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18517 #endif
18518  sum = 0.0;
18519  for( j = 0; j < lp->ncols; ++j )
18520  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18521  sum /= alpha;
18522 
18523  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18524  ++cnt;
18525  }
18526  }
18527  /* check bounds */
18528  for( j = 0; j < lp->ncols; ++j )
18529  {
18530  SCIP_COL* col;
18531 #ifndef NDEBUG
18532  SCIP_Real val;
18533 #endif
18534 
18535  col = lp->cols[j];
18536  assert( col != NULL );
18537 #ifndef NDEBUG
18538  val = primal[col->lppos] / alpha;
18539 #endif
18540  /* if the variable is not fixed */
18541  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18542  {
18543  /* treat lb */
18544  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18545  {
18546  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18547  ++cnt;
18548  }
18549  /* treat rhs */
18550  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18551  {
18552  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18553  ++cnt;
18554  }
18555  }
18556  }
18557 #endif
18558 
18559  /* free */
18560  SCIPsetFreeBufferArray(set, &primal);
18561 
18562  *success = TRUE;
18563  }
18564 
18565  return SCIP_OKAY;
18566 }
18567 
18568 /** compute relative interior point
18569  *
18570  * We use the approach of@par
18571  * R. Freund, R. Roundy, M. J. Todd@par
18572  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18573  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18574  *
18575  * to compute a relative interior point for the current LP.
18576  *
18577  * Assume the original LP looks as follows:
18578  * \f[
18579  * \begin{array}{rrl}
18580  * \min & c^T x &\\
18581  * & A x & \geq a\\
18582  * & B x & \leq b\\
18583  * & D x & = d.
18584  * \end{array}
18585  * \f]
18586  * Note that bounds should be included in the system.
18587  *
18588  * To find an interior point the following LP does the job:
18589  * \f[
18590  * \begin{array}{rrl}
18591  * \max & 1^T y &\\
18592  * & A x - y - \alpha a & \geq 0\\
18593  * & B x + y - \alpha b & \leq 0\\
18594  * & D x - \alpha d & = 0\\
18595  * & 0 \leq y & \leq 1\\
18596  * & \alpha & \geq 1.
18597  * \end{array}
18598  * \f]
18599  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18600  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18601  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18602  */
18604  SCIP_SET* set, /**< global SCIP settings */
18605  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18606  SCIP_LP* lp, /**< LP data */
18607  SCIP_PROB* prob, /**< problem data */
18608  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18609  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18610  SCIP_Real timelimit, /**< time limit for LP solver */
18611  int iterlimit, /**< iteration limit for LP solver */
18612  SCIP_Real* point, /**< array to store relative interior point on exit */
18613  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18614  )
18615 {
18616  SCIP_LPI* lpi;
18617  SCIP_RETCODE retcode;
18618 
18619  assert(set != NULL);
18620  assert(lp != NULL);
18621  assert(point != NULL);
18622  assert(success != NULL);
18623 
18624  *success = FALSE;
18625 
18626  /* check time and iteration limits */
18627  if ( timelimit <= 0.0 || iterlimit <= 0 )
18628  return SCIP_OKAY;
18629 
18630  /* exit if there are no columns */
18631  assert(lp->nrows >= 0);
18632  assert(lp->ncols >= 0);
18633  if( lp->ncols == 0 )
18634  return SCIP_OKAY;
18635 
18636  /* disable objective cutoff if we have none */
18637  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18638  inclobjcutoff = FALSE;
18639 
18640  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18641 
18642  /* if there are no rows, we return the zero point */
18643  if( lp->nrows == 0 && !inclobjcutoff )
18644  {
18645  /* create zero point */
18646  BMSclearMemoryArray(point, lp->ncols);
18647  *success = TRUE;
18648 
18649  return SCIP_OKAY;
18650  }
18651 
18652  /* create auxiliary LP */
18653  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18654 
18655  /* catch return code and ensure that lpi is freed, anyway */
18656  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18657 
18658  SCIP_CALL( SCIPlpiFree(&lpi) );
18659 
18660  /* return error, unless we obtained an LP error */
18661  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18662  {
18663  SCIP_CALL( retcode );
18664  }
18665 
18666  return SCIP_OKAY;
18667 }
18668 
18669 /** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
18670  * based on the changes applied when reducing the problem to the optimal face
18671  *
18672  * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
18673  * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
18674  */
18676  SCIP_LP* lp, /**< LP data */
18677  SCIP_SET* set, /**< global SCIP settings */
18678  SCIP_STAT* stat, /**< problem statistics */
18679  SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
18680  SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
18681  )
18682 {
18683  assert(lp != NULL);
18684  assert(lp->solved);
18685  assert(lp->flushed);
18686 
18687  if( lp->validdegeneracylp != stat->nlps )
18688  {
18689  lp->validdegeneracylp = stat->nlps;
18690 
18691  /* if the LP was solved to optimality, we determine the dual degeneracy */
18693  {
18694  SCIP_COL** cols;
18695  SCIP_ROW** rows;
18696  SCIP_COL* col;
18697  int ncols;
18698  int nrows;
18699  int nfixedcols = 0;
18700  int nalreadyfixedcols = 0;
18701  int nfixedrows = 0;
18702 #ifndef NDEBUG
18703  int nimplicitfixedrows = 0;
18704 #endif
18705  int nineq = 0;
18706  int c;
18707  int r;
18708  int nbasicequalities = 0;
18709 
18710  cols = lp->cols;
18711  rows = lp->rows;
18712  ncols = lp->ncols;
18713  nrows = lp->nrows;
18714 
18715  /* count number of columns that will be fixed when reducing the LP to the optimal face */
18716  for( c = ncols - 1 ; c >= 0; --c )
18717  {
18718  col = cols[c];
18719  assert(SCIPcolIsInLP(col));
18720 
18721  /* column is not basic and not fixed already */
18723  {
18724  /* variable with nonzero reduced costs are fixed */
18725  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18726  if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
18727  ++nfixedcols;
18728  else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
18729  ++nalreadyfixedcols;
18730  }
18731  }
18732 
18733  /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
18734  for( r = nrows - 1; r >= 0; --r )
18735  {
18736  SCIP_ROW* row = rows[r];
18737 
18738  assert(SCIProwIsInLP(row));
18739 
18740  if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
18741  {
18742  SCIP_Real dualsol = SCIProwGetDualsol(row);
18743 
18744  ++nineq;
18745 
18747  {
18748  /* rows with nonzero dual solution are turned into equations */
18749  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18750  if( !SCIPsetIsZero(set, dualsol) )
18751  {
18752  if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18753  {
18754  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol));
18755  ++nfixedrows;
18756  }
18757  else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18758  {
18759  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol));
18760  ++nfixedrows;
18761  }
18762  }
18763 #ifndef NDEBUG
18764  else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
18765  || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
18766  {
18767  ++nimplicitfixedrows;
18768  }
18769 #endif
18770  }
18771  }
18772  else if( SCIProwGetBasisStatus(row) == SCIP_BASESTAT_BASIC )
18773  ++nbasicequalities;
18774  }
18775  assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
18776 
18777  if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
18778  lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
18779  else
18780  lp->degeneracy = 0.0;
18781 
18782  if( nrows > 0 )
18783  lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
18784  else
18785  lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
18786  assert(lp->degeneracy >= 0);
18787  assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
18788  assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
18789  }
18790  else
18791  {
18792  lp->degeneracy = 0.0;
18793  lp->varconsratio = 0.0;
18794  }
18795  }
18796 
18797  *degeneracy = lp->degeneracy;
18798  *varconsratio = lp->varconsratio;
18799 
18800  return SCIP_OKAY;
18801 }
18802 
18803 /** checks, if absolute difference of values is in range of LP primal feastol */
18805  SCIP_SET* set, /**< global SCIP settings */
18806  SCIP_LP* lp, /**< current LP data */
18807  SCIP_Real val1, /**< first value to be compared */
18808  SCIP_Real val2 /**< second value to be compared */
18809  )
18810 {
18811  assert(set != NULL);
18812  assert(lp != NULL);
18813 
18814  /* avoid to compare two different infinities; the reason for that is
18815  * that such a comparison can lead to unexpected results */
18816  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18817  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18818  || val1 == val2 ); /*lint !e777*/
18819 
18820  return EPSEQ(val1, val2, lp->feastol);
18821 }
18822 
18823 /** checks, if absolute difference of val1 and val2 is lower than LP primal feastol */
18825  SCIP_SET* set, /**< global SCIP settings */
18826  SCIP_LP* lp, /**< current LP data */
18827  SCIP_Real val1, /**< first value to be compared */
18828  SCIP_Real val2 /**< second value to be compared */
18829  )
18830 {
18831  assert(set != NULL);
18832  assert(lp != NULL);
18833 
18834  /* avoid to compare two different infinities; the reason for that is
18835  * that such a comparison can lead to unexpected results */
18836  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18837  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18838  || val1 == val2 ); /*lint !e777*/
18839 
18840  return EPSLT(val1, val2, lp->feastol);
18841 }
18842 
18843 /** checks, if absolute difference of val1 and val2 is not greater than LP primal feastol */
18845  SCIP_SET* set, /**< global SCIP settings */
18846  SCIP_LP* lp, /**< current LP data */
18847  SCIP_Real val1, /**< first value to be compared */
18848  SCIP_Real val2 /**< second value to be compared */
18849  )
18850 {
18851  assert(set != NULL);
18852  assert(lp != NULL);
18853 
18854  /* avoid to compare two different infinities; the reason for that is
18855  * that such a comparison can lead to unexpected results */
18856  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18857  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18858  || val1 == val2 ); /*lint !e777*/
18859 
18860  return EPSLE(val1, val2, lp->feastol);
18861 }
18862 
18863 /** checks, if absolute difference of val1 and val2 is greater than LP primal feastol */
18865  SCIP_SET* set, /**< global SCIP settings */
18866  SCIP_LP* lp, /**< current LP data */
18867  SCIP_Real val1, /**< first value to be compared */
18868  SCIP_Real val2 /**< second value to be compared */
18869  )
18870 {
18871  assert(set != NULL);
18872  assert(lp != NULL);
18873 
18874  /* avoid to compare two different infinities; the reason for that is
18875  * that such a comparison can lead to unexpected results */
18876  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18877  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18878  || val1 == val2 ); /*lint !e777*/
18879 
18880  return EPSGT(val1, val2, lp->feastol);
18881 }
18882 
18883 /** checks, if absolute difference of val1 and val2 is not lower than -LP primal feastol */
18885  SCIP_SET* set, /**< global SCIP settings */
18886  SCIP_LP* lp, /**< current LP data */
18887  SCIP_Real val1, /**< first value to be compared */
18888  SCIP_Real val2 /**< second value to be compared */
18889  )
18890 {
18891  assert(set != NULL);
18892  assert(lp != NULL);
18893 
18894  /* avoid to compare two different infinities; the reason for that is
18895  * that such a comparison can lead to unexpected results */
18896  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18897  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18898  || val1 == val2 ); /*lint !e777*/
18899 
18900  return EPSGE(val1, val2, lp->feastol);
18901 }
18902 
18903 /** checks, if value is in range LP primal feasibility tolerance of 0.0 */
18905  SCIP_LP* lp, /**< current LP data */
18906  SCIP_Real val /**< value to process */
18907  )
18908 {
18909  assert(lp != NULL);
18910 
18911  return EPSZ(val, lp->feastol);
18912 }
18913 
18914 /** checks, if value is greater than LP primal feasibility tolerance */
18916  SCIP_LP* lp, /**< current LP data */
18917  SCIP_Real val /**< value to process */
18918  )
18919 {
18920  assert(lp != NULL);
18921 
18922  return EPSP(val, lp->feastol);
18923 }
18924 
18925 /** checks, if value is lower than -LP primal feasibility tolerance */
18927  SCIP_LP* lp, /**< current LP data */
18928  SCIP_Real val /**< value to process */
18929  )
18930 {
18931  assert(lp != NULL);
18932 
18933  return EPSN(val, lp->feastol);
18934 }
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:7386
SCIP_Longint nprimallps
Definition: struct_stat.h:194
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17421
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:17901
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4751
int firstnewrow
Definition: struct_lp.h:336
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16491
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6508
SCIP_Real sbup
Definition: struct_lp.h:154
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13191
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:4707
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:10281
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:6269
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6572
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2541
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2860
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6703
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:4299
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:468
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2748
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:13725
#define NULL
Definition: def.h:267
SCIP_Real maxactivity
Definition: struct_lp.h:218
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8937
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:10177
SCIP_Real obj
Definition: struct_lp.h:137
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17889
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:2835
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7365
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6327
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17665
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6777
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:2966
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7008
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:4940
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14028
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:17847
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:148
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9705
int nummaxval
Definition: struct_lp.h:245
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17784
SCIP_Longint validactivitylp
Definition: struct_lp.h:232
int lpifirstchgrow
Definition: struct_lp.h:321
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6590
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3644
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:17371
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1401
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17476
#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:6176
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6687
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:16358
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:7463
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15713
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:18603
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:3115
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:9872
char * name
Definition: struct_lp.h:226
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:18227
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6274
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:3513
int nlpicols
Definition: struct_lp.h:317
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6667
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:15682
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:12026
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6422
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17719
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:18079
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6640
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:288
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8005
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:17031
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6172
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1805
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17676
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:10117
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:13602
int lpdepth
Definition: struct_lp.h:241
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17161
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17173
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6392
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:126
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17213
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2967
SCIP_Real objsumnorm
Definition: struct_lp.h:293
#define SQR(x)
Definition: def.h:214
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:18135
SCIP_ROW ** chgrows
Definition: struct_lp.h:300
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5339
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:5585
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:15302
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:15227
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:11995
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17351
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:17600
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6134
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:8902
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3698
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7897
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17545
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13270
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:15052
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13919
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14207
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:11497
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:10100
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:2646
#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:17227
#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:3279
static const int nscalars
Definition: lp.c:5744
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10396
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:13892
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17292
SCIP_ROW ** rows
Definition: struct_lp.h:161
#define FALSE
Definition: def.h:94
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:16527
#define EPSEQ(x, y, eps)
Definition: def.h:198
#define EPSISINT(x, eps)
Definition: def.h:210
int pseudoobjvalinf
Definition: struct_lp.h:340
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17837
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:13960
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6810
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:17072
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3619
int divinglpiitlim
Definition: struct_lp.h:344
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16973
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:11184
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:17340
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16953
SCIP_Bool dualchecked
Definition: struct_lp.h:371
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6381
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16505
#define TRUE
Definition: def.h:93
#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:8228
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:2791
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6808
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10033
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:17752
#define EPSP(x, eps)
Definition: def.h:204
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16345
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:2653
SCIP_Real redcost
Definition: struct_lp.h:149
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1748
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:466
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:2581
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:5476
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17769
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:18844
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:360
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:59
unsigned int sbdownvalid
Definition: struct_lp.h:188
unsigned int objchanged
Definition: struct_lp.h:182
#define DIVESTACKGROWFACT
Definition: lp.c:16288
unsigned int delaysort
Definition: struct_lp.h:253
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5834
#define SCIP_UNUSED(x)
Definition: def.h:434
unsigned int basisstatus
Definition: struct_lp.h:179
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:17104
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:15651
SCIP_Real sbsolval
Definition: struct_lp.h:155
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6478
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3092
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:9058
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:123
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6964
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:16109
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:5981
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:2941
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real dualfarkas
Definition: struct_lp.h:215
#define EPSGE(x, y, eps)
Definition: def.h:202
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:12413
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:12331
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition: set.c:6248
SCIP_Real pseudoobjval
Definition: struct_lp.h:279
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17612
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:7919
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:13643
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13302
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6751
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:3564
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:15890
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17441
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3468
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10191
unsigned int coefchanged
Definition: struct_lp.h:185
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:15242
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:10157
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:6403
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17431
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:3027
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1066
#define SCIP_LONGINT_MAX
Definition: def.h:159
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:1755
unsigned int basisstatus
Definition: struct_lp.h:109
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:51
#define BMSfreeMemory(ptr)
Definition: memory.h:145
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16330
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:2553
#define checkRow(row)
Definition: lp.c:695
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6623
int maxdepth
Definition: struct_stat.h:236
SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2352
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:9032
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:5528
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17312
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:13103
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:4739
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:14120
Definition: heur_padm.c:134
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:17730
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:16291
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:1372
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:17575
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12304
int * linkpos
Definition: struct_lp.h:230
#define FEASTOLTIGHTFAC
Definition: lp.c:11576
#define SCIP_DEFAULT_EPSILON
Definition: def.h:179
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6363
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2752
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17523
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:7131
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:9394
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4364
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:18804
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2647
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17740
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3847
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4830
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18089
int lppos
Definition: struct_lp.h:239
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6159
int divechgsidessize
Definition: struct_lp.h:343
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6309
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:15851
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:6536
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:7833
int SCIPcolGetAge(SCIP_COL *col)
Definition: lp.c:17193
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:3447
int glbpseudoobjvalinf
Definition: struct_lp.h:339
#define EPSN(x, eps)
Definition: def.h:205
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17643
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13987
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:17280
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:462
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14252
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:16003
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16996
SCIP_Real sbdown
Definition: struct_lp.h:153
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6719
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:16315
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5666
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6016
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:8671
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:8179
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:16542
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:17817
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17203
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:4900
#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:3229
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14330
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17827
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:17151
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:9450
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:9633
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17565
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17401
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:4082
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:15780
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8623
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5730
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:9947
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:9790
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:6204
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16963
#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:17420
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:17391
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:6336
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14665
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:10057
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6148
SCIP_Real cutoffbound
Definition: struct_lp.h:284
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6450
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:9509
internal miscellaneous methods
SCIP_Bool isrelax
Definition: struct_lp.h:374
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17707
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:69
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6944
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:197
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:2705
SCIP_Bool looseobjvalid
Definition: struct_lp.h:358
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:380
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition: lp.c:10256
SCIP_Real activity
Definition: struct_lp.h:108
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6755
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:18217
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6526
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:17622
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:17867
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:17302
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8376
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11488
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:6291
int lpicolssize
Definition: struct_lp.h:316
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17774
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13119
SCIP_LPI * lpi
Definition: struct_lp.h:296
SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18926
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5299
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17411
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:6711
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17238
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6908
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:4180
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6735
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:9010
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8862
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5352
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:12214
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:18675
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:9415
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6466
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:17052
SCIP_Real sblpobjval
Definition: struct_lp.h:156
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:465
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition: lp.c:10246
internal methods for problem variables
SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2395
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:7970
#define SCIP_UNKNOWN
Definition: def.h:194
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9816
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6414
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2766
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17248
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:18864
int len
Definition: struct_lp.h:169
SCIP_Real * soldirection
Definition: struct_lp.h:304
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17764
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9771
SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18884
#define SCIP_Bool
Definition: def.h:91
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13202
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:6166
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:202
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:454
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:10769
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15401
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:9370
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16983
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6049
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:112
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3899
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:6268
int chgrowssize
Definition: struct_lp.h:324
int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
Definition: lp.c:17585
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17654
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18466
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:9850
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:467
SCIP_Longint sbnode
Definition: struct_lp.h:157
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17857
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:3757
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3430
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:8236
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition: lp.c:3140
#define MIN(x, y)
Definition: def.h:243
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:17937
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:9075
#define SCIPsetDebugMsg
Definition: set.h:1784
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:4210
int minidx
Definition: struct_lp.h:242
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:17083
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:2350
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:400
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17927
SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2433
#define EPSLE(x, y, eps)
Definition: def.h:200
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:5430
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9078
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9833
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:3494
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9802
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17325
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17790
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:13924
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6865
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6924
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:15929
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6689
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:6500
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:3802
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:10133
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3249
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:7857
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3377
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3407
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12393
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:17456
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:17381
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:13430
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:166
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:17009
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:4484
#define SCIP_REAL_MAX
Definition: def.h:174
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5378
SCIP_Real maxval
Definition: struct_lp.h:211
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6999
SCIP_Real minactivity
Definition: struct_lp.h:217
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6619
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:13561
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:11268
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:7724
#define checkRowObjprod(row)
Definition: lp.c:770
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13158
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16381
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8163
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:13332
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:2617
#define EPSLT(x, y, eps)
Definition: def.h:199
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
#define SCIP_LONGINT_FORMAT
Definition: def.h:165
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:201
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17258
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:15499
SCIP_VAR ** b
Definition: circlepacking.c:65
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13178
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:17126
#define MAX(x, y)
Definition: def.h:239
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6849
int age
Definition: struct_lp.h:177
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:219
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3417
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:159
void SCIPconsCapture(SCIP_CONS *cons)
Definition: cons.c:6256
SCIP_Real * vals
Definition: struct_lp.h:162
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6598
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:17042
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8976
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10201
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static const SCIP_Real scalars[]
Definition: lp.c:5743
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:17534
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8734
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:8524
SCIP_CLOCK * primallptime
Definition: struct_stat.h:164
SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18915
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13838
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6634
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:146
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:15575
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:180
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14073
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:4771
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:6254
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6345
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:17183
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17539
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2690
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17501
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:10321
SCIP_Real primsol
Definition: struct_lp.h:95
#define SCIP_Real
Definition: def.h:173
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:17807
int size
Definition: struct_lp.h:168
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7800
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6788
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:4088
SCIP_Real lpiobjlim
Definition: struct_lp.h:286
SCIP_VAR ** y
Definition: circlepacking.c:64
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:6186
#define SCIPsetDebugMsgPrint
Definition: set.h:1785
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:5110
int nunlinked
Definition: struct_lp.h:171
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4161
#define BMSallocMemory(ptr)
Definition: memory.h:118
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14309
#define SCIP_INVALID
Definition: def.h:193
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
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:5698
SCIP_Real primsol
Definition: struct_lp.h:148
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17797
SCIP_CLOCK * duallptime
Definition: struct_stat.h:165
SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2475
SCIP_Real maxprimsol
Definition: struct_lp.h:152
#define SCIP_Longint
Definition: def.h:158
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18191
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6988
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10298
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3050
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17512
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14991
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:65
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2991
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:5747
#define SCIPisFinite(x)
Definition: pub_misc.h:1933
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:6733
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:9898
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7878
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:17361
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:6671
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4135
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6224
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:11550
unsigned int nlocks
Definition: struct_lp.h:264
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2891
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18145
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:451
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:7010
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3435
SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18904
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3976
SCIP_Longint obsoletenode
Definition: struct_lp.h:158
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:950
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9923
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14185
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:13372
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:437
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4264
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14049
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:11579
SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18824
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:359
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3199
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17632
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:17019
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:5409
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:3952
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:14348
#define SCIP_ALLOC(x)
Definition: def.h:391
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:13147
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6395
#define SCIPABORT()
Definition: def.h:352
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2916
SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7234
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:17140
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6900
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2514
unsigned int nonlpcolssorted
Definition: struct_lp.h:252
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:17093
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17611
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:10670
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17555
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:10479
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9121
int ncols
Definition: struct_lp.h:328
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2606
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4195
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:17268
SCIP_Real lpobjval
Definition: struct_lp.h:119
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17878
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:458
SCIP_Real objsqrnorm
Definition: struct_lp.h:292
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition: set.c:6196
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:3662
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17115
unsigned int local
Definition: struct_lp.h:259
#define EPSZ(x, eps)
Definition: def.h:203
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1647
#define ABS(x)
Definition: def.h:235
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:5259
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:7788
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6799
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3252
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9580
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition: lp.c:17062
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:11405
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:5640
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:5393
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:4243
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:4030
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:3165
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17491
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:67
#define checkRowSumnorm(row)
Definition: lp.c:769