Scippy

SCIP

Solving Constraint Integer Programs

redcosts.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-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file redcosts.c
17  * @brief Reduced cost based routines for Steiner problems
18  * @author Daniel Rehfeldt
19  *
20  * This file encompasses various routines for reduced costs based computations
21  *
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 
27 //#define SCIP_DEBUG
28 #include "redcosts.h"
29 #include "graph.h"
30 #include "portab.h"
31 
32 
33 /** reduced cost result data */
35 {
36  SCIP_Real* lvl_redEdgeCost; /**< for all levels: reduced costs */
37  SCIP_Real* lvl_rootToNodeDist; /**< for all levels: shortest path distances from root */
38  PATH* lvl_nodeToTermsPaths; /**< for all levels: paths to nCloseTerms nearest terminals */
39  int* lvl_nodeToTermsBases; /**< for all levels: nCloseTerms nearest terminals */
40  SCIP_Real* lvl_cutoff; /**< for all levels: reduced cost cutoff value or -1.0 if not used */
41  SCIP_Real* lvl_dualBound; /**< for all levels: dual bound or -1.0 if not used */
42  int* lvl_redCostRoot; /**< for all levels: graph root for reduced cost calculation */
43  int nCloseTerms; /**< number of close terminals: 1,2, or 3 */
44  int toplevel; /**< current top level; 0 <= toplevel < nLevelsMax */
45  int nLevelsMax; /**< maximum number of levels; >= 1*/
46  int nnodes; /**< number of nodes */
47  int nedges; /**< number of edges */
48 };
49 
50 /**@name Local methods
51  *
52  * @{
53  */
54 
55 
56 /** initializes reduced costs data structure from given parameter struct */
57 static
59  SCIP* scip, /**< SCIP */
60  const RCPARAMS* parameters, /**< parameters for initialization */
61  REDCOST** redcostdata /**< data to initialize */
62 )
63 {
64  REDCOST* rc;
65  const int nnodes = parameters->nnodes;
66  const int nedges = parameters->nedges;
67  const int nCloseTerms = parameters->nCloseTerms;
68  const int nLevels = parameters->nLevels;
69  const int redCostRoot = parameters->redCostRoot;
70  const SCIP_Real cutoff = parameters->cutoff;
71 
72  assert(nnodes >= 1 && nedges >= 1);
73  assert(nedges % 2 == 0);
74  assert(redCostRoot >= 0 || redCostRoot == UNKNOWN);
75  assert(GE(cutoff, 0.0) || EQ(cutoff, -1.0));
76  assert(nLevels >= 1);
77  assert(nCloseTerms == 1 || nCloseTerms == 2 || nCloseTerms == 3);
78 
79  SCIP_CALL( SCIPallocMemory(scip, redcostdata) );
80  rc = *redcostdata;
81 
82  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_redEdgeCost ), nLevels * nedges) );
83  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_rootToNodeDist), nLevels * nnodes) );
84  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_nodeToTermsPaths), nLevels * nCloseTerms * nnodes) );
85  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_nodeToTermsBases), nLevels * nCloseTerms * nnodes) );
86  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_cutoff), nLevels) );
87  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_redCostRoot), nLevels) );
88  SCIP_CALL( SCIPallocMemoryArray(scip, &(rc->lvl_dualBound), nLevels) );
89 
90 
91  rc->toplevel = 0;
92  rc->nLevelsMax = nLevels;
94  rc->nnodes = nnodes;
95  rc->nedges = nedges;
96 
97  for( int i = 0; i < nLevels; i++ )
98  {
99  rc->lvl_cutoff[i] = -1.0;
100  rc->lvl_dualBound[i] = -1.0;
101  rc->lvl_redCostRoot[i] = -1;
102  }
103 
104  rc->lvl_cutoff[0] = cutoff;
105  rc->lvl_redCostRoot[0] = redCostRoot;
106 
107  return SCIP_OKAY;
108 }
109 
110 
111 /** returns top level*/
112 static inline
114  const REDCOST* redcostdata /**< reduced costs data */
115  )
116 {
117  assert(redcostdata);
118  assert(0 <= redcostdata->toplevel && redcostdata->toplevel < redcostdata->nLevelsMax);
119 
120  return redcostdata->toplevel;
121 }
122 
123 
124 #ifndef NDEBUG
125 static
127  const REDCOST* redcostdata, /**< reduced costs data */
128  int level /**< the level */
129  )
130 {
131  const int toplevel = getTopLevel(redcostdata);
132 
133  return (0 <= level && level <= toplevel);
134 }
135 #endif
136 
137 
138 /** returns start position of given level for lvl_nodeToTermsPaths and lvl_nodeToTermsBases */
139 static
141  const REDCOST* redcostdata, /**< reduced costs data */
142  int level /**< the level */
143  )
144 {
145  const int nnodes = redcostdata->nnodes;
146  const int nCloseTerms = redcostdata->nCloseTerms;
147 
148  assert(nnodes >= 1 && nCloseTerms >= 1);
149  assert(levelIsValid(redcostdata, level));
150 
151  return (nnodes * nCloseTerms * level);
152 }
153 
154 
155 /**@} */
156 
157 /**@name Interface methods
158  *
159  * @{
160  */
161 
162 
163 
164 /** returns number of nodes for which reduced costs are stored */
166  const REDCOST* redcostdata /**< reduced costs data */
167  )
168 {
169  assert(redcostdata);
170 
171  return redcostdata->nnodes;
172 }
173 
174 
175 /** returns number of edges for which reduced costs are stored */
177  const REDCOST* redcostdata /**< reduced costs data */
178  )
179 {
180  assert(redcostdata);
181 
182  return redcostdata->nedges;
183 }
184 
185 
186 /** returns reduced costs */
188  const REDCOST* redcostdata, /**< reduced costs data */
189  int level /**< level to get reduced costs for */
190  )
191 {
192  const int nedges = redcostdata->nedges;
193 
194  assert(levelIsValid(redcostdata, level));
195  assert(redcostdata->lvl_redEdgeCost);
196 
197  return &(redcostdata->lvl_redEdgeCost[nedges * level]);
198 }
199 
200 
201 /** returns top level reduced costs */
203  const REDCOST* redcostdata /**< reduced costs data */
204  )
205 {
206  const int toplevel = getTopLevel(redcostdata);
207 
208  return redcosts_getEdgeCosts(redcostdata, toplevel);
209 }
210 
211 
212 /** returns root to node distances */
214  const REDCOST* redcostdata, /**< reduced costs data */
215  int level /**< level to get distances for */
216  )
217 {
218  const int nnodes = redcostdata->nnodes;
219 
220  assert(levelIsValid(redcostdata, level));
221  assert(redcostdata->lvl_rootToNodeDist);
222 
223  return &(redcostdata->lvl_rootToNodeDist[level * nnodes]);
224 }
225 
226 
227 /** returns root to node distances for top level */
229  const REDCOST* redcostdata /**< reduced costs data */
230  )
231 {
232  const int toplevel = getTopLevel(redcostdata);
233 
234  return redcosts_getRootToNodeDist(redcostdata, toplevel);
235 }
236 
237 
238 
239 /** returns paths from nodes to closes terms */
241  const REDCOST* redcostdata, /**< reduced costs data */
242  int level /**< level to get reduced costs for */
243  )
244 {
245  const int position = getStartPositionCloseTerms(redcostdata, level);
246  assert(redcostdata->lvl_nodeToTermsPaths);
247 
248  return &(redcostdata->lvl_nodeToTermsPaths[position]);
249 }
250 
251 
252 /** returns paths from nodes to closes terms for top level */
254  const REDCOST* redcostdata /**< reduced costs data */
255  )
256 {
257  const int toplevel = getTopLevel(redcostdata);
258 
259  return redcosts_getNodeToTermsPaths(redcostdata, toplevel);
260 }
261 
262 
263 /** returns closest terminals to nodes */
265  const REDCOST* redcostdata, /**< reduced costs data */
266  int level /**< level to terminals for */
267  )
268 {
269  const int position = getStartPositionCloseTerms(redcostdata, level);
270  assert(redcostdata->lvl_nodeToTermsBases);
271 
272  return &(redcostdata->lvl_nodeToTermsBases[position]);
273 }
274 
275 
276 /** returns closest terms to nodes for top level */
278  const REDCOST* redcostdata /**< reduced costs data */
279  )
280 {
281  const int toplevel = getTopLevel(redcostdata);
282 
283  return redcosts_getNodeToTermsBases(redcostdata, toplevel);
284 }
285 
286 
287 /** returns cutoff */
289  const REDCOST* redcostdata, /**< reduced costs data */
290  int level /**< level to get cutoff for */
291  )
292 {
293  assert(levelIsValid(redcostdata, level));
294 
295  return redcostdata->lvl_cutoff[level];
296 }
297 
298 
299 /** returns cutoff for top level */
301  const REDCOST* redcostdata /**< reduced costs data */
302  )
303 {
304  const int toplevel = getTopLevel(redcostdata);
305 
306  return redcosts_getCutoff(redcostdata, toplevel);
307 }
308 
309 
310 /** returns dual-bound */
312  int level, /**< level */
313  const REDCOST* redcostdata /**< reduced costs data */
314  )
315 {
316  assert(levelIsValid(redcostdata, level));
317  assert(redcostdata->lvl_dualBound);
318 
319  return redcostdata->lvl_dualBound[level];
320 }
321 
322 
323 /** returns dual-bound for top level */
325  const REDCOST* redcostdata /**< reduced costs data */
326  )
327 {
328  const int toplevel = getTopLevel(redcostdata);
329 
330  return redcosts_getDualBound(toplevel, redcostdata);
331 }
332 
333 
334 /** returns root used for reduced cost computation */
336  const REDCOST* redcostdata, /**< reduced costs data */
337  int level /**< level to get root for */
338  )
339 {
340  assert(levelIsValid(redcostdata, level));
341 
342  return redcostdata->lvl_redCostRoot[level];
343 }
344 
345 
346 /** returns root used for reduced cost computation for to level */
348  const REDCOST* redcostdata /**< reduced costs data */
349  )
350 {
351  const int toplevel = getTopLevel(redcostdata);
352 
353  return redcosts_getRoot(redcostdata, toplevel);
354 }
355 
356 
357 /** returns current (top) level; 0-indexed */
359  const REDCOST* redcostdata /**< reduced costs data */
360  )
361 {
362  const int toplevel = getTopLevel(redcostdata);
363 
364  return toplevel;
365 }
366 
367 
368 /** returns current number of levels*/
370  const REDCOST* redcostdata /**< reduced costs data */
371  )
372 {
373  const int toplevel = getTopLevel(redcostdata);
374 
375  return toplevel + 1;
376 }
377 
378 
379 /** sets cutoff */
381  SCIP_Real cutoff, /**< the value */
382  int level, /**< level to set cutoff for */
383  REDCOST* redcostdata /**< reduced costs data */
384  )
385 {
386  assert(levelIsValid(redcostdata, level));
387  assert(GE(cutoff, 0.0));
388 
389  redcostdata->lvl_cutoff[level] = cutoff;
390 }
391 
392 
393 /** sets cutoff for top level */
395  SCIP_Real cutoff, /**< the value */
396  REDCOST* redcostdata /**< reduced costs data */
397  )
398 {
399  const int toplevel = getTopLevel(redcostdata);
400 
401  redcosts_setCutoff(cutoff, toplevel, redcostdata);
402 }
403 
404 
405 /** sets dual-bound */
407  SCIP_Real dualbound, /**< the value */
408  int level, /**< level to set dual bound for */
409  REDCOST* redcostdata /**< reduced costs data */
410  )
411 {
412  assert(levelIsValid(redcostdata, level));
413  assert(GE(dualbound, 0.0));
414 
415  redcostdata->lvl_dualBound[level] = dualbound;
416 }
417 
418 
419 /** sets dual-bound */
421  SCIP_Real dualbound, /**< the value */
422  REDCOST* redcostdata /**< reduced costs data */
423  )
424 {
425  const int toplevel = getTopLevel(redcostdata);
426  assert(GE(dualbound, 0.0));
427 
428  redcosts_setDualBound(dualbound, toplevel, redcostdata);
429 }
430 
431 
432 /** sets root used for reduced cost computation */
434  int root, /**< the root */
435  int level, /**< level to set dual bound for */
436  REDCOST* redcostdata /**< reduced costs data */
437  )
438 {
439  assert(levelIsValid(redcostdata, level));
440  assert(root >= 0);
441 
442  redcostdata->lvl_redCostRoot[level] = root;
443 }
444 
445 
446 /** sets root used for reduced cost computation */
448  int root, /**< the root */
449  REDCOST* redcostdata /**< reduced costs data */
450  )
451 {
452  const int toplevel = getTopLevel(redcostdata);
453  assert(root >= 0);
454 
455  redcosts_setRoot(root, toplevel, redcostdata);
456 }
457 
458 
459 /** adds a new level */
461  REDCOST* redcostdata /**< reduced costs data */
462  )
463 {
464  assert(redcostdata);
465  assert(0 <= redcostdata->toplevel && redcostdata->toplevel < redcostdata->nLevelsMax - 1);
466 
467  redcostdata->toplevel++;
468 }
469 
470 
471 
472 /* initialize distances from reduced costs */
474  SCIP* scip, /**< SCIP */
475  int level, /**< level to inizialize for*/
476  GRAPH* g, /**< graph data structure */
477  REDCOST* redcostdata /**< reduced cost data */
478  )
479 {
480  int* pathedge;
481  const int daroot = redcosts_getRoot(redcostdata, level);
482  const SCIP_Real* const redcosts = redcosts_getEdgeCosts(redcostdata, level);
483  PATH* const vnoi = redcosts_getNodeToTermsPaths(redcostdata, level);
484  SCIP_Real* const pathdist = redcosts_getRootToNodeDist(redcostdata, level);
485  int* const vbase = redcosts_getNodeToTermsBases(redcostdata, level);
486  SCIP_Real* costrev = NULL;
487  const int nnodes = graph_get_nNodes(g);
488  const int nedges = graph_get_nEdges(g);
489  const SCIP_Bool isRpcmw = graph_pc_isRootedPcMw(g);
490  const SCIP_Bool directed = (g->stp_type == STP_SAP || g->stp_type == STP_NWSPG);
491  int* state;
492 
493  SCIP_CALL( SCIPallocBufferArray(scip, &costrev, nedges) );
494  SCIP_CALL( SCIPallocBufferArray(scip, &pathedge, nnodes + 1) );
495 
496  /* distance from root to all nodes */
497  graph_path_execX(scip, g, daroot, redcosts, pathdist, pathedge);
498 
499  for( int e = 0; e < nedges; e++ )
500  costrev[e] = redcosts[flipedge(e)];
501 
502  /* no paths should go back to the root */
503  for( int e = g->outbeg[daroot]; e != EAT_LAST; e = g->oeat[e] )
504  costrev[e] = FARAWAY;
505 
506  if( isRpcmw )
507  {
508  if( !g->extended )
509  graph_pc_2trans(scip, g);
510  else
511  graph_mark(g);
512  }
513 
514  assert(graph_isMarked(g));
515 
516  /* build Voronoi diagram
517  * todo very hacky, should be done properly by the calling method */
518  if( directed )
519  {
520  SCIP_CALL( SCIPallocBufferArray(scip, &state, nnodes) );
521 
522  assert(!isRpcmw);
523  graph_add1stTermPaths(g, costrev, vnoi, vbase, state);
524  }
525  else
526  {
527  const int nCloseTerms = redcostdata->nCloseTerms;
528  SCIP_CALL( SCIPallocBufferArray(scip, &state, nCloseTerms * nnodes) );
529 
530  if( nCloseTerms == 2 )
531  {
532  graph_get2nextTermPaths(g, costrev, costrev, vnoi, vbase, state);
533  }
534  else
535  {
536  // todo cover case == 1?
537  assert(nCloseTerms == 3);
538  graph_get3nextTermPaths(g, costrev, costrev, vnoi, vbase, state);
539  }
540 
541 #ifndef NDEBUG
542  {
543  for( int i = 0; i < nnodes; i++ )
544  {
545  if( !g->mark[i] )
546  continue;
547 
548  if( !Is_term(g->term[i]) )
549  {
550  assert(vbase[i] != daroot || vnoi[i].dist >= FARAWAY);
551  assert(vbase[i + nnodes] != daroot || vnoi[i + nnodes].dist >= FARAWAY);
552  }
553  else
554  assert(vbase[i] == i);
555  }
556  }
557 #endif
558  }
559 
560  if( isRpcmw )
561  graph_pc_2org(scip, g);
562 
563  SCIPfreeBufferArray(scip, &state);
564  SCIPfreeBufferArray(scip, &pathedge);
565  SCIPfreeBufferArray(scip, &costrev);
566 
567  return SCIP_OKAY;
568 }
569 
570 
571 
572 /* initialize distances from reduced costs */
574  SCIP* scip, /**< SCIP */
575  GRAPH* g, /**< graph data structure */
576  REDCOST* redcostdata /**< reduced cost data */
577  )
578 {
579  const int toplevel = getTopLevel(redcostdata);
580 
581  assert(g && scip);
582 
583  SCIP_CALL( redcosts_initializeDistances(scip, toplevel, g, redcostdata) );
584 
585  return SCIP_OKAY;
586 }
587 
588 
589 /** initializes reduced costs data structure from given parameter struct */
591  SCIP* scip, /**< SCIP */
592  const RCPARAMS* parameters, /**< parameters for initialization */
593  REDCOST** redcostdata /**< data to initialize */
594 )
595 {
596  assert(scip && parameters && redcostdata);
597 
598  SCIP_CALL( initFromParams(scip, parameters, redcostdata) );
599 
600  return SCIP_OKAY;
601 }
602 
603 
604 /** initializes reduced costs data structure */
606  SCIP* scip, /**< SCIP */
607  int nnodes, /**< number of nodes */
608  int nedges, /**< number of edges */
609  SCIP_Real cutoff, /**< reduced cost cutoff value or -1.0 if not used */
610  int redCostRoot, /**< graph root for reduced cost calculation */
611  REDCOST** redcostdata /**< data to initialize */
612 )
613 {
614  RCPARAMS params = { .cutoff = cutoff, .nLevels = 1, .nCloseTerms = 3, .nnodes = nnodes,
615  .nedges = nedges, .redCostRoot = redCostRoot };
616 
617  SCIP_CALL( redcosts_initFromParams(scip, &params, redcostdata) );
618 
619  return SCIP_OKAY;
620 }
621 
622 
623 /** sets cutoff */
625  SCIP_Real upperbound, /**< bound */
626  REDCOST* redcostdata, /**< reduced cost data */
627  SCIP_Real* cutoffbound /**< cutoff */
628 )
629 {
630  assert(redcostdata && cutoffbound);
631  assert(GE(redcosts_getDualBoundTop(redcostdata), 0.0));
632 
633  *cutoffbound = upperbound - redcosts_getDualBoundTop(redcostdata);
634 
635  assert(GE_FEAS_EPS(*cutoffbound, 0.0, EPSILON));
636 
637  if( *cutoffbound < 0.0 )
638  *cutoffbound = 0.0;
639 
640  redcosts_setCutoffTop(*cutoffbound, redcostdata);
641 }
642 
643 
644 /** sets cutoff */
646  SCIP_Real upperbound, /**< bound */
647  int level, /**< level */
648  REDCOST* redcostdata /**< reduced cost data */
649 )
650 {
651  SCIP_Real cutoff;
652 
653  assert(redcostdata);
654  assert(levelIsValid(redcostdata, level));
655  assert(GE(redcosts_getDualBound(level, redcostdata), 0.0));
656  assert(GE(upperbound, 0.0));
657 
658  cutoff = upperbound - redcosts_getDualBound(level, redcostdata);
659 
660  assert(GE_FEAS_EPS(cutoff, 0.0, EPSILON));
661 
662  if( cutoff < 0.0 )
663  cutoff = 0.0;
664 
665  redcosts_setCutoff(cutoff, level, redcostdata);
666 }
667 
668 
669 /** sets cutoff for top level */
671  SCIP_Real upperbound, /**< bound */
672  REDCOST* redcostdata /**< reduced cost data */
673 )
674 {
675  const int toplevel = getTopLevel(redcostdata);
676 
677  redcosts_setCutoffFromBound(upperbound, toplevel, redcostdata);
678 }
679 
680 
681 /** increases reduced cost for deleted arcs */
683  const GRAPH* graph, /**< graph */
684  const STP_Bool* arcsdeleted, /**< array to mark deleted arcs */
685  int level, /**< the level */
686  REDCOST* redcostdata /**< reduced cost data */
687 )
688 {
689  SCIP_Real* const redEdgeCost = redcosts_getEdgeCosts(redcostdata, level);
690  const int nedges = graph_get_nEdges(graph);
691  const SCIP_Real offset = 2.0 * redcosts_getCutoff(redcostdata, level) + 1.0;
692 
693  assert(GE(offset, 1.0));
694  assert(nedges == redcostdata->nedges);
695 
696  for( int i = 0; i < nedges; i++ )
697  {
698  if( arcsdeleted[i] )
699  redEdgeCost[i] += offset;
700  }
701 }
702 
703 
704 /** unifies costs */
706  const GRAPH* graph, /**< graph */
707  int level, /**< the level */
708  REDCOST* redcostdata /**< reduced cost data */
709 )
710 {
711  SCIP_Real* const redEdgeCost = redcosts_getEdgeCosts(redcostdata, level);
712  const int nedges = graph_get_nEdges(graph);
713  const SCIP_Real bound = 2.0 * redcosts_getCutoff(redcostdata, level) + 1.0;
714 
715  assert(GE(bound, 1.0));
716  assert(LT(bound, FARAWAY));
717  assert(nedges == redcostdata->nedges);
718 
719  for( int i = 0; i < nedges; i++ )
720  {
721  if( redEdgeCost[i] > bound )
722  redEdgeCost[i] = bound;
723  }
724 }
725 
726 
727 /** increases reduced cost for deleted arcs for top level */
729  const GRAPH* graph, /**< graph */
730  const STP_Bool* arcsdeleted, /**< array to mark deleted arcs */
731  REDCOST* redcostdata /**< reduced cost data */
732 )
733 {
734  const int toplevel = getTopLevel(redcostdata);
735 
736  assert(graph && arcsdeleted);
737 
738  redcosts_increaseOnDeletedArcs(graph, arcsdeleted, toplevel, redcostdata);
739 }
740 
741 
742 /** frees */
744  SCIP* scip, /**< SCIP */
745  REDCOST** redcostdata /**< data */
746 )
747 {
748  REDCOST* reddata;
749 
750  assert(scip && redcostdata);
751 
752  reddata = *redcostdata;
753 
754  SCIPfreeMemoryArray(scip, &(reddata->lvl_dualBound));
755  SCIPfreeMemoryArray(scip, &(reddata->lvl_redCostRoot));
756  SCIPfreeMemoryArray(scip, &(reddata->lvl_cutoff));
757  SCIPfreeMemoryArray(scip, &(reddata->lvl_nodeToTermsBases));
758  SCIPfreeMemoryArray(scip, &(reddata->lvl_nodeToTermsPaths));
759  SCIPfreeMemoryArray(scip, &(reddata->lvl_rootToNodeDist));
760  SCIPfreeMemoryArray(scip, &(reddata->lvl_redEdgeCost));
761 
762  SCIPfreeMemory(scip, redcostdata);
763 }
764 
765 
766 /** reduced costs available? */
768  SCIP* scip /**< SCIP structure */
769 )
770 {
771  /* only execute if current node has an LP */
772  if( !SCIPhasCurrentNodeLP(scip) )
773  {
774  SCIPdebugMessage("!SCIPhasCurrentNodeLP \n");
775  return FALSE;
776  }
777 
778  /* only execute dualcostVarfixing if optimal LP solution is at hand */
780  {
781  SCIPdebugMessage("SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL (%d) \n", SCIPgetLPSolstat(scip));
782  return FALSE;
783  }
784 
785  /* only execute if current LP is valid relaxation */
786  if( !SCIPisLPRelax(scip) )
787  {
788  SCIPdebugMessage("!SCIPisLPRelax \n");
789  return FALSE;
790  }
791 
792  /* we cannot apply reduced cost strengthening if no simplex basis is available */
793  if( !SCIPisLPSolBasic(scip) )
794  {
795  SCIPdebugMessage("!SCIPisLPSolBasic \n");
796  return FALSE;
797  }
798 
799  /* reduced cost strengthening can only be applied if cutoff is finite */
800  if( SCIPisInfinity(scip, SCIPgetCutoffbound(scip)) )
801  {
802  SCIPdebugMessage("!SCIPgetCutoffbound \n");
803  return FALSE;
804  }
805 
806  SCIPdebugMessage("reduced costs are available! \n");
807 
808 
809  return TRUE;
810 }
811 
812 
813 /** are reduced costs reliable? */
815  SCIP* scip, /**< SCIP structure */
816  SCIP_VAR** vars, /**< variables (in) */
817  const GRAPH* graph /**< graph data */
818  )
819 {
820  const int nedges = graph_get_nEdges(graph);
821 
822  assert(nedges >= 0);
823  assert(vars && scip);
824 
825  for( int e = 0; e < nedges; e++ )
826  {
827  assert(SCIPvarIsBinary(vars[e]));
828 
829  /* variable is already fixed? */
830  if( SCIPvarGetLbLocal(vars[e]) + 0.5 > SCIPvarGetUbLocal(vars[e]) )
831  {
832  continue;
833  }
834 
835  if( SCIPisFeasZero(scip, SCIPgetSolVal(scip, NULL, vars[e])) )
836  {
837  if( SCIPisDualfeasNegative(scip, SCIPgetVarRedcost(scip, vars[e])) )
838  {
839  return FALSE;
840  }
841  }
842  else
843  {
844  if( SCIPisDualfeasPositive(scip, SCIPgetVarRedcost(scip, vars[e])) )
845  {
846  return FALSE;
847  }
848 
849  if( !(SCIPisFeasEQ(scip, SCIPgetSolVal(scip, NULL, vars[e]), 1.0) || SCIPisDualfeasZero(scip, SCIPgetVarRedcost(scip, vars[e]))) )
850  {
851  return FALSE;
852  }
853  }
854  }
855 
856  return TRUE;
857 }
858 
859 
860 /** initialize reduced costs*/
862  SCIP* scip, /**< SCIP structure */
863  SCIP_VAR** vars, /**< variables (in) */
864  const GRAPH* graph, /**< graph data */
865  SCIP_Real* redcosts /**< reduced costs (out) */
866  )
867 {
868  const int nedges = graph_get_nEdges(graph);
869 
870  assert(nedges >= 0);
871  assert(vars && redcosts && scip);
872 
873  for( int e = 0; e < nedges; e++ )
874  {
875  assert(SCIPvarIsBinary(vars[e]));
876 
877  /* variable is already fixed, we must not trust the reduced cost */
878  if( SCIPvarGetLbLocal(vars[e]) + 0.5 > SCIPvarGetUbLocal(vars[e]) )
879  {
880  if( SCIPvarGetLbLocal(vars[e]) > 0.5 )
881  redcosts[e] = 0.0;
882  else
883  {
884  assert(SCIPvarGetUbLocal(vars[e]) < 0.5);
885  redcosts[e] = FARAWAY;
886  }
887  }
888  else
889  {
890  if( SCIPisFeasZero(scip, SCIPgetSolVal(scip, NULL, vars[e])) )
891  {
892  assert(!SCIPisDualfeasNegative(scip, SCIPgetVarRedcost(scip, vars[e])));
893  redcosts[e] = SCIPgetVarRedcost(scip, vars[e]);
894  }
895  else
896  {
897  assert(!SCIPisDualfeasPositive(scip, SCIPgetVarRedcost(scip, vars[e])));
898  assert(SCIPisFeasEQ(scip, SCIPgetSolVal(scip, NULL, vars[e]), 1.0) || SCIPisDualfeasZero(scip, SCIPgetVarRedcost(scip, vars[e])));
899  redcosts[e] = 0.0;
900  }
901  }
902 
903  if( redcosts[e] < 0.0 )
904  redcosts[e] = 0.0;
905  }
906 #ifdef SCIP_DISABLED_CODE
907  if( graph_pc_isPcMw(graph) )
908  {
909  /* we do some clean-up */
910  const int nnodes = graph_get_nNodes(graph);
911  const int root = graph->source;
912 
913  assert(graph->term2edge);
914 
915  for( int i = 0; i < nnodes; i++ )
916  {
917  if( graph_pc_knotIsDummyTerm(graph, i) && i != root )
918  {
919  const int edge2dummy = flipedge(graph->term2edge[i]);
920 
921  assert(edge2dummy >= 0 && graph->head[edge2dummy] == i);
922  assert(EQ(graph->cost[edge2dummy], 0.0));
923  assert(EQ(redcosts[edge2dummy], 0.0) || EQ(redcosts[edge2dummy], FARAWAY));
924 
925  if( EQ(redcosts[edge2dummy], 0.0) )
926  redcosts[edge2dummy] = 0.0;
927  }
928  }
929  }
930 #endif
931 }
932 
933 /**@} */
int graph_get_nEdges(const GRAPH *)
Definition: graph_stats.c:548
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real * lvl_redEdgeCost
Definition: redcosts.c:36
static SCIP_RETCODE initFromParams(SCIP *scip, const RCPARAMS *parameters, REDCOST **redcostdata)
Definition: redcosts.c:58
void redcosts_setAndReturnCutoffFromBoundTop(SCIP_Real upperbound, REDCOST *redcostdata, SCIP_Real *cutoffbound)
Definition: redcosts.c:624
int *RESTRICT head
Definition: graphdefs.h:224
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int * lvl_nodeToTermsBases
Definition: redcosts.c:39
int source
Definition: graphdefs.h:195
SCIP_Bool graph_pc_isRootedPcMw(const GRAPH *)
#define Is_term(a)
Definition: graphdefs.h:102
int * lvl_redCostRoot
Definition: redcosts.c:42
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
void redcosts_increaseOnDeletedArcs(const GRAPH *graph, const STP_Bool *arcsdeleted, int level, REDCOST *redcostdata)
Definition: redcosts.c:682
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:71
#define EPSILON
Definition: lpi_qso.c:93
int redcosts_getNlevels(const REDCOST *redcostdata)
Definition: redcosts.c:369
static SCIP_Bool levelIsValid(const REDCOST *redcostdata, int level)
Definition: redcosts.c:126
static int getTopLevel(const REDCOST *redcostdata)
Definition: redcosts.c:113
SCIP_Real redcosts_getCutoffTop(const REDCOST *redcostdata)
Definition: redcosts.c:300
SCIP_Real * redcosts_getRootToNodeDist(const REDCOST *redcostdata, int level)
Definition: redcosts.c:213
static long bound
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1861
void graph_get3nextTermPaths(GRAPH *, const SCIP_Real *, const SCIP_Real *, PATH *, int *, int *)
Definition: graph_tpath.c:1562
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:55
void graph_mark(GRAPH *)
Definition: graph_base.c:1130
void redcosts_addLevel(REDCOST *redcostdata)
Definition: redcosts.c:460
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
void graph_pc_2org(SCIP *, GRAPH *)
#define FALSE
Definition: def.h:87
int redcosts_getRoot(const REDCOST *redcostdata, int level)
Definition: redcosts.c:335
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
includes various files containing graph methods used for Steiner tree problems
#define STP_SAP
Definition: graphdefs.h:43
void redcosts_setDualBound(SCIP_Real dualbound, int level, REDCOST *redcostdata)
Definition: redcosts.c:406
SCIP_Bool SCIPisDualfeasZero(SCIP *scip, SCIP_Real val)
void redcosts_free(SCIP *scip, REDCOST **redcostdata)
Definition: redcosts.c:743
#define EAT_LAST
Definition: graphdefs.h:58
#define SCIPdebugMessage
Definition: pub_message.h:87
#define FARAWAY
Definition: graphdefs.h:89
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_RETCODE redcosts_initializeDistancesTop(SCIP *scip, GRAPH *g, REDCOST *redcostdata)
Definition: redcosts.c:573
void graph_get2nextTermPaths(GRAPH *, const SCIP_Real *, const SCIP_Real *, PATH *, int *, int *)
Definition: graph_tpath.c:1542
int *RESTRICT mark
Definition: graphdefs.h:198
int redcosts_getRootTop(const REDCOST *redcostdata)
Definition: redcosts.c:347
SCIP_Real * redcosts_getEdgeCosts(const REDCOST *redcostdata, int level)
Definition: redcosts.c:187
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition: scip_lp.c:216
int * redcosts_getNodeToTermsBases(const REDCOST *redcostdata, int level)
Definition: redcosts.c:264
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip_lp.c:658
int *RESTRICT oeat
Definition: graphdefs.h:231
SCIP_Real redcosts_getDualBoundTop(const REDCOST *redcostdata)
Definition: redcosts.c:324
#define GE(a, b)
Definition: portab.h:85
void graph_path_execX(SCIP *, const GRAPH *, int, const SCIP_Real *, SCIP_Real *, int *)
Definition: graph_path.c:905
void graph_pc_2trans(SCIP *, GRAPH *)
SCIP_Bool extended
Definition: graphdefs.h:267
int stp_type
Definition: graphdefs.h:264
void redcosts_setCutoffFromBoundTop(SCIP_Real upperbound, REDCOST *redcostdata)
Definition: redcosts.c:670
SCIP_Real * redcosts_getEdgeCostsTop(const REDCOST *redcostdata)
Definition: redcosts.c:202
int redcosts_getNnodes(const REDCOST *redcostdata)
Definition: redcosts.c:165
#define NULL
Definition: lpi_spx1.cpp:155
int redcosts_getNedges(const REDCOST *redcostdata)
Definition: redcosts.c:176
#define EQ(a, b)
Definition: portab.h:79
#define SCIP_CALL(x)
Definition: def.h:384
int * term2edge
Definition: graphdefs.h:208
SCIP_Real redcosts_getCutoff(const REDCOST *redcostdata, int level)
Definition: redcosts.c:288
#define LT(a, b)
Definition: portab.h:81
SCIP_RETCODE redcosts_initializeDistances(SCIP *scip, int level, GRAPH *g, REDCOST *redcostdata)
Definition: redcosts.c:473
unsigned char STP_Bool
Definition: portab.h:34
SCIP_Bool SCIPisDualfeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:74
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
SCIP_Real * lvl_dualBound
Definition: redcosts.c:41
#define SCIP_Bool
Definition: def.h:84
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:159
SCIP_Real * lvl_cutoff
Definition: redcosts.c:40
SCIP_Real * lvl_rootToNodeDist
Definition: redcosts.c:37
SCIP_Bool graph_isMarked(const GRAPH *)
Definition: graph_base.c:1165
PATH * lvl_nodeToTermsPaths
Definition: redcosts.c:38
PATH * redcosts_getNodeToTermsPathsTop(const REDCOST *redcostdata)
Definition: redcosts.c:253
SCIP_RETCODE redcosts_init(SCIP *scip, int nnodes, int nedges, SCIP_Real cutoff, int redCostRoot, REDCOST **redcostdata)
Definition: redcosts.c:605
#define flipedge(edge)
Definition: graphdefs.h:84
int *RESTRICT term
Definition: graphdefs.h:196
int redcosts_getLevel(const REDCOST *redcostdata)
Definition: redcosts.c:358
void redcosts_setRoot(int root, int level, REDCOST *redcostdata)
Definition: redcosts.c:433
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real redcosts_getDualBound(int level, const REDCOST *redcostdata)
Definition: redcosts.c:311
int * redcosts_getNodeToTermsBasesTop(const REDCOST *redcostdata)
Definition: redcosts.c:277
Portable definitions.
#define SCIPfreeMemory(scip, ptr)
Definition: scip_mem.h:69
void redcosts_setCutoffFromBound(SCIP_Real upperbound, int level, REDCOST *redcostdata)
Definition: redcosts.c:645
#define STP_NWSPG
Definition: graphdefs.h:46
void redcosts_unifyBlockedEdgeCosts(const GRAPH *graph, int level, REDCOST *redcostdata)
Definition: redcosts.c:705
SCIP_Bool SCIPisDualfeasPositive(SCIP *scip, SCIP_Real val)
static int getStartPositionCloseTerms(const REDCOST *redcostdata, int level)
Definition: redcosts.c:140
SCIP_Bool redcosts_forLPareAvailable(SCIP *scip)
Definition: redcosts.c:767
Reduced cost based routines for Steiner problems.
void redcosts_setCutoffTop(SCIP_Real cutoff, REDCOST *redcostdata)
Definition: redcosts.c:394
void redcosts_setDualBoundTop(SCIP_Real dualbound, REDCOST *redcostdata)
Definition: redcosts.c:420
SCIP_Bool graph_pc_knotIsDummyTerm(const GRAPH *, int)
SCIP_Real * cost
Definition: graphdefs.h:221
SCIP_Bool redcosts_forLPareReliable(SCIP *scip, SCIP_VAR **vars, const GRAPH *graph)
Definition: redcosts.c:814
SCIP_Bool graph_pc_isPcMw(const GRAPH *)
#define SCIP_Real
Definition: def.h:177
void redcosts_setCutoff(SCIP_Real cutoff, int level, REDCOST *redcostdata)
Definition: redcosts.c:380
PATH * redcosts_getNodeToTermsPaths(const REDCOST *redcostdata, int level)
Definition: redcosts.c:240
int *RESTRICT outbeg
Definition: graphdefs.h:204
SCIP_Real * redcosts_getRootToNodeDistTop(const REDCOST *redcostdata)
Definition: redcosts.c:228
int graph_get_nNodes(const GRAPH *)
Definition: graph_stats.c:536
#define SCIPallocMemory(scip, ptr)
Definition: scip_mem.h:51
#define UNKNOWN
Definition: sepa_mcf.c:4095
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
void graph_add1stTermPaths(const GRAPH *, const SCIP_Real *, PATH *, int *, int *)
Definition: graph_tpath.c:1464
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
void redcosts_setRootTop(int root, REDCOST *redcostdata)
Definition: redcosts.c:447
SCIP_RETCODE redcosts_initFromParams(SCIP *scip, const RCPARAMS *parameters, REDCOST **redcostdata)
Definition: redcosts.c:590
void redcosts_increaseOnDeletedArcsTop(const GRAPH *graph, const STP_Bool *arcsdeleted, REDCOST *redcostdata)
Definition: redcosts.c:728
#define GE_FEAS_EPS(a, b, eps)
Definition: portab.h:77
void redcosts_forLPget(SCIP *scip, SCIP_VAR **vars, const GRAPH *graph, SCIP_Real *redcosts)
Definition: redcosts.c:861