Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinSteinerTreeDirectedCut.h
Go to the documentation of this file.
1 
42 #pragma once
43 
44 #include <ogdf/basic/Graph.h>
45 #include <ogdf/basic/Logger.h>
49 
50 #include <ogdf/external/abacus.h>
52 
53 #include <memory>
54 // heuristics, approximation algorithms:
56 
57 // turn on/off logging for STP b&c algorithm
58 //#define OGDF_STP_EXACT_LOGGING
59 
60 // TODO: Add module option for max flow algorithm
61 
62 namespace ogdf {
63 
65 
68 template<typename T>
70 protected:
71  // all the settings
72  const char* m_configFile;
73  double m_eps;
74 #ifdef OGDF_STP_EXACT_LOGGING
75  Logger::Level m_outputLevel;
76 #endif
77  std::unique_ptr<MaxFlowModule<double>> m_maxFlowModuleOption;
92 
93  // Abacus LP classes
94  class Sub;
95  class EdgeConstraint;
96  class DegreeConstraint;
99  class EdgeVariable;
100 
101 public:
102  class Master;
103 
104  // a lot of setter methods
106  void setEpsilon(double eps) { m_eps = eps; }
107 
109  void setConfigFile(const char* configfile) { m_configFile = configfile; }
110 #ifdef OGDF_STP_EXACT_LOGGING
111  void setOutputLevel(Logger::Level outputLevel) { m_outputLevel = outputLevel; }
113 #endif
114  void setMaxFlowModule(MaxFlowModule<double>* module) { m_maxFlowModuleOption.reset(module); }
116 
119 
122 
125 
128 
131 
134 
136  void useBackCuts(bool b) { m_backCutComputation = b; }
137 
139  void useNestedCuts(bool b) { m_nestedCutComputation = b; }
140 
143 
146 
149 
152 
155  OGDF_ASSERT(b >= 0);
156  OGDF_ASSERT(b <= 2);
158  }
159 
162 
164  : m_configFile(nullptr)
165  , m_eps(1e-6)
166 #ifdef OGDF_STP_EXACT_LOGGING
167  , m_outputLevel(Logger::Level::Default)
168 #endif
170  , m_addDegreeConstraints(true)
172  , m_addGSEC2Constraints(true)
175  , m_shuffleTerminals(true)
176  , m_backCutComputation(true)
177  , m_nestedCutComputation(true)
180  , m_minCardinalityCuts(true)
182  , m_primalHeuristic(nullptr)
183  , m_poolSizeInitFactor(5) {
184  }
185 
186 protected:
187  virtual T computeSteinerTree(const EdgeWeightedGraph<T>& G, const List<node>& terminals,
188  const NodeArray<bool>& isTerminal, EdgeWeightedGraphCopy<T>*& finalSteinerTree) override;
189 };
190 
192 template<typename T>
194 public:
204  Master(const EdgeWeightedGraph<T>& wG, const List<node>& terminals,
205  const NodeArray<bool>& isTerminal, double eps, bool relaxed = false);
206 
208  virtual ~Master() {
209  delete[] m_bestSolution;
210  delete[] m_terminals;
211  delete[] m_nodes;
212  delete[] m_edges;
213  delete m_pGraph;
214  delete m_pWeightedGraphPH;
215  delete m_pCutPool;
216  }
217 
219  void setConfigFile(const char* filename) { m_configfile = filename; }
220 #ifdef OGDF_STP_EXACT_LOGGING
221  void setOutputLevel(Level outputLevel) {
223  this->globalLogLevel(Level::Default);
224  this->localLogMode(LogMode::Log);
225  if (outputLevel >= Level::Minor && outputLevel <= Level::Force) {
226  this->localLogLevel((Level)outputLevel);
227  this->globalMinimumLogLevel((Level)outputLevel);
228  }
229  }
230 #endif
231  void setMaxFlowModule(MaxFlowModule<double>* module) { m_maxFlowModule = module; }
233 
235  MaxFlowModule<double>* getMaxFlowModule() { return m_maxFlowModule; }
236 
239 
242 
245 
248 
252  this->maxConAdd(m_maxNrAddedCuttingPlanes);
253  this->maxConBuffered(m_maxNrAddedCuttingPlanes);
254  }
255 
258 
260  void useBackCuts(bool b) { m_backCutComputation = b; }
261 
263  void useNestedCuts(bool b) { m_nestedCutComputation = b; }
264 
266  void setSeparationStrategy(int b) {
267  OGDF_ASSERT(b >= 1);
268  OGDF_ASSERT(b <= 2);
270  }
271 
273  void setSaturationStrategy(int b) {
274  OGDF_ASSERT(b >= 1);
275  OGDF_ASSERT(b <= 2);
277  }
278 
281 
284  OGDF_ASSERT(b >= 0);
285  OGDF_ASSERT(b <= 2);
287  }
288 
291 
293  void setPrimalHeuristic(MinSteinerTreeModule<double>* pMinSteinerTreeModule) {
294  m_primalHeuristic.reset(pMinSteinerTreeModule);
295  }
296 
298  std::unique_ptr<MinSteinerTreeModule<double>>& getPrimalHeuristic() {
299  return m_primalHeuristic;
300  }
301 
304 
306  virtual abacus::Sub* firstSub() override { return new Sub(this); }
307 
309  bool isSolutionEdge(edge e) const {
310  return m_isSolutionEdge[m_mapToBidirectedGraph1[e]]
311  || m_isSolutionEdge[m_mapToBidirectedGraph2[e]];
312  }
313 
315  const Graph& graph() const { return *m_pGraph; }
316 
318  int nNodes() const { return m_pGraph->numberOfNodes(); }
319 
321  int nEdges() const { return m_pGraph->numberOfEdges(); }
322 
324  int nEdgesU() const { return m_nEdgesU; }
325 
327  node rootNode() const { return m_root; }
328 
330  int nTerminals() const { return m_nTerminals; }
331 
333  const node* terminals() const { return m_terminals; }
334 
336  node terminal(int i) const { return m_terminals[i]; }
337 
339  bool isTerminal(node n) const { return m_isTerminal[n]; }
340 
342  const NodeArray<bool> isTerminal() const { return m_isTerminal; }
343 
345  int edgeID(edge e) const { return m_edgeIDs[e]; }
346 
348  int nodeID(node n) const { return m_nodeIDs[n]; }
349 
351  node* nodes() const { return m_nodes; }
352 
354  const NodeArray<int>& nodeIDs() const { return m_nodeIDs; }
355 
357  const EdgeArray<int>& edgeIDs() const { return m_edgeIDs; }
358 
360  edge getEdge(int i) const { return m_edges[i]; }
361 
363  node getNode(int i) const { return m_nodes[i]; }
364 
366  const EdgeArray<double>& capacities() const { return m_capacities; }
367 
369  double capacities(edge e) const { return m_capacities[e]; }
370 
372  edge twin(edge e) const { return m_twin[e]; }
373 
374  // the twin edge array
375  const EdgeArray<edge>& twins() const { return m_twin; }
376 
378  EdgeVariable* getVar(edge e) const { return m_edgeToVar[e]; }
379 
381  EdgeVariable* getVarTwin(edge e) const { return m_edgeToVar[m_twin[e]]; }
382 
384  bool relaxed() const { return m_relaxed; }
385 
387  double solutionValue() const { return this->primalBound(); }
388 
390  double* bestSolution() const { return m_bestSolution; }
391 
393  void updateBestSolution(double* values);
395  void updateBestSolutionByEdges(const List<edge>& sol);
396 
398  void setRelaxedSolValue(double val) { m_relaxedSolValue = val; }
399 
401  void setNIterRoot(int val) { m_nIterRoot = val; }
402 
405 
407  bool computeNestedCuts() const { return m_nestedCutComputation; }
408 
410  bool computeBackCuts() const { return m_backCutComputation; }
411 
413  bool minCardinalityCuts() const { return m_minCardinalityCuts; }
414 
416  bool callPrimalHeuristic() const { return m_callPrimalHeuristic > 0; }
417 
420 
422  int separationStrategy() const { return m_separationStrategy; }
423 
425  int saturationStrategy() const { return m_saturationStrategy; }
426 
428  bool shuffleTerminals() const { return m_shuffleTerminals; }
429 
431  int maxPoolSize() const { return m_maxPoolSize; }
432 
435  if (m_poolSizeMax < m_pCutPool->size()) {
436  m_poolSizeMax = m_pCutPool->size();
437  }
438  }
439 
441  int poolSizeInit() const { return m_poolSizeInit; }
442 
444  void incNrCutsTotal(int val) { m_nrCutsTotal += val; }
445 
447  void incNrCutsTotal() { m_nrCutsTotal++; }
448 
450  int nrCutsTotal() const { return m_nrCutsTotal; }
451 
452  /*
453  * Methods for primal heuristics.
454  * Naming convention: suffix "PH"
455  */
456  /*
457  * Edge weighted bidirected graph; used and modified for primal heuristics.
458  * Required for calling MinSteinerTreeModule algorihms
459  */
460  EdgeWeightedGraph<double>& weightedGraphPH() { return *m_pWeightedGraphPH; }
461 
463  const List<node>& terminalListPH() const { return m_terminalListPH; }
464 
466  const NodeArray<bool>& isTerminalPH() const { return m_isTerminalPH; }
467 
469  node rootNodePH() const { return m_rootPH; }
470 
472  edge edgeGToWgPH(edge e) const { return m_edgesGToWgPH[e]; }
473 
475  edge edgeWgToGPH(edge e) const { return m_edgesWgToGPH[e]; }
476 
477  /*
478  * some additional timers
479  */
481  StopwatchWallClock* separationTimer() { return &m_separationTimer; }
482 
484  StopwatchWallClock* timerMinSTCut() { return &m_timerMinSTCut; }
485 
487  StopwatchWallClock* primalHeuristicTimer() { return &m_primalHeuristicTimer; }
488 
489 protected:
491  virtual void initializeOptimization() override;
493  virtual void terminateOptimization() override;
495  virtual void initializeParameters() override;
496 
497 private:
499 
501  const char* m_configfile;
502 
504  std::unique_ptr<MinSteinerTreeModule<double>> m_primalHeuristic;
505 
507  bool m_relaxed;
508 
511 
514 
517 
520 
529 
534 
541 
552 
555 
557  double* m_bestSolution;
559 
560  /*
561  * Stuff for primal heuristics
562  */
577 
590 
599 
609  /*
610  * basic strategy:
611  * Computes mincut between the root and a terminal. Saturates cutedges afterwards.
612  * Continues with same terminal until no violated cut is found. Considers next terminal.
613  * 1: When switching to next terminal saturated edges remain saturated (default)
614  * 2: When switching to next terminal saturated edges are reset to original capacity
615  */
618  /*
619  * for all cutedges e:
620  * 1: capacity[e]=1 (default)
621  * 2: capacity[e]=1/C with C=nr of cutedges
622  */
624 
626  /*
627  * adds epsilon to each arc capacity before computing the minimum cut
628  */
630 
632  /*
633  * 0: no PH
634  * 1: call PH right before branchting
635  * 2: call PH every iteration
636  */
638 
645 
646  Master(const Master& rhs);
647  const Master& operator=(const Master& rhs);
648 };
649 
651 template<typename T>
653 public:
655  explicit Sub(abacus::Master* master);
657  Sub(abacus::Master* master, abacus::Sub* father, abacus::BranchRule* branchRule);
658 
660  virtual ~Sub() { }
661 
662 #ifdef OGDF_STP_EXACT_LOGGING
663  void printCurrentSolution(bool onlyNonZeros = true);
665 #endif
666 
667 protected:
669  virtual bool feasible() override;
670 
672  virtual int separate() override {
673  if (m_alreadySeparated == -1) {
674  m_alreadySeparated = mySeparate();
675  }
676  return m_alreadySeparated;
677  }
678 
680  int mySeparate();
681 
683  void myImprove();
684 
685 #ifdef OGDF_STP_EXACT_LOGGING
686  void printMainInfosInFeasible(bool header = false) const;
688 #endif
689 
690 private:
691 #ifdef OGDF_STP_EXACT_LOGGING
692  void printConstraint(abacus::Constraint* constraint,
694  Logger::Level level = Logger::Level::Default) const;
695 #endif
696 
699 
702 
717 
719  /*
720  * 0: no PH
721  * 1: call PH right before branchting
722  * 2: call PH every iteration
723  */
725 
727  virtual Sub* generateSon(abacus::BranchRule* rule) override {
728  return new Sub(master_, this, rule);
729  }
730 };
731 
733 template<typename T>
735 public:
737 #if 0
738  const abacus::Sub *sub,
739 #endif
740  int id, edge e, double coeff, double lb = 0.0, double ub = 1.0,
742  : abacus::Variable(master, nullptr /*, sub*/, false, false, coeff, lb, ub, vartype)
743  , m_edge(e)
744  , m_id(id) {
745  }
746 
748  edge theEdge() const { return m_edge; }
749 
751  int id() const { return m_id; }
752 
754  double coefficient() const { return this->obj(); }
755 
757  node source() const { return m_edge->source(); }
758 
760  node target() const { return m_edge->target(); }
761 
762 private:
766  int m_id;
767 };
768 
770 template<typename T>
772 public:
773  EdgeConstraint(abacus::Master* master, edge e1, edge e2, int factor = 1.0,
774  abacus::CSense::SENSE sense = abacus::CSense::Less, double rhs = 1.0)
775  : abacus::Constraint(master, nullptr, sense, rhs, false, false, false)
776  , m_e1(e1)
777  , m_e2(e2)
778  , m_factor(factor) { }
779 
781  double coeff(const abacus::Variable* v) const override {
782  EdgeVariable* edgeVar = (EdgeVariable*)v;
783  edge e = edgeVar->theEdge();
784  if (e != m_e1 && e != m_e2) {
785  return 0.0;
786  }
787  return m_factor;
788  }
789 
790 private:
796  int m_factor;
797 };
798 
800 template<typename T>
802 public:
803  DegreeConstraint(abacus::Master* master, node n, double coeffIn, double coeffOut,
804  abacus::CSense::SENSE sense, double rhs)
805  : abacus::Constraint(master, nullptr, sense, rhs, false, false, false)
806  , m_node(n)
807  , m_coeffIn(coeffIn)
808  , m_coeffOut(coeffOut) { }
809 
811  virtual double coeff(const abacus::Variable* v) const override {
812  EdgeVariable* edgeVar = (EdgeVariable*)v;
813  edge e = edgeVar->theEdge();
814  if (e->target() == m_node) {
815  return m_coeffIn;
816  } else {
817  if (e->source() == m_node) {
818  return m_coeffOut;
819  } else {
820  return 0.0;
821  }
822  }
823  }
824 
826  node theNode() const { return m_node; }
827 
828 private:
832  double m_coeffIn;
834  double m_coeffOut;
835 };
836 
838 template<typename T>
840 public:
841  DegreeEdgeConstraint(abacus::Master* master, edge e, double coeffIn, double coeffEdge,
842  abacus::CSense::SENSE sense, double rhs)
843  : abacus::Constraint(master, nullptr, sense, rhs, false, false, false)
844  , m_edge(e)
845  , m_coeffIn(coeffIn)
846  , m_coeffEdge(coeffEdge) { }
847 
849  double coeff(const abacus::Variable* v) const override {
850  EdgeVariable* edgeVar = (EdgeVariable*)v;
851  edge e = edgeVar->theEdge();
852  // the edge
853  if (e->isParallelDirected(m_edge)) {
854  return m_coeffEdge;
855  }
856  // all edges to vertices x != source
857  if (e->target() != m_edge->source()) {
858  return 0.0;
859  }
860  // reverse edge
861  if (e->source() == m_edge->target()) {
862  return 0.0;
863  }
864  // all ingoing edges of the source (except the reverse edge, of course)
865  return m_coeffIn;
866  }
867 
869  edge theEdge() const { return m_edge; }
870 
871 private:
875  double m_coeffIn;
877  double m_coeffEdge;
878 };
879 
881 template<typename T>
883 public:
886  : abacus::Constraint(master, nullptr, abacus::CSense::Greater, 1.0, false, false, false)
887  , m_pGraph(&g)
888  , m_name("") {
889 #ifdef OGDF_STP_EXACT_LOGGING
890  std::cout << "Creating new DirectedCutConstraint: " << std::endl;
891 #endif
892  m_hashKey = 0;
893  m_marked.init(g);
894  for (node n : g.nodes) {
896  m_marked[n] = minSTCut->isInFrontCut(n);
897 #ifdef OGDF_STP_EXACT_LOGGING
898  if (m_marked[n]) {
899  // TODO: Use lout instead
900  std::cout << " marked node " << n << std::endl;
901  }
902 #endif
903  } else {
905  m_marked[n] = !minSTCut->isInBackCut(n);
906  }
907  if (m_marked[n]) {
908  m_nMarkedNodes++;
909  m_hashKey += n->index();
910  }
911  }
912  m_hashKey += m_nMarkedNodes * g.numberOfNodes() * g.numberOfNodes();
913 #ifdef OGDF_STP_EXACT_LOGGING
914  std::cout << " front cut edges:" << std::endl;
915  for (edge e : g.edges) {
916  if (minSTCut->isFrontCutEdge(e)) {
917  std::cout << " " << e << std::endl;
918  }
919  }
920  std::cout << " back cut edges:" << std::endl;
921  for (edge e : g.edges) {
922  if (minSTCut->isBackCutEdge(e)) {
923  std::cout << " " << e << std::endl;
924  }
925  }
926 #endif
927  }
928 
929  double coeff(const abacus::Variable* v) const override;
930 
932  bool active(node n) const { return m_marked[n]; }
933 
935  bool cutedge(edge e) const { return m_marked[e->source()] && !m_marked[e->target()]; }
936 
938  int nMarkedNodes() const { return m_nMarkedNodes; }
939 
941  bool marked(node n) const { return m_marked[n]; }
942 
944  unsigned hashKey() const override { return m_hashKey; };
945 
947  bool equal(const ConVar* cv) const override;
948 
950  const char* name() const override { return m_name; }
951 
952 private:
954  const Graph* m_pGraph;
955 
957  /*
958  * A vertex is marked iff it is separated by the cut
959  * i.e., it is contained in the same set as the target
960  */
962 
965 
967  unsigned int m_hashKey;
969  const char* m_name;
970 };
971 
972 template<typename T>
974  const List<node>& terminals, const NodeArray<bool>& isTerminal, double eps, bool relaxed)
975  : abacus::Master("MinSteinerTreeDirectedCut::Master", true, false, abacus::OptSense::Min, eps)
976  , m_maxFlowModule(nullptr)
977  , m_configfile(nullptr)
978  , m_relaxed(relaxed)
979  , m_relaxedSolValue(-1)
980  , m_nIterRoot(-1)
981  , m_wG(wG)
982  , m_pCutPool(nullptr)
983  , m_poolSizeInitFactor(5)
984  , m_poolSizeMax(0)
985  , m_maxPoolSize(-1)
986  , m_nrCutsTotal(0)
987  , m_addGSEC2Constraints(true)
988  , m_addDegreeConstraints(true)
989  , m_addIndegreeEdgeConstraints(true)
990  , m_addFlowBalanceConstraints(true)
991  , m_maxNrAddedCuttingPlanes(500)
992  , m_shuffleTerminals(true)
993  , m_backCutComputation(true)
994  , m_nestedCutComputation(true)
995  , m_separationStrategy(1)
996  , m_saturationStrategy(1)
997  , m_minCardinalityCuts(true)
998  , m_callPrimalHeuristic(1) {
999 #ifdef OGDF_STP_EXACT_LOGGING
1001  << "Master::Master(): default LP solver: " << this->OSISOLVER_[this->defaultLpSolver()]
1002  << std::endl;
1003 #endif
1004  m_pGraph = new Graph();
1005 
1006  edge e1, e2;
1007  int i = 0;
1008  int t = 0;
1009 
1010  m_nodes = new node[m_wG.numberOfNodes()];
1011  m_nodeIDs.init(*m_pGraph);
1012  m_isTerminal.init(*m_pGraph);
1013  m_nTerminals = terminals.size();
1014  m_root = nullptr;
1015 
1016 #ifdef OGDF_STP_EXACT_LOGGING
1017  lout(Level::Default) << "Master::Master(): nTerminals=" << m_nTerminals << std::flush;
1018  lout(Level::Minor) << " terminals: " << std::flush;
1019 #endif
1020  NodeArray<node> nodeMapping(m_wG);
1021  m_terminals = new node[m_nTerminals];
1022 
1023  for (node nOrig : m_wG.nodes) {
1024  node n = m_pGraph->newNode();
1025  nodeMapping[nOrig] = n;
1026  m_nodes[i] = n;
1027  m_nodeIDs[n] = i;
1028  m_isTerminal[n] = isTerminal[nOrig];
1029  if (m_isTerminal[n]) {
1030 #ifdef OGDF_STP_EXACT_LOGGING
1031  lout(Level::Minor) << n << "," << std::flush;
1032 #endif
1033  m_terminals[t++] = n;
1034  }
1035  i++;
1036  }
1037 #ifdef OGDF_STP_EXACT_LOGGING
1038  lout(Level::Minor) << std::endl << "Master::Master(): edges: ";
1039 #endif
1040 
1041  m_nEdgesU = m_wG.numberOfEdges();
1042  m_capacities.init(*m_pGraph);
1043  m_twin.init(*m_pGraph);
1044  m_edgeIDs.init(*m_pGraph);
1045  m_edges = new edge[2 * m_nEdgesU];
1046 
1047  m_mapToOrigGraph.init(*m_pGraph);
1050 
1051  i = 0;
1052  for (edge eOrig : m_wG.edges) {
1053  e1 = m_pGraph->newEdge(nodeMapping[eOrig->source()], nodeMapping[eOrig->target()]);
1054  e2 = m_pGraph->newEdge(nodeMapping[eOrig->target()], nodeMapping[eOrig->source()]);
1055  m_capacities[e1] = m_capacities[e2] = m_wG.weight(eOrig);
1056  m_twin[e1] = e2;
1057  m_twin[e2] = e1;
1058  m_edges[i] = e1;
1059  m_edgeIDs[e1] = i++;
1060  m_edges[i] = e2;
1061  m_edgeIDs[e2] = i++;
1062  m_mapToOrigGraph[e1] = eOrig;
1063  m_mapToOrigGraph[e2] = eOrig;
1064  m_mapToBidirectedGraph1[eOrig] = e1;
1065  m_mapToBidirectedGraph2[eOrig] = e2;
1066 #ifdef OGDF_STP_EXACT_LOGGING
1067  lout(Level::Minor) << " " << eOrig << "[" << e1 << ", " << e2 << "]" << std::flush;
1068 #endif
1069  }
1070 #ifdef OGDF_STP_EXACT_LOGGING
1071  lout(Level::Default) << std::endl;
1072 #endif
1073  for (node n : m_pGraph->nodes) {
1074  if (m_isTerminal[n]) {
1075  // possibility to set the root node
1076  // default: terminal with highest degree
1077  if (!m_root) {
1078  m_root = n;
1079  } else {
1080  if (m_root->degree() < n->degree()) {
1081  m_root = n;
1082  }
1083  }
1084  }
1085  }
1086 
1087 #ifdef OGDF_STP_EXACT_LOGGING
1088  lout(Level::Medium) << "Master::Master(): m_root=" << m_root << std::endl;
1089 #endif
1090 
1091  m_isSolutionEdge.init(*m_pGraph, false);
1092  m_bestSolution = new double[m_pGraph->numberOfEdges()];
1093  for (i = 0; i < m_pGraph->numberOfEdges(); i++) {
1094  m_bestSolution[i] = 1.0;
1095  }
1096 
1097  // stuff for "primal heuristic"
1099  m_nodesGToWgPH.init(*m_pGraph);
1100  m_edgesGToWgPH.init(*m_pGraph);
1103 
1104  for (node nOrig : m_pGraph->nodes) {
1106  m_nodesGToWgPH[nOrig] = n;
1107  m_isTerminalPH[n] = m_isTerminal[nOrig];
1108  if (m_isTerminalPH[n]) {
1109  m_terminalListPH.pushBack(n);
1110  }
1111  if (m_root == nOrig) {
1112  m_rootPH = n;
1113  }
1114  }
1115 
1116  for (edge eOrig : m_pGraph->edges) {
1118  m_nodesGToWgPH[eOrig->target()], 0.0);
1119  m_edgesGToWgPH[eOrig] = e;
1120  m_edgesWgToGPH[e] = eOrig;
1121  }
1122 
1123  // set default primal heuristic module to takahashi algorithm
1125 }
1126 
1127 template<typename T>
1129  if (m_configfile) {
1130  bool objectiveInteger = false;
1131  try {
1132  this->readParameters(m_configfile);
1133  } catch (const AlgorithmFailureException&) {
1134 #ifdef OGDF_STP_EXACT_LOGGING
1135  lout(Level::Alarm) << "Master::initializeParameters(): Error reading parameters."
1136  << "Using default values." << std::endl;
1137 #endif
1138  }
1139 #ifdef OGDF_STP_EXACT_LOGGING
1140  int outputLevel;
1141  getParameter("OutputLevel", outputLevel);
1142  setOutputLevel(static_cast<Level>(outputLevel));
1143 #endif
1144  int solver = (OSISOLVER)findParameter("DefaultLpSolver", 12, OSISOLVER_);
1145  this->defaultLpSolver((OSISOLVER)solver);
1146  getParameter("AddGSEC2Constraints", m_addGSEC2Constraints);
1147  getParameter("AddDegreeConstraints", m_addDegreeConstraints);
1148  getParameter("AddIndegreeEdgeConstraints", m_addIndegreeEdgeConstraints);
1149  getParameter("AddFlowBalanceConstraints", m_addFlowBalanceConstraints);
1150  getParameter("MaxNrCuttingPlanes", m_maxNrAddedCuttingPlanes);
1151  getParameter("ShuffleTerminals", m_shuffleTerminals);
1152  getParameter("BackCutComputation", m_backCutComputation);
1153  getParameter("NestedCutComputation", m_nestedCutComputation);
1154  getParameter("SeparationStrategy", m_separationStrategy);
1155  getParameter("SaturationStrategy", m_saturationStrategy);
1156  getParameter("MinCardinalityCuts", m_minCardinalityCuts);
1157  getParameter("PrimalHeuristic", m_callPrimalHeuristic);
1158  getParameter("PoolSizeInitFactor", m_poolSizeInitFactor);
1159  getParameter("ObjInteger", objectiveInteger);
1160  this->objInteger(objectiveInteger);
1161  }
1162 
1163 #ifdef OGDF_STP_EXACT_LOGGING
1164  lout(Level::High)
1165  << "Master::initializeParameters(): parameters:" << std::endl
1166  << "\tLP-Solver " << OSISOLVER_[this->defaultLpSolver()] << std::endl
1167  << "\tOutputLevel " << this->localLogLevel() << std::endl
1168  << "\tAddDegreeConstraints " << m_addDegreeConstraints << std::endl
1169  << "\tAddIndegreeEdgeConstraints " << m_addIndegreeEdgeConstraints << std::endl
1170  << "\tAddGSEC2Constraints " << m_addGSEC2Constraints << std::endl
1171  << "\tAddFlowBalanceConstraints " << m_addFlowBalanceConstraints << std::endl
1172  << "\tMaxNrCuttingPlanes " << m_maxNrAddedCuttingPlanes << std::endl
1173  << "\tShuffleTerminals " << m_shuffleTerminals << std::endl
1174  << "\tBackCutComputation " << m_backCutComputation << std::endl
1175  << "\tMinCardinalityCuts " << m_minCardinalityCuts << std::endl
1176  << "\tNestedCutComputation " << m_nestedCutComputation << std::endl;
1177  if (m_nestedCutComputation) {
1178  lout(Level::High) << "\t SeparationStrategy " << m_separationStrategy << std::endl
1179  << "\t SaturationStrategy " << m_saturationStrategy << std::endl;
1180  }
1181  lout(Level::High) << "\tPrimalHeuristic " << m_callPrimalHeuristic << std::endl
1182  << "\tPoolSizeInitFactor " << m_poolSizeInitFactor << std::endl
1183  << "\tObjective integer " << this->objInteger() << std::endl
1184  << std::endl;
1185 #endif
1187 }
1188 
1189 template<typename T>
1191 #ifdef OGDF_STP_EXACT_LOGGING
1192  lout(Level::High) << "Master::initializeOptimization(): Instance properties:" << std::endl
1193  << "\t(nNodes,nEdges) : (" << m_pGraph->numberOfNodes() << ", "
1194  << m_nEdgesU << ")" << std::endl
1195  << "\tNumber of terminals : " << m_nTerminals << std::endl
1196  << "\tRoot node : " << m_root << std::endl
1197  << std::endl;
1198 #endif
1199  int i;
1200 
1201  // buffer for variables; one for each directed edge
1202  ArrayBuffer<abacus::Variable*> variables(m_pGraph->numberOfEdges());
1203 
1204  // add (edge) variables
1205  EdgeVariable* eVar;
1206  m_edgeToVar.init(*m_pGraph, nullptr);
1207 
1209  if (m_relaxed) {
1210  vartype = abacus::VarType::Continuous;
1211  }
1212 
1213  for (i = 0; i < m_pGraph->numberOfEdges(); i++) {
1214  edge e = m_edges[i];
1215  if (e->target() != m_root // not going into root
1216  && !e->isSelfLoop()) {
1217  eVar = new EdgeVariable(this, i, e, m_capacities[e], 0.0, 1.0, vartype);
1218 #ifdef OGDF_STP_EXACT_LOGGING
1219  lout(Level::Minor) << "\tadding variable x_" << i << ", edge " << e << std::endl;
1220 #endif
1221  } else {
1222  // ub = lb = 0 is not nice, but makes life easier -> ids
1223  OGDF_ASSERT(m_capacities[e] >= 0);
1224  eVar = new EdgeVariable(this, i, e, m_capacities[e], 0.0, 0.0, vartype);
1225 #ifdef OGDF_STP_EXACT_LOGGING
1226  lout(Level::Minor) << "\tmuting variable x_" << i << ", edge " << e << std::endl;
1227 #endif
1228  }
1229  variables.push(eVar);
1230  m_edgeToVar[e] = eVar;
1231  }
1232 
1233  // add constraints
1234  int nCons = 0;
1235  if (m_addGSEC2Constraints) {
1236  nCons += m_nEdgesU;
1237  }
1238  if (m_addDegreeConstraints) {
1239  nCons += m_pGraph->numberOfNodes();
1240  }
1242  nCons += m_pGraph->numberOfEdges();
1243  }
1245  nCons += m_pGraph->numberOfNodes() - 1;
1246  }
1247 
1248  ArrayBuffer<abacus::Constraint*> basicConstraints(nCons);
1249 
1250  i = 0;
1251  if (m_addGSEC2Constraints) {
1252  EdgeArray<bool> marked(*m_pGraph, false);
1253  for (edge e : m_pGraph->edges) {
1254  if (!marked[e] && !e->isSelfLoop()) { // we have to ignore self-loops here
1255  EdgeConstraint* newCon =
1256  new EdgeConstraint(this, e, m_twin[e], 1, abacus::CSense::Less, 1.0);
1257  basicConstraints.push(newCon);
1258  marked[e] = true;
1259  marked[m_twin[e]] = true;
1260 
1261 #ifdef OGDF_STP_EXACT_LOGGING
1262  lout(Level::Minor)
1263  << "\tadding constraint " << i++ << " GSEC2: edge " << e << std::endl;
1264 #endif
1265  }
1266  }
1267  }
1268 
1269  // "degree" constraints:
1270  // (1) forall terminals t != m_root: x(delta-(t)) == 1
1271  // (2) forall non-temrinals n : x(delta-(n)) <= 1
1272  // (3) for the root : x(delta+(m_root)) >= 1
1273  if (m_addDegreeConstraints) {
1274  for (node n : m_pGraph->nodes) {
1275  DegreeConstraint* newCon;
1276  if (n == m_root) {
1277  // (3)
1278  newCon = new DegreeConstraint(this, n, 0.0, 1.0, abacus::CSense::Greater, 1.0);
1279  } else {
1280  if (m_isTerminal[n]) {
1281  // (1)
1282  newCon = new DegreeConstraint(this, n, 1.0, 0.0, abacus::CSense::Equal, 1.0);
1283  } else {
1284  // (2)
1285  newCon = new DegreeConstraint(this, n, 1.0, 0.0, abacus::CSense::Less, 1.0);
1286  }
1287  }
1288  basicConstraints.push(newCon);
1289 
1290 #ifdef OGDF_STP_EXACT_LOGGING
1291  lout(Level::Minor) << "\tadding constraint " << i++ << " Degree: node " << n << std::endl;
1292 #endif
1293  }
1294  }
1295 
1297  for (edge e : m_pGraph->edges) {
1298  if (e->source() != m_root) {
1299  DegreeEdgeConstraint* newCon =
1300  new DegreeEdgeConstraint(this, e, 1.0, -1.0, abacus::CSense::Greater, 0.0);
1301  basicConstraints.push(newCon);
1302 
1303 #ifdef OGDF_STP_EXACT_LOGGING
1304  lout(Level::Minor)
1305  << "\tadding constraint " << i++ << " Indegree: edge " << e << std::endl;
1306 #endif
1307  }
1308  }
1309  }
1310 
1312  for (node n : m_pGraph->nodes) {
1313  if (!m_isTerminal[n]) {
1314  DegreeConstraint* newCon =
1315  new DegreeConstraint(this, n, -1.0, 1.0, abacus::CSense::Greater, 0.0);
1316  basicConstraints.push(newCon);
1317 
1318 #ifdef OGDF_STP_EXACT_LOGGING
1319  lout(Level::Minor) << "\tadding constraint " << i++ << " Flow-Balance: node " << n
1320  << std::endl;
1321 #endif
1322  }
1323  }
1324  }
1325 
1326  m_poolSizeInit = m_poolSizeInitFactor * m_pGraph->numberOfEdges();
1327  m_poolSizeMax = m_poolSizeInit;
1328  // initialize the non-duplicate cut pool
1329  m_pCutPool = new abacus::NonDuplPool<abacus::Constraint, abacus::Variable>(this, m_poolSizeInit,
1330  true);
1331 
1332  this->initializePools(basicConstraints, variables, 0, nCons, true);
1333 
1334 #ifdef OGDF_STP_EXACT_LOGGING
1335  lout(Level::Minor) << "Master::initializeOptimization() done." << std::endl;
1336 #endif
1337 }
1338 
1339 template<typename T>
1341 #ifdef OGDF_STP_EXACT_LOGGING
1342  int nOnesInSol = 0;
1343 #endif
1344  for (int i = 0; i < m_pGraph->numberOfEdges(); i++) {
1345  if (m_bestSolution[i] > 0.5) {
1346  m_isSolutionEdge[m_edges[i]] = true;
1347 #ifdef OGDF_STP_EXACT_LOGGING
1348  nOnesInSol++;
1349 #endif
1350  }
1351  }
1352 
1353 #ifdef OGDF_STP_EXACT_LOGGING
1354  lout(Level::High) << std::endl;
1355  if (is_lout(Level::Medium)) {
1356  lout(Level::Medium) << "\toptimum solution edges:" << std::endl;
1357  for (edge e : m_pGraph->edges) {
1358  if (m_isSolutionEdge[e]) {
1359  lout(Level::Medium) << "\t" << e << std::endl;
1360  }
1361  }
1362  }
1363  lout(Level::Medium) << std::endl;
1364 
1365  lout(Level::High)
1366  << "Finished optimization. Statistics:" << std::endl
1367  << "Solution " << std::endl
1368  << " value " << this->primalBound() << std::endl
1369  << " rounded sol. value " << ((int)this->primalBound()) << std::endl
1370  << " nr edges " << nOnesInSol << std::endl
1371  << "Status " << this->STATUS_[this->status()] << std::endl
1372  << "Primal/dual bound " << this->primalBound() << "/" << this->dualBound()
1373  << std::endl
1374  << "Relaxed solution value " << this->m_relaxedSolValue << std::endl
1375  << "Nr subproblems " << this->nSub() << std::endl
1376  << "Nr solved LPs " << this->nLp() << std::endl
1377  << "nr solved LPs in root " << m_nIterRoot << std::endl
1378  << std::endl
1379 
1380  << "LP Solver " << this->OSISOLVER_[this->defaultLpSolver()] << std::endl
1381  << "Enumeration strategy " << this->ENUMSTRAT_[this->enumerationStrategy()] << std::endl
1382  << "Branching strategy " << this->BRANCHINGSTRAT_[this->branchingStrategy()]
1383  << std::endl
1384  << "Objective integer " << (this->objInteger() ? "true" : "false") << std::endl
1385  << std::endl
1386 
1387  << "Total time (centi sec) " << this->totalTime()->centiSeconds() << std::endl
1388  << "Total time " << *this->totalTime() << std::endl
1389  << "Total cow-time " << *this->totalCowTime() << std::endl
1390  << "LP time " << *this->lpTime() << std::endl
1391  << "LP solver time " << *this->lpSolverTime() << std::endl
1392  << "Separation time " << this->m_separationTimer << std::endl
1393  << "Minimum Cut time " << this->m_timerMinSTCut << std::endl
1394  << "Primal heuristic time " << this->m_primalHeuristicTimer << std::endl
1395  << std::endl
1396 
1397  << "Initial cutpool size " << this->m_poolSizeInit << std::endl
1398  << "Maximum cutpool size " << this->m_poolSizeMax << std::endl
1399  << "Nr separated cuts " << m_nrCutsTotal << std::endl;
1400 
1401  int nDuplicates, nCollisions;
1402  m_pCutPool->statistics(nDuplicates, nCollisions);
1403  lout(Level::High) << "Cutpool duplications " << nDuplicates << std::endl
1404  << "Cutpool collisions " << nCollisions << std::endl
1405  << std::endl;
1406 #endif
1407 }
1408 
1409 template<typename T>
1411  double eps = this->eps();
1412  double oneMinusEps = 1.0 - eps;
1413  for (int i = 0; i < m_pGraph->numberOfEdges(); i++) {
1414  if (values[i] > oneMinusEps) {
1415  m_bestSolution[i] = 1.0;
1416  } else if (values[i] < eps) {
1417  m_bestSolution[i] = 0.0;
1418  } else {
1419  m_bestSolution[i] = values[i];
1420  }
1421  }
1422 }
1423 
1424 template<typename T>
1426  for (int i = 0; i < m_pGraph->numberOfEdges(); i++) {
1427  m_bestSolution[i] = 0.0;
1428  }
1429  for (ListConstIterator<edge> it = sol.begin(); it.valid(); it++) {
1430  m_bestSolution[m_edgeIDs[*it]] = 1.0;
1431  }
1432 }
1433 
1434 template<typename T>
1436  : abacus::Sub(master, 0, 0, 0), m_alreadySeparated(-1) {
1437  m_pMaster = (Master*)master;
1446 }
1447 
1448 template<typename T>
1450  abacus::BranchRule* branchRule)
1451  : abacus::Sub(master, father, branchRule), m_alreadySeparated(-1) {
1452  m_pMaster = (Master*)master;
1453 #ifdef OGDF_STP_EXACT_LOGGING
1454  m_pMaster->lout(Logger::Level::High) << std::setw(7) << this->id() << std::setw(7) << this->nIter_
1455  << " new subproblem, parent=" << father->id() << std::endl;
1456 #endif
1465 }
1466 
1467 #ifdef OGDF_STP_EXACT_LOGGING
1468 template<typename T>
1470  if (header) {
1471  // print header
1472  m_pMaster->lout(Logger::Level::High)
1473  << std::endl
1474  << std::setw(7) << "id" << std::setw(7) << "iter" << std::setw(10) << "lp value"
1475  << std::setw(10) << "gl. LB" << std::setw(10) << "gl. UB" << std::setw(10) << "nSub"
1476  << std::setw(10) << "nOpenSub" << std::endl;
1477  } else {
1478  m_pMaster->lout(Logger::Level::High) << std::setw(7) << this->id() << std::setw(7)
1479  << this->nIter_ << std::setw(10) << lp_->value();
1480  if (this->id() == 1) {
1481  m_pMaster->lout(Logger::Level::High) << std::setw(10) << "--";
1482  } else {
1483  m_pMaster->lout(Logger::Level::High) << std::setw(10) << master_->lowerBound();
1484  }
1485  if (master_->feasibleFound()) {
1486  m_pMaster->lout(Logger::Level::High) << std::setw(10) << master_->upperBound();
1487  } else {
1488  m_pMaster->lout(Logger::Level::High) << std::setw(10) << "--";
1489  }
1490  m_pMaster->lout(Logger::Level::High) << std::setw(10) << master_->nSub() << std::setw(10)
1491  << master_->openSub()->number() << std::endl;
1492  m_pMaster->lout(Logger::Level::Minor) << "\tcurrent LP:" << std::endl;
1493  m_pMaster->lout(Logger::Level::Minor) << *lp_;
1494  m_pMaster->lout(Logger::Level::Minor) << std::endl;
1495  }
1496 }
1497 #endif
1498 
1499 template<typename T>
1501  double eps = master_->eps();
1502  double oneMinusEps = 1.0 - eps;
1503 
1504 #ifdef OGDF_STP_EXACT_LOGGING
1505  if (this->nIter_ == 1) {
1506  this->printMainInfosInFeasible(true);
1507  } else {
1508  this->printMainInfosInFeasible(false);
1509  }
1510 #endif
1511 
1512  // separate directed cuts
1513  m_alreadySeparated = mySeparate();
1514 
1515  if (m_alreadySeparated > 0) {
1516  if (m_callPrimalHeuristic == 2 && !m_pMaster->relaxed()) {
1517  myImprove();
1518  }
1519  return false;
1520  }
1521 
1522  if (this->id() == 1) {
1523  // set some statistics if we are in the root node
1524  m_pMaster->setRelaxedSolValue(lp_->value());
1525  m_pMaster->setNIterRoot(nIter_);
1526  }
1527 
1528  if (!m_pMaster->relaxed()) {
1529  // check integrality
1530  for (int i = 0; i < m_pMaster->nEdges(); i++) {
1531  if (xVal_[i] > eps && xVal_[i] < oneMinusEps) {
1532  // found non-integral solution but no violated directed cuts
1533  // i.e., we have to branch.
1534  // But first, we call the primal heuristic
1535  if (m_callPrimalHeuristic > 0) {
1536  myImprove();
1537  }
1538 
1539 #ifdef OGDF_STP_EXACT_LOGGING
1540  m_pMaster->lout(Logger::Level::Default)
1541  << "\tsolution is fractional -> Branching." << std::endl;
1542 #endif
1543  return false;
1544  }
1545  }
1546  }
1547 
1548  if (m_pMaster->betterPrimal(lp_->value())) {
1549 #ifdef OGDF_STP_EXACT_LOGGING
1550  m_pMaster->lout(Logger::Level::High)
1551  << std::setw(7) << this->id() << std::setw(7) << this->nIter_
1552  << " found better integer solution with value " << lp_->value();
1553  if (m_pMaster->is_lout(Logger::Level::Medium)) {
1554  m_pMaster->lout(Logger::Level::Medium) << ", variables > 0:" << std::endl;
1555  printCurrentSolution();
1556  } else {
1557  m_pMaster->lout(Logger::Level::High) << std::endl;
1558  }
1559 #endif
1560  m_pMaster->primalBound(lp_->value());
1561  m_pMaster->updateBestSolution(xVal_);
1562  }
1563 
1564  return true;
1565 }
1566 
1567 #ifdef OGDF_STP_EXACT_LOGGING
1568 template<typename T>
1570  int nOnesInSol = 0;
1571  double eps = master_->eps();
1572  double oneMinusEps = 1.0 - eps;
1573  for (int i = 0; i < nVar(); i++) {
1574  if (xVal_[i] > -eps && xVal_[i] < eps) {
1575  if (!onlyNonZeros) {
1576  m_pMaster->lout(Logger::Level::Minor) << "\tx" << i << "=0" << std::flush;
1577  m_pMaster->lout(Logger::Level::Minor)
1578  << " [edge " << ((EdgeVariable*)variable(i))->theEdge() << "]" << std::endl;
1579  }
1580  } else if (xVal_[i] > oneMinusEps && xVal_[i] < 1 + eps) {
1581  m_pMaster->lout(Logger::Level::Minor) << "\tx" << i << "=1" << std::flush;
1582  m_pMaster->lout(Logger::Level::Minor)
1583  << " [edge " << ((EdgeVariable*)variable(i))->theEdge() << "]" << std::endl;
1584  nOnesInSol++;
1585  } else {
1586  m_pMaster->lout(Logger::Level::Minor) << "\tx" << i << "=" << xVal_[i] << std::flush;
1587  m_pMaster->lout(Logger::Level::Minor)
1588  << " [edge " << ((EdgeVariable*)variable(i))->theEdge() << "]" << std::endl;
1589  }
1590  }
1591  m_pMaster->lout(Logger::Level::Medium) << "\tnEdges=" << nOnesInSol << std::endl << std::flush;
1592 }
1593 #endif
1594 
1595 template<typename T>
1597 #ifdef OGDF_STP_EXACT_LOGGING
1598  m_pMaster->lout(Logger::Level::Medium)
1599  << "Sub::mySeparate(): id=" << this->id() << ", iter=" << this->nIter_ << std::endl;
1600 #endif
1601  m_pMaster->separationTimer()->start();
1602  double eps = master_->eps();
1603  double cardEps = eps / 100;
1604  double oneMinusEps = 1 - eps;
1605  node r = m_pMaster->rootNode();
1606  const Graph& g = m_pMaster->graph();
1607  int nEdgesU = m_pMaster->nEdgesU();
1608 
1609  int nTerminals = m_pMaster->nTerminals();
1610  const node* masterTerminals = m_pMaster->terminals();
1611  Array<node> terminal(nTerminals);
1612 
1613  for (int i = 0; i < nTerminals; i++) {
1614  terminal[i] = masterTerminals[i];
1615  }
1616 
1617  if (m_shuffleTerminals) {
1618  // shuffle the ordering of the terminals
1619  int j;
1620  node h = nullptr;
1621  for (int i = 0; i < nTerminals - 1; i++) {
1622  j = randomNumber(i, nTerminals - 1);
1623  h = terminal[i];
1624  terminal[i] = terminal[j];
1625  terminal[j] = h;
1626  }
1627  }
1628 
1629 #ifdef OGDF_STP_EXACT_LOGGING
1630  if (m_pMaster->is_lout(Logger::Level::Medium)) {
1631  m_pMaster->lout(Logger::Level::Medium) << "Sub::mySeparate(): considered terminal ordering: ";
1632  for (int i = 0; i < nTerminals; i++) {
1633  m_pMaster->lout(Logger::Level::Medium) << terminal[i] << " ";
1634  }
1635  m_pMaster->lout(Logger::Level::Medium) << std::endl;
1636  }
1637 #endif
1638 
1639  EdgeArray<double> capacities;
1640  capacities.init(g, 0);
1641  for (edge e : g.edges) {
1642  // some LP solvers might return a negative epsilon instead of 0 due to numerical reasons
1643  capacities[e] = max(xVal_[m_pMaster->edgeID(e)], 0.);
1644  if (m_minCardinalityCuts) {
1645  capacities[e] += cardEps;
1646  }
1647  }
1648 
1649 #ifdef OGDF_STP_EXACT_LOGGING
1650  m_pMaster->lout(Logger::Level::Minor)
1651  << "Sub::mySeparate(): current capacities (>0) for mincut computation:" << std::endl;
1652  for (edge e : g.edges) {
1653  if (capacities[e] >= 2 * cardEps) {
1654  m_pMaster->lout(Logger::Level::Minor)
1655  << "\tcapacity[" << e << "]=" << capacities[e] << std::endl;
1656  }
1657  }
1658 #endif
1659  // Minimum s-t-cut object
1660  MinSTCutMaxFlow<double> minSTCut;
1661  // current terminal
1662  node t;
1663  // index of current terminal
1664  int ti = 0;
1665  // value of current cut
1666  double cutValue = 2.0;
1667  // value of current back cut
1668  double cutValueBack = 0.0;
1669  // for backcut computation
1670  int nOtherNodes = 0;
1671  // upper bound for mincut computation
1672  double uBound = 1 + nEdgesU * cardEps;
1673  // nr of violated cuts found
1674  int cutsFound = 0;
1675 
1676  // buffer for new constraints
1677  ArrayBuffer<abacus::Constraint*> newConstraints(m_maxNrCuttingPlanes);
1678 
1679  // size of cut and backcut
1680  int cardinalityCut, cardinalityBackcut;
1681  cardinalityCut = cardinalityBackcut = 0;
1682 
1683  // Only relevant if nested cuts are computed:
1684  // this list contains the modified edges i.e., the saturated edges.
1685  // The capacity of these edges can is reset in SeparationStrategy 2
1686  List<edge> modified;
1687 
1688  // main while loop for the computation of the cutting planes
1689  while (cutsFound < m_maxNrCuttingPlanes && ti < nTerminals) {
1690  t = terminal[ti];
1691  if (t != r) {
1692 #ifdef OGDF_STP_EXACT_LOGGING
1693  m_pMaster->lout(Logger::Level::Medium)
1694  << "Sub::mySeparate(): computing minimum cut between root " << r << " and " << t
1695  << std::flush;
1696 #endif
1697  // /compute the minimum r-t-cut
1698  /*
1699  * the cut itself is stored in the integer array with values
1700  * in {0,1,2}. If a node has the value 1, it is contained in the
1701  * subset of the root, 2 indicates the set of the separated node, and
1702  * 0 depicts the set in between
1703  */
1704  m_pMaster->timerMinSTCut()->start();
1705 
1706  EdgeArray<double> flow;
1707  MaxFlowModule<double>* mf = m_pMaster->getMaxFlowModule();
1708  OGDF_ASSERT(mf != nullptr);
1709  mf->init(g);
1710  mf->useEpsilonTest(cardEps / 100);
1711  cutValue = mf->computeFlow(capacities, r, t, flow);
1712 #ifdef OGDF_STP_EXACT_LOGGING
1713  m_pMaster->lout(Logger::Level::Medium) << " Calculated flow:" << std::endl;
1714  for (edge flowEdge : g.edges) {
1715  m_pMaster->lout(Logger::Level::Medium)
1716  << " " << flowEdge << " : " << flow[flowEdge] << " / "
1717  << capacities[flowEdge] << std::endl;
1718  }
1719 #endif
1720 
1721  // used epsilon should be smaller than the eps used for cardinality cuts heuristic
1722  minSTCut.setEpsilonTest(new EpsilonTest(cardEps / 100));
1723  minSTCut.call(g, capacities, flow, r, t);
1724 
1725  m_pMaster->timerMinSTCut()->stop();
1726  cutValueBack = 0;
1727 
1728 #ifdef OGDF_STP_EXACT_LOGGING
1729  m_pMaster->lout(Logger::Level::Medium) << ", cutvalue=" << cutValue << std::flush;
1730 #endif
1731 
1732  // min cardinality
1733  if (m_minCardinalityCuts && cutValue < uBound) {
1734  for (edge e : g.edges) {
1735  if (minSTCut.isFrontCutEdge(e)) {
1736  cutValue -= cardEps;
1737  }
1738  if (m_computeBackCuts && minSTCut.isBackCutEdge(e)) {
1739  cutValueBack += capacities[e] - cardEps;
1740  }
1741  }
1742  } else if (m_computeBackCuts) {
1743  for (edge e : g.edges) {
1744  if (minSTCut.isBackCutEdge(e)) {
1745  cutValueBack += capacities[e];
1746  }
1747  }
1748  }
1749 
1750  if (m_saturationStrategy == 2) {
1751  cardinalityCut = cardinalityBackcut = 0;
1752  for (edge e : g.edges) {
1753  if (minSTCut.isFrontCutEdge(e)) {
1754  cardinalityCut++;
1755  }
1756  if (m_computeBackCuts && minSTCut.isBackCutEdge(e)) {
1757  cardinalityBackcut++;
1758  }
1759  }
1760  }
1761 
1762 #ifdef OGDF_STP_EXACT_LOGGING
1763  m_pMaster->lout(Logger::Level::Medium) << ", actual cutvalue=" << cutValue;
1764  if (m_computeBackCuts) {
1765  m_pMaster->lout(Logger::Level::Medium) << ", actual cutValueBack=" << cutValueBack;
1766  }
1767  m_pMaster->lout(Logger::Level::Medium) << std::endl;
1768 #endif
1769  nOtherNodes = 0;
1770 
1771  if (cutValue < oneMinusEps) {
1772  // found violated cut
1773  cutsFound++;
1774  // generate new constraint
1775  DirectedCutConstraint* newCut = new DirectedCutConstraint(master_, g, &minSTCut,
1777  // push cut to the set of new constraints
1778  newConstraints.push(newCut);
1779 
1780 #ifdef OGDF_STP_EXACT_LOGGING
1781  m_pMaster->lout(Logger::Level::Medium)
1782  << "Sub::mySeparate(): found violated cut:" << std::endl;
1783  printConstraint(newCut, Logger::Level::Medium);
1784 #endif
1785  if (m_computeBackCuts && !minSTCut.frontCutIsComplementOfBackCut()
1786  && cutsFound < m_maxNrCuttingPlanes && cutValueBack <= oneMinusEps) {
1787  cutsFound++;
1788  // generate new constraint
1789  DirectedCutConstraint* newBackCut = new DirectedCutConstraint(master_, g,
1791  // push cut to the set of new constraints
1792  newConstraints.push(newBackCut);
1793 
1794 #ifdef OGDF_STP_EXACT_LOGGING
1795  m_pMaster->lout(Logger::Level::Medium)
1796  << "Sub::mySeparate(): found violated cut (backcut):" << std::endl;
1797  printConstraint(newBackCut, Logger::Level::Medium);
1798 #endif
1799  }
1800 
1801  // saturate cut edges in case of nested cut computation
1802  if (m_computeNestedCuts) {
1803  for (edge e : g.edges) {
1804  if (minSTCut.isFrontCutEdge(e)) {
1805  if (m_saturationStrategy == 2) {
1806  capacities[e] = 1.0 / (double)cardinalityCut + eps;
1807  } else {
1808  capacities[e] = 1.0 + eps;
1809  }
1810  // for resetting the saturation after each iteration
1811  if (m_separationStrategy == 2) {
1812  modified.pushBack(e);
1813  }
1814  } else {
1815  if (m_computeBackCuts && nOtherNodes > 0 && cutValueBack <= oneMinusEps
1816  && minSTCut.isBackCutEdge(e)) {
1817  if (m_saturationStrategy == 2) {
1818  capacities[e] = 1.0 / (double)cardinalityBackcut + eps;
1819  } else {
1820  capacities[e] = 1.0 + eps;
1821  }
1822  // for resetting the saturation after each iteration
1823  if (m_separationStrategy == 2) {
1824  modified.pushBack(e);
1825  }
1826  }
1827  }
1828  }
1829  }
1830  }
1831  }
1832 
1833  if (!m_computeNestedCuts) {
1834  ti++;
1835  } else {
1836  if (cutValue > oneMinusEps || r == t) {
1837  ti++;
1838  if (m_separationStrategy == 2) {
1839  while (!modified.empty()) {
1840  edge e = modified.popFrontRet();
1841  capacities[e] = xVal_[m_pMaster->edgeID(e)];
1842  if (m_minCardinalityCuts) {
1843  capacities[e] += cardEps;
1844  }
1845  }
1846  }
1847  }
1848  }
1849  }
1850 
1851  m_alreadySeparated = cutsFound;
1852 
1853  if (cutsFound > 0) {
1854  // add separated directed cuts
1855  int nAdded = addCons(newConstraints, m_pMaster->cutPool());
1856  // update statistics
1857  m_pMaster->incNrCutsTotal(nAdded);
1858  m_pMaster->checkSetMaxPoolSize();
1859  if (nAdded != cutsFound) {
1860  // ToDo: is this a problem?!
1861  }
1862  }
1863 
1864 #ifdef OGDF_STP_EXACT_LOGGING
1865  m_pMaster->lout(Logger::Level::Medium)
1866  << "Sub::mySeparate(): id=" << this->id() << ", iter=" << this->nIter_ << " separated "
1867  << cutsFound << " directed cuts" << std::endl;
1868 #endif
1869  m_pMaster->separationTimer()->stop();
1870 
1871  return cutsFound;
1872 }
1873 
1874 template<typename T>
1876  m_pMaster->primalHeuristicTimer()->start();
1877 
1878 #ifdef OGDF_STP_EXACT_LOGGING
1879  m_pMaster->lout(Logger::Level::Minor)
1880  << "Sub::myImprove(): id=" << this->id() << ", iter=" << this->nIter_ << std::endl;
1881 #endif
1882  double eps = master_->eps();
1883  const Graph& g = m_pMaster->graph();
1884  EdgeWeightedGraph<double>& ewg = m_pMaster->weightedGraphPH();
1885 
1886 #ifdef OGDF_STP_EXACT_LOGGING
1887  if (m_pMaster->ilout(Logger::Level::Minor)) {
1888  m_pMaster->lout(Logger::Level::Minor) << "Sub::myImprove(): current solution:" << std::endl;
1889  for (edge e : g.edges) {
1890  m_pMaster->lout(Logger::Level::Minor)
1891  << "\tx" << m_pMaster->edgeID(e) << "=" << xVal_[m_pMaster->edgeID(e)]
1892  << ", edge " << e << std::endl;
1893  }
1894  }
1895 #endif
1896 
1897  // set edge weights to eps + (1-x_e)*c_e, forall edges e
1898  // thereby, use minimum of e and twin(e), respectively
1899  double currWeight, twinWeight;
1900  for (edge e : g.edges) {
1901  edge e2 = m_pMaster->twin(e);
1902  currWeight = 1.0 - xVal_[m_pMaster->edgeID(e)];
1903  twinWeight = 1.0 - xVal_[m_pMaster->edgeID(e2)];
1904  if (twinWeight < currWeight) {
1905  currWeight = twinWeight;
1906  }
1907  if (currWeight < 0) {
1908  currWeight = 0;
1909  }
1910  ewg.setWeight(m_pMaster->edgeGToWgPH(e),
1911  eps + currWeight * variable(m_pMaster->edgeID(e))->obj());
1912  }
1913 
1914 #ifdef OGDF_STP_EXACT_LOGGING
1915  if (m_pMaster->ilout(Logger::Level::Minor)) {
1916  m_pMaster->lout(Logger::Level::Minor) << "Sub::myImprove(): edge weights:" << std::endl;
1917  for (edge e : g.edges) {
1918  m_pMaster->lout(Logger::Level::Minor)
1919  << "\tweight[" << e << "]=" << ewg.weight(m_pMaster->edgeGToWgPH(e))
1920  << std::endl;
1921  }
1922  }
1923 #endif
1924 
1925  // get primal heuristic algorithm
1926  auto& primalHeuristic = m_pMaster->getPrimalHeuristic();
1927 
1928  // the computed heuristic solution
1929  EdgeWeightedGraphCopy<double>* heuristicSolutionWg = nullptr;
1930 
1931 #ifdef OGDF_STP_EXACT_LOGGING
1932  // heuristic solution value for the modified edge weights
1933  double tmpHeuristicSolutionValue =
1934 #endif
1935  // call primal heuristic
1936  primalHeuristic->call(m_pMaster->weightedGraphPH(), m_pMaster->terminalListPH(),
1937  m_pMaster->isTerminalPH(), heuristicSolutionWg);
1938 
1939  // verify that solution is a Steiner tree
1940  bool isSteinerTree = primalHeuristic->isSteinerTree(m_pMaster->weightedGraphPH(),
1941  m_pMaster->terminalListPH(), m_pMaster->isTerminalPH(), *heuristicSolutionWg);
1942 
1943 #ifdef OGDF_STP_EXACT_LOGGING
1944  m_pMaster->lout(Logger::Level::Default)
1945  << "Sub::myImprove(): primal heuristic algorithm returned solution with "
1946  << "value " << tmpHeuristicSolutionValue << ", isSteinerTree=" << isSteinerTree
1947  << std::endl;
1948 #endif
1949 
1950  if (isSteinerTree) {
1951  // actual heuristic solution value, i.e., by using real edge weights
1952  double heuristicSolutionValue = 0.0;
1953  // list of edges in the heuristic solution
1954  List<edge> solutionEdges;
1955 
1956  for (edge e : heuristicSolutionWg->edges) {
1957  edge e2 = m_pMaster->edgeWgToGPH(heuristicSolutionWg->original(e));
1958  solutionEdges.pushBack(e2);
1959  heuristicSolutionValue += m_pMaster->capacities(e2);
1960 #ifdef OGDF_STP_EXACT_LOGGING
1961  m_pMaster->lout(Logger::Level::Minor)
1962  << "\t" << e << " -> " << e2 << " c=" << m_pMaster->capacities(e2) << std::endl;
1963 #endif
1964  }
1965 
1966 #ifdef OGDF_STP_EXACT_LOGGING
1967  m_pMaster->lout(Logger::Level::Default)
1968  << "Sub::myImprove(): found integer solution with value " << heuristicSolutionValue
1969  << std::endl;
1970 #endif
1971  if (m_pMaster->betterPrimal(heuristicSolutionValue)) {
1972 #ifdef OGDF_STP_EXACT_LOGGING
1973  m_pMaster->lout(Logger::Level::High)
1974  << std::setw(7) << this->id() << std::setw(7) << this->nIter_
1975  << " primal heuristic founds better integer solution with value "
1976  << heuristicSolutionValue << std::endl;
1977 #endif
1978  m_pMaster->primalBound(heuristicSolutionValue);
1979  m_pMaster->updateBestSolutionByEdges(solutionEdges);
1980  }
1981  }
1982 #ifdef OGDF_STP_EXACT_LOGGING
1983  else {
1984  m_pMaster->lout(Logger::Level::High)
1985  << "Sub::myImprove(): id=" << this->id() << ", iter=" << this->nIter_
1986  << ": computed solution is no Steiner tree!" << std::endl;
1987  }
1988 #endif
1989 
1990  delete heuristicSolutionWg;
1991  m_pMaster->primalHeuristicTimer()->stop();
1992 }
1993 
1994 #ifdef OGDF_STP_EXACT_LOGGING
1995 template<typename T>
1997  Logger::Level level) const {
1998  double eps = master_->eps();
1999  double val = 0;
2001  bool first = true;
2002  for (int i = 0; i < nVar(); i++) {
2003  var = variable(i);
2004  val = constraint->coeff(var);
2005  if (val > eps || val < -eps) {
2006  if (val > 0) {
2007  if (val > 1 - eps && val < 1 + eps) {
2008  if (!first) {
2009  m_pMaster->lout(level) << " + ";
2010  }
2011  } else {
2012  if (!first) {
2013  m_pMaster->lout(level) << " + " << val;
2014  }
2015  }
2016  } else {
2017  if (val < -1 + eps && val > -1 - eps) {
2018  if (!first) {
2019  m_pMaster->lout(level) << " - ";
2020  } else {
2021  m_pMaster->lout(level) << " -";
2022  }
2023  } else {
2024  if (!first) {
2025  m_pMaster->lout(level) << " - " << (-1) * val;
2026  } else {
2027  m_pMaster->lout(level) << val;
2028  }
2029  }
2030  }
2031  m_pMaster->lout(level) << "x" << i;
2032  first = false;
2033  }
2034  }
2035  m_pMaster->lout(level) << " " << *(constraint->sense()) << " " << constraint->rhs() << std::endl;
2036 }
2037 #endif
2038 
2039 template<typename T>
2041  if (m_hashKey != cv->hashKey()) {
2042  return false;
2043  }
2045  if (m_nMarkedNodes != dirCut->nMarkedNodes()) {
2046  return false;
2047  }
2048  for (node n : m_pGraph->nodes) {
2049  if (m_marked[n] != dirCut->marked(n)) {
2050  return false;
2051  }
2052  }
2053  return true;
2054 }
2055 
2056 template<typename T>
2058  EdgeVariable* edgeVar = (EdgeVariable*)v;
2059  if (this->cutedge(edgeVar->theEdge())) {
2060  return 1.0;
2061  }
2062  return 0.0;
2063 }
2064 
2065 template<typename T>
2067  const List<node>& terminals, const NodeArray<bool>& isTerminal,
2068  EdgeWeightedGraphCopy<T>*& finalSteinerTree) {
2069  Master stpMaster(G, terminals, isTerminal, m_eps);
2070  if (m_configFile) {
2071  stpMaster.setConfigFile(m_configFile);
2072  }
2073 #ifdef OGDF_STP_EXACT_LOGGING
2074  stpMaster.setOutputLevel(m_outputLevel);
2075 #endif
2082  stpMaster.useBackCuts(m_backCutComputation);
2087  stpMaster.setMaxFlowModule(m_maxFlowModuleOption.get());
2088  if (m_primalHeuristic) {
2090  }
2093  // XXX: should we set stpMaster.objInteger true/false according to weights automatically?
2094 
2095  // now solve LP
2096  stpMaster.optimize();
2097 
2098  // collect solution edges to build Steiner tree
2099  finalSteinerTree = new EdgeWeightedGraphCopy<T>();
2100  finalSteinerTree->setOriginalGraph(G);
2101  T weight(0);
2102  for (edge e = G.firstEdge(); e; e = e->succ()) {
2103  if (stpMaster.isSolutionEdge(e)) {
2104  const node vO = e->source();
2105  node vC = finalSteinerTree->copy(vO);
2106  if (!vC) {
2107  vC = finalSteinerTree->newNode(vO);
2108  }
2109  const node wO = e->target();
2110  node wC = finalSteinerTree->copy(wO);
2111  if (!wC) {
2112  wC = finalSteinerTree->newNode(wO);
2113  }
2114  T edgeCost = G.weight(e);
2115  finalSteinerTree->newEdge(e, edgeCost);
2116  weight += edgeCost;
2117  }
2118  }
2119 
2120  return weight;
2121 }
2122 
2123 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:46
abacus::CSense::Greater
@ Greater
Definition: csense.h:51
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::m_coeffIn
double m_coeffIn
coefficient of ingoing edges
Definition: MinSteinerTreeDirectedCut.h:832
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MinSteinerTreeDirectedCut::Sub::m_computeBackCuts
bool m_computeBackCuts
Definition: MinSteinerTreeDirectedCut.h:712
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::equal
bool equal(const ConVar *cv) const override
tests if cuts are equal; required method for nonduplpool
Definition: MinSteinerTreeDirectedCut.h:2040
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::nMarkedNodes
int nMarkedNodes() const
the number of marked nodes
Definition: MinSteinerTreeDirectedCut.h:938
ogdf::MinSteinerTreeDirectedCut::Master::m_poolSizeMax
int m_poolSizeMax
maximal size of the pool
Definition: MinSteinerTreeDirectedCut.h:585
ogdf::MinSteinerTreeDirectedCut::Master::m_addIndegreeEdgeConstraints
bool m_addIndegreeEdgeConstraints
add constraints concerning the indegree of a node w.r.t. one outgoing edge: indeg(v) >= outgoing edge...
Definition: MinSteinerTreeDirectedCut.h:596
ogdf::MinSteinerTreeDirectedCut::Master::incNrCutsTotal
void incNrCutsTotal(int val)
increases the number of separated directed cuts
Definition: MinSteinerTreeDirectedCut.h:444
ogdf::MinSteinerTreeModule::isSteinerTree
static bool isSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, const EdgeWeightedGraphCopy< T > &steinerTree)
Checks in O(n) time if a given tree is acually a Steiner Tree.
Definition: MinSteinerTreeModule.h:420
ogdf::MinSTCutMaxFlow::setEpsilonTest
void setEpsilonTest(EpsilonTest *et)
Assigns a new epsilon test.
Definition: MinSTCutMaxFlow.h:117
Graph.h
Includes declaration of graph class.
MinSteinerTreeTakahashi.h
Implementation of the 2(1-1/l)-approximation algorithm for the minimum Steiner tree problem by Matsuy...
ogdf::MinSteinerTreeDirectedCut::Master::m_separationTimer
StopwatchWallClock m_separationTimer
timer for separation
Definition: MinSteinerTreeDirectedCut.h:640
ogdf::EdgeWeightedGraph::newEdge
edge newEdge(node v, node w, T weight)
Definition: EdgeWeightedGraph.h:47
ogdf::MinSteinerTreeDirectedCut::Master::initializeParameters
virtual void initializeParameters() override
read/set parameters from file
Definition: MinSteinerTreeDirectedCut.h:1128
abacus::NonDuplPool< abacus::Constraint, abacus::Variable >
ogdf::MinSteinerTreeDirectedCut::m_addFlowBalanceConstraints
bool m_addFlowBalanceConstraints
Definition: MinSteinerTreeDirectedCut.h:81
ogdf::EpsilonTest
Definition: EpsilonTest.h:41
ogdf::MinSteinerTreeDirectedCut::Master::rootNode
node rootNode() const
the designated root node (special terminal)
Definition: MinSteinerTreeDirectedCut.h:327
ogdf::MinSteinerTreeDirectedCut::m_callPrimalHeuristic
int m_callPrimalHeuristic
Definition: MinSteinerTreeDirectedCut.h:89
ogdf::MinSTCutMaxFlow::isFrontCutEdge
bool isFrontCutEdge(const edge e) const
Returns whether this edge is leaving the front cut.
Definition: MinSTCutMaxFlow.h:133
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint
Constraint for relating the indegree and one outgoing edge of a node.
Definition: MinSteinerTreeDirectedCut.h:839
ogdf::MinSteinerTreeDirectedCut::m_addGSEC2Constraints
bool m_addGSEC2Constraints
Definition: MinSteinerTreeDirectedCut.h:80
ogdf::MinSteinerTreeDirectedCut::Master::nEdgesU
int nEdgesU() const
returns number of undirected edges, i.e., nEdges()/2
Definition: MinSteinerTreeDirectedCut.h:324
abacus::BranchRule
Abstract base class for all branching rules.
Definition: branchrule.h:59
ogdf::MinSteinerTreeDirectedCut::Master::m_separationStrategy
int m_separationStrategy
parameter: separation strategy, only important if nested cuts are computed
Definition: MinSteinerTreeDirectedCut.h:616
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::DegreeConstraint
DegreeConstraint(abacus::Master *master, node n, double coeffIn, double coeffOut, abacus::CSense::SENSE sense, double rhs)
Definition: MinSteinerTreeDirectedCut.h:803
abacus.h
Includes Abacus.
ogdf::MinSteinerTreeDirectedCut::Master::getMaxFlowModule
MaxFlowModule< double > * getMaxFlowModule()
Get the maximum flow module used by separation algorithm.
Definition: MinSteinerTreeDirectedCut.h:235
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::source
node source() const
source node
Definition: MinSteinerTreeDirectedCut.h:757
ogdf::internal::gcm::tools::equal
bool equal(const node a, const node b)
Definition: Universal.h:42
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::MinSteinerTreeDirectedCut::Master::m_pCutPool
abacus::NonDuplPool< abacus::Constraint, abacus::Variable > * m_pCutPool
the non-duplicate cut pool for the directed Steiner cuts
Definition: MinSteinerTreeDirectedCut.h:579
ogdf::EdgeWeightedGraph::weight
T weight(const edge e) const
Definition: EdgeWeightedGraph.h:58
ogdf::Logger::Level::Minor
@ Minor
ogdf::StopwatchWallClock
Implements a stopwatch measuring wall-clock time.
Definition: Stopwatch.h:180
ogdf::MinSteinerTreeDirectedCut::Master::computeBackCuts
bool computeBackCuts() const
parameter: back cut computation
Definition: MinSteinerTreeDirectedCut.h:410
ogdf::MinSteinerTreeDirectedCut::Master::getNode
node getNode(int i) const
id -> node
Definition: MinSteinerTreeDirectedCut.h:363
abacus::Constraint::rhs
virtual double rhs() const
Returns the right hand side of the constraint.
Definition: constraint.h:130
ogdf::MinSteinerTreeDirectedCut::Master::solutionValue
double solutionValue() const
solution value after solving the problem, i.e., returns final primal bound
Definition: MinSteinerTreeDirectedCut.h:387
ogdf::MinSteinerTreeDirectedCut::Sub::Sub
Sub(abacus::Master *master)
Constructor for the root problem of the b&b tree.
Definition: MinSteinerTreeDirectedCut.h:1435
ogdf::MinSteinerTreeDirectedCut::Master::m_edgesWgToGPH
EdgeArray< edge > m_edgesWgToGPH
edge mapping m_pWeightedGraphPH -> m_pGraph
Definition: MinSteinerTreeDirectedCut.h:574
ogdf::MinSteinerTreeDirectedCut::Sub::m_alreadySeparated
int m_alreadySeparated
nr of already separated cuts, default is -1
Definition: MinSteinerTreeDirectedCut.h:701
ogdf::MinSteinerTreeDirectedCut::Master::edgeID
int edgeID(edge e) const
edge -> id of lp variable
Definition: MinSteinerTreeDirectedCut.h:345
ogdf::MinSteinerTreeDirectedCut::Master::m_relaxedSolValue
double m_relaxedSolValue
statistics: solution value of the relaxed master problem
Definition: MinSteinerTreeDirectedCut.h:510
ogdf::MinSteinerTreeDirectedCut::Master::terminalListPH
const List< node > & terminalListPH() const
list of terminals (in m_pWeightedGraphPH)
Definition: MinSteinerTreeDirectedCut.h:463
ogdf::MinSteinerTreeDirectedCut::Master::m_addDegreeConstraints
bool m_addDegreeConstraints
parameter: add constraints concerning the indegree of a node, like: indeg <= 1 for all vertices
Definition: MinSteinerTreeDirectedCut.h:594
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::DegreeEdgeConstraint
DegreeEdgeConstraint(abacus::Master *master, edge e, double coeffIn, double coeffEdge, abacus::CSense::SENSE sense, double rhs)
Definition: MinSteinerTreeDirectedCut.h:841
ogdf::MinSteinerTreeDirectedCut::Master::getPrimalHeuristic
std::unique_ptr< MinSteinerTreeModule< double > > & getPrimalHeuristic()
the primal heuristic module
Definition: MinSteinerTreeDirectedCut.h:298
ogdf::EdgeWeightedGraphCopy::setOriginalGraph
void setOriginalGraph(const Graph *wG) override
Associates the graph copy with G, but does not create any nodes or edges.
Definition: EdgeWeightedGraphCopy.h:158
ogdf::MinSteinerTreeDirectedCut::useGSEC2Constraints
void useGSEC2Constraints(bool b)
Switch usage of constraints x_uv + x_vu <= 1 on or off.
Definition: MinSteinerTreeDirectedCut.h:124
ogdf::MinSteinerTreeDirectedCut::useFlowBalanceConstraints
void useFlowBalanceConstraints(bool b)
Switch usage of flow balance constraints on or off.
Definition: MinSteinerTreeDirectedCut.h:127
ogdf::List::popFrontRet
E popFrontRet()
Removes the first element from the list and returns it.
Definition: List.h:1581
ogdf::MinSteinerTreeDirectedCut::Master::updateBestSolution
void updateBestSolution(double *values)
updates best found solution
Definition: MinSteinerTreeDirectedCut.h:1410
ogdf::MinSTCutMaxFlow::frontCutIsComplementOfBackCut
bool frontCutIsComplementOfBackCut() const
Returns whether the front cut is the complement of the backcut.
Definition: MinSTCutMaxFlow.h:125
ogdf::MinSteinerTreeDirectedCut::Master::m_callPrimalHeuristic
int m_callPrimalHeuristic
parameter: primal heuristic (PH) call strategy
Definition: MinSteinerTreeDirectedCut.h:637
ogdf::MinSteinerTreeDirectedCut::Master::Master
Master(const EdgeWeightedGraph< T > &wG, const List< node > &terminals, const NodeArray< bool > &isTerminal, double eps, bool relaxed=false)
Constructor of the master problem.
Definition: MinSteinerTreeDirectedCut.h:973
ogdf::MinSTCutMaxFlow::isBackCutEdge
bool isBackCutEdge(const edge e) const
Returns whether this edge is entering the back cut.
Definition: MinSTCutMaxFlow.h:142
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::m_edge
edge m_edge
the associated edge
Definition: MinSteinerTreeDirectedCut.h:873
ogdf::MinSteinerTreeDirectedCut::Master::nrCutsTotal
int nrCutsTotal() const
total number of separated directed cuts
Definition: MinSteinerTreeDirectedCut.h:450
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::m_coeffEdge
double m_coeffEdge
coefficient of the edge
Definition: MinSteinerTreeDirectedCut.h:877
ogdf::EdgeElement::isParallelDirected
bool isParallelDirected(edge e) const
Returns true iff edge e is parallel to this (directed) edge (or if it is the same edge)
Definition: Graph_d.h:418
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::name
const char * name() const override
return the name of the cut; required method for nonduplpool
Definition: MinSteinerTreeDirectedCut.h:950
ogdf::MinSteinerTreeDirectedCut::Sub::feasible
virtual bool feasible() override
checks if the current solution is feasible, i.e., calls mySeparate()
Definition: MinSteinerTreeDirectedCut.h:1500
ogdf::MinSteinerTreeDirectedCut::m_nestedCutComputation
bool m_nestedCutComputation
Definition: MinSteinerTreeDirectedCut.h:85
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::theEdge
edge theEdge() const
the associated edge
Definition: MinSteinerTreeDirectedCut.h:748
abacus::Sub::master
Master * master()
Returns the master of the optimization.
Definition: sub.h:320
abacus
Definition: abacusroot.h:48
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint::coeff
double coeff(const abacus::Variable *v) const override
coefficient of variable in constraint
Definition: MinSteinerTreeDirectedCut.h:781
ogdf::MinSteinerTreeDirectedCut::MinSteinerTreeDirectedCut
MinSteinerTreeDirectedCut()
Definition: MinSteinerTreeDirectedCut.h:163
ogdf::MinSteinerTreeDirectedCut::Master::m_maxFlowModule
MaxFlowModule< double > * m_maxFlowModule
Definition: MinSteinerTreeDirectedCut.h:498
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::m_marked
NodeArray< bool > m_marked
defines if a vertex is on the left side of the cut (false) or not
Definition: MinSteinerTreeDirectedCut.h:961
ogdf::MinSteinerTreeDirectedCut::m_addDegreeConstraints
bool m_addDegreeConstraints
Definition: MinSteinerTreeDirectedCut.h:78
ogdf::MinSteinerTreeDirectedCut::Master::edgeGToWgPH
edge edgeGToWgPH(edge e) const
edge mapping m_pGraph -> m_pWeightedGraphPH
Definition: MinSteinerTreeDirectedCut.h:472
ogdf::Logger::Level
Level
supported log-levels from lowest to highest importance
Definition: Logger.h:103
ogdf::MinSteinerTreeDirectedCut::Master::m_terminals
node * m_terminals
terminal index -> terminal node
Definition: MinSteinerTreeDirectedCut.h:551
ogdf::MinSteinerTreeDirectedCut::Master::m_nEdgesU
int m_nEdgesU
number of undirected edges
Definition: MinSteinerTreeDirectedCut.h:522
ogdf::MinSteinerTreeDirectedCut::Master::m_edgeIDs
EdgeArray< int > m_edgeIDs
edge -> id
Definition: MinSteinerTreeDirectedCut.h:526
ogdf::MinSteinerTreeDirectedCut::m_separationStrategy
int m_separationStrategy
Definition: MinSteinerTreeDirectedCut.h:86
ogdf::EdgeWeightedGraphCopy::newEdge
edge newEdge(node u, node v, T weight)
Definition: EdgeWeightedGraphCopy.h:165
opensub.h
open subproblems.
ogdf::MinSteinerTreeDirectedCut::Master::useFlowBalanceConstraints
void useFlowBalanceConstraints(bool b)
Switch usage of flow balance constraints on or off.
Definition: MinSteinerTreeDirectedCut.h:247
ogdf::MinSteinerTreeDirectedCut::Master::relaxed
bool relaxed() const
solve relaxed LP or ILP
Definition: MinSteinerTreeDirectedCut.h:384
ogdf::MinSteinerTreeDirectedCut::setConfigFile
void setConfigFile(const char *configfile)
Set a configuration file to use. The contents of the configuration file can override all other used o...
Definition: MinSteinerTreeDirectedCut.h:109
ogdf::MinSteinerTreeDirectedCut::Sub::m_saturationStrategy
int m_saturationStrategy
Definition: MinSteinerTreeDirectedCut.h:710
ogdf::Logger::Level::Default
@ Default
ogdf::MinSteinerTreeDirectedCut::Master::terminals
const node * terminals() const
terminals in an array
Definition: MinSteinerTreeDirectedCut.h:333
ogdf::MinSteinerTreeDirectedCut::useBackCuts
void useBackCuts(bool b)
Switch computation of back-cuts on or off.
Definition: MinSteinerTreeDirectedCut.h:136
ogdf::MinSteinerTreeDirectedCut::Master::primalHeuristicTimer
StopwatchWallClock * primalHeuristicTimer()
timer for primal heuristics
Definition: MinSteinerTreeDirectedCut.h:487
ogdf::MaxFlowGoldbergTarjan
Computes a max flow via Preflow-Push (global relabeling and gap relabeling heuristic).
Definition: MaxFlowGoldbergTarjan.h:53
ogdf::MinSteinerTreeDirectedCut::Master::checkSetMaxPoolSize
void checkSetMaxPoolSize()
checks if current pool size is maximum and sets it if necessary
Definition: MinSteinerTreeDirectedCut.h:434
ogdf::MinSteinerTreeDirectedCut::Master::m_wG
const EdgeWeightedGraph< T > & m_wG
the original weighted graph
Definition: MinSteinerTreeDirectedCut.h:516
ogdf::MinSteinerTreeDirectedCut::Master::callPrimalHeuristicStrategy
int callPrimalHeuristicStrategy() const
strategy for calling primal heuristic (PH)
Definition: MinSteinerTreeDirectedCut.h:419
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::theEdge
edge theEdge() const
the associated edge
Definition: MinSteinerTreeDirectedCut.h:869
abacus::Sub::nIter_
int nIter_
The number of iterations in the cutting plane phase.
Definition: sub.h:1479
ogdf::MinSteinerTreeDirectedCut::Master::m_backCutComputation
bool m_backCutComputation
parameter: compute back cuts yes/no i.e., outgoing edges of the root-set
Definition: MinSteinerTreeDirectedCut.h:605
ogdf::MinSteinerTreeDirectedCut::Master::twin
edge twin(edge e) const
the twin edge, i.e. twin[(u,v)] = (v,u)
Definition: MinSteinerTreeDirectedCut.h:372
ogdf::MinSteinerTreeDirectedCut::Master::getVar
EdgeVariable * getVar(edge e) const
returns the variable assigned to edge e
Definition: MinSteinerTreeDirectedCut.h:378
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::m_coeffOut
double m_coeffOut
coefficient of outgoing edges
Definition: MinSteinerTreeDirectedCut.h:834
ogdf::MinSteinerTreeDirectedCut::Sub::m_shuffleTerminals
bool m_shuffleTerminals
Definition: MinSteinerTreeDirectedCut.h:714
ogdf::MinSteinerTreeDirectedCut::m_maxFlowModuleOption
std::unique_ptr< MaxFlowModule< double > > m_maxFlowModuleOption
Definition: MinSteinerTreeDirectedCut.h:77
ogdf::MinSteinerTreeDirectedCut::setPrimalHeuristicCallStrategy
void setPrimalHeuristicCallStrategy(int b)
Set primal heuristic call strategy.
Definition: MinSteinerTreeDirectedCut.h:154
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::m_nMarkedNodes
int m_nMarkedNodes
number of marked nodes
Definition: MinSteinerTreeDirectedCut.h:964
ogdf::MinSteinerTreeDirectedCut::m_shuffleTerminals
bool m_shuffleTerminals
Definition: MinSteinerTreeDirectedCut.h:83
ogdf::MinSteinerTreeDirectedCut::Master::m_minCardinalityCuts
bool m_minCardinalityCuts
parameter: compute minimum cardinality cuts
Definition: MinSteinerTreeDirectedCut.h:629
ogdf::MinSteinerTreeDirectedCut::Master::m_mapToOrigGraph
EdgeArray< edge > m_mapToOrigGraph
the undirected edge in the original graph for each arc in m_pGraph
Definition: MinSteinerTreeDirectedCut.h:536
ogdf::MinSteinerTreeDirectedCut::Master::m_edgesGToWgPH
EdgeArray< edge > m_edgesGToWgPH
edge mapping m_pGraph -> m_pWeightedGraphPH
Definition: MinSteinerTreeDirectedCut.h:572
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::active
bool active(node n) const
returns true iff the node n is separated by this cut
Definition: MinSteinerTreeDirectedCut.h:932
ogdf::MinSteinerTreeDirectedCut::Master::nodeIDs
const NodeArray< int > & nodeIDs() const
lp variable ids of nodes
Definition: MinSteinerTreeDirectedCut.h:354
ogdf::MinSteinerTreeDirectedCut::Master::m_nIterRoot
int m_nIterRoot
statistics: nr of iterations in the root node of the b&b tree
Definition: MinSteinerTreeDirectedCut.h:513
ogdf::MinSteinerTreeDirectedCut::Master::m_mapToBidirectedGraph2
EdgeArray< edge > m_mapToBidirectedGraph2
the second directed arc in m_pGraph for an original edge
Definition: MinSteinerTreeDirectedCut.h:540
ogdf::Logger::Level::Medium
@ Medium
ogdf::MinSteinerTreeDirectedCut::Master::edgeWgToGPH
edge edgeWgToGPH(edge e) const
edge mapping m_pWeightedGraphPH -> m_pGraph
Definition: MinSteinerTreeDirectedCut.h:475
ogdf::MinSteinerTreeDirectedCut::Master::m_primalHeuristicTimer
StopwatchWallClock m_primalHeuristicTimer
timer for primal heuristics
Definition: MinSteinerTreeDirectedCut.h:644
ogdf::MinSteinerTreeDirectedCut::Master::maxNrAddedCuttingPlanes
int maxNrAddedCuttingPlanes() const
maximum nr of cutting planes
Definition: MinSteinerTreeDirectedCut.h:404
Logger.h
Contains logging functionality.
EdgeWeightedGraphCopy.h
Extends the GraphCopy concept to weighted graphs.
ogdf::MinSteinerTreeDirectedCut::Master::setPrimalHeuristicCallStrategy
void setPrimalHeuristicCallStrategy(int b)
Set primal heuristic call strategy.
Definition: MinSteinerTreeDirectedCut.h:283
ogdf::MinSteinerTreeDirectedCut::Master::m_maxNrAddedCuttingPlanes
int m_maxNrAddedCuttingPlanes
parameter: maximum nr of cutting planes per iteration
Definition: MinSteinerTreeDirectedCut.h:601
abacus::CSense::Equal
@ Equal
Definition: csense.h:51
abacus::Master::defaultLpSolver
OSISOLVER defaultLpSolver() const
returns the Lp Solver.
Definition: master.h:533
ogdf::AlgorithmFailureException
Exception thrown when an algorithm realizes an internal bug that prevents it from continuing.
Definition: exceptions.h:243
ogdf::MinSteinerTreeModule
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
Definition: MinSteinerTreeModule.h:59
ogdf::MinSteinerTreeDirectedCut::setPrimalHeuristic
void setPrimalHeuristic(MinSteinerTreeModule< double > *b)
Set the module option for the primal heuristic (use MinSteinerTreeModule<double> types)....
Definition: MinSteinerTreeDirectedCut.h:151
ogdf::MinSteinerTreeDirectedCut::Master::incNrCutsTotal
void incNrCutsTotal()
increases the number of separated directed cuts by 1
Definition: MinSteinerTreeDirectedCut.h:447
ogdf::MinSteinerTreeDirectedCut::Master::edgeIDs
const EdgeArray< int > & edgeIDs() const
lp variable ids of edges
Definition: MinSteinerTreeDirectedCut.h:357
ogdf::MinSteinerTreeDirectedCut::Master::m_isTerminal
NodeArray< bool > m_isTerminal
node is terminal yes/no
Definition: MinSteinerTreeDirectedCut.h:547
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::coeff
double coeff(const abacus::Variable *v) const override
Returns the coefficient of the variable v in the constraint.
Definition: MinSteinerTreeDirectedCut.h:2057
ogdf::MinSteinerTreeDirectedCut::Master::m_mapToBidirectedGraph1
EdgeArray< edge > m_mapToBidirectedGraph1
the first directed arc in m_pGraph for an original edge
Definition: MinSteinerTreeDirectedCut.h:538
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::m_id
int m_id
id of the edge
Definition: MinSteinerTreeDirectedCut.h:766
ogdf::MinSteinerTreeDirectedCut::Master::useDegreeConstraints
void useDegreeConstraints(bool b)
Switch usage of degree constraints (like indeg <= 1) on or off.
Definition: MinSteinerTreeDirectedCut.h:238
ogdf::MinSteinerTreeDirectedCut::Master::graph
const Graph & graph() const
the directed graph, i.e., the bidirection of the input graph
Definition: MinSteinerTreeDirectedCut.h:315
ogdf::MinSTCutMaxFlow::call
virtual bool call(const Graph &graph, const EdgeArray< TCost > &weight, node s, node t, List< edge > &edgeList, edge e_st=nullptr) override
The actual algorithm call.
Definition: MinSTCutMaxFlow.h:310
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint
Constraint for nodes, e.g., in/outdegree stuff.
Definition: MinSteinerTreeDirectedCut.h:801
ogdf::MaxFlowModule::computeFlow
T computeFlow(EdgeArray< T > &cap, node &s, node &t, EdgeArray< T > &flow)
Only a shortcut for computeValue and computeFlowAfterValue.
Definition: MaxFlowModule.h:164
ogdf::MinSteinerTreeDirectedCut::Master::computeNestedCuts
bool computeNestedCuts() const
parameter: nested cut computation
Definition: MinSteinerTreeDirectedCut.h:407
ogdf::MinSteinerTreeDirectedCut::Sub::m_computeNestedCuts
bool m_computeNestedCuts
Definition: MinSteinerTreeDirectedCut.h:706
ogdf::AlgorithmFailureCode::Constraint
@ Constraint
r
int r[]
Definition: hierarchical-ranking.cpp:8
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:924
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::cutedge
bool cutedge(edge e) const
returns true iff the edge is contained in the cut
Definition: MinSteinerTreeDirectedCut.h:935
ogdf::EdgeElement::isSelfLoop
bool isSelfLoop() const
Returns true iff the edge is a self-loop (source node = target node).
Definition: Graph_d.h:412
ogdf::MinSteinerTreeDirectedCut::Master::nTerminals
int nTerminals() const
number of terminals
Definition: MinSteinerTreeDirectedCut.h:330
ogdf::MinSteinerTreeDirectedCut::Master::shuffleTerminals
bool shuffleTerminals() const
shuffle ordering of terminals before each separation routine
Definition: MinSteinerTreeDirectedCut.h:428
ogdf::Graph::numberOfEdges
int numberOfEdges() const
Returns the number of edges in the graph.
Definition: Graph_d.h:977
ogdf::MinSteinerTreeDirectedCut::useTerminalShuffle
void useTerminalShuffle(bool b)
Switch terminal shuffling before separation on or off.
Definition: MinSteinerTreeDirectedCut.h:133
ogdf::MinSteinerTreeDirectedCut::Master::maxPoolSize
int maxPoolSize() const
the maximum pool size during the algorithm
Definition: MinSteinerTreeDirectedCut.h:431
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint::m_e2
edge m_e2
twin of m_e1, i.e., if m_e1 = (u,v) it holds m_e2 = (v,u)
Definition: MinSteinerTreeDirectedCut.h:794
ogdf::MinSteinerTreeDirectedCut::Master::m_configfile
const char * m_configfile
problem dependent config file
Definition: MinSteinerTreeDirectedCut.h:501
ogdf::NodeElement::degree
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition: Graph_d.h:276
ogdf::MinSteinerTreeDirectedCut::Master::poolSizeInit
int poolSizeInit() const
initial pool size
Definition: MinSteinerTreeDirectedCut.h:441
ogdf::MinSteinerTreeDirectedCut::Master::minCardinalityCuts
bool minCardinalityCuts() const
parameter: compute minimum cardinality cuts
Definition: MinSteinerTreeDirectedCut.h:413
ogdf::Graph::numberOfNodes
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition: Graph_d.h:974
abacus::Master::OSISOLVER_
static const char * OSISOLVER_[]
Array for the literal values for possible Osi solvers.
Definition: master.h:212
ogdf::MinSteinerTreeDirectedCut::computeSteinerTree
virtual T computeSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Computes the actual Steiner tree.
Definition: MinSteinerTreeDirectedCut.h:2066
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint
Constraint for edges, e.g., subtour elimination constraints of size 2 ((G)SEC2)
Definition: MinSteinerTreeDirectedCut.h:771
ogdf::EdgeWeightedGraph
Definition: EdgeWeightedGraph.h:39
ogdf::MinSteinerTreeDirectedCut::Master::m_isTerminalPH
NodeArray< bool > m_isTerminalPH
is terminal yes/no (in m_pWeightedGraphPH)
Definition: MinSteinerTreeDirectedCut.h:568
ogdf::MinSteinerTreeDirectedCut::Master::m_saturationStrategy
int m_saturationStrategy
parameter: saturation strategy, only important if nested cuts are computed
Definition: MinSteinerTreeDirectedCut.h:623
ogdf::MinSteinerTreeDirectedCut::Master::nNodes
int nNodes() const
number of nodes of the graph
Definition: MinSteinerTreeDirectedCut.h:318
ogdf::Array< node >
ogdf::MinSteinerTreeDirectedCut::Master::m_shuffleTerminals
bool m_shuffleTerminals
parameter: shuffle the list of terminals right before separation
Definition: MinSteinerTreeDirectedCut.h:603
ogdf::MinSteinerTreeDirectedCut::Master
Master problem of Steiner tree branch&cut algorithm
Definition: MinSteinerTreeDirectedCut.h:193
ogdf::MinSteinerTreeDirectedCut::Master::isTerminal
bool isTerminal(node n) const
true if n is a terminal
Definition: MinSteinerTreeDirectedCut.h:339
ogdf::MinSteinerTreeDirectedCut::Master::getVarTwin
EdgeVariable * getVarTwin(edge e) const
returns the variable assigned to the twin of edge e
Definition: MinSteinerTreeDirectedCut.h:381
ogdf::MinSteinerTreeDirectedCut::Master::useTerminalShuffle
void useTerminalShuffle(bool b)
Switch terminal shuffling before separation on or off.
Definition: MinSteinerTreeDirectedCut.h:257
ogdf::MaxFlowModule::useEpsilonTest
void useEpsilonTest(const double &eps)
Change the used EpsilonTest from StandardEpsilonTest to a user given EpsilonTest.
Definition: MaxFlowModule.h:109
ogdf::MinSteinerTreeDirectedCut::Master::m_nrCutsTotal
int m_nrCutsTotal
total number of separated directed cuts
Definition: MinSteinerTreeDirectedCut.h:589
ogdf::MinSteinerTreeDirectedCut::Sub::m_callPrimalHeuristic
int m_callPrimalHeuristic
Strategy for primal heuristic (PH) calls.
Definition: MinSteinerTreeDirectedCut.h:724
ogdf::MinSteinerTreeDirectedCut::Master::m_pWeightedGraphPH
EdgeWeightedGraph< double > * m_pWeightedGraphPH
edge weighted bidirected graph; used and modified for primal heuristics
Definition: MinSteinerTreeDirectedCut.h:564
ogdf::MinSteinerTreeDirectedCut::Master::saturationStrategy
int saturationStrategy() const
strategy for saturating edges during separation; Only relevant for nested cuts
Definition: MinSteinerTreeDirectedCut.h:425
ogdf::MinSteinerTreeDirectedCut::Master::capacities
double capacities(edge e) const
costs for edge e
Definition: MinSteinerTreeDirectedCut.h:369
ogdf::MinSteinerTreeDirectedCut::Master::m_pGraph
Graph * m_pGraph
the bidirected graph
Definition: MinSteinerTreeDirectedCut.h:519
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:209
ogdf::MinSteinerTreeDirectedCut::Master::isTerminal
const NodeArray< bool > isTerminal() const
boolean array of terminal status
Definition: MinSteinerTreeDirectedCut.h:342
ogdf::MinSteinerTreeDirectedCut::m_backCutComputation
bool m_backCutComputation
Definition: MinSteinerTreeDirectedCut.h:84
ogdf::MinSteinerTreeDirectedCut::Sub::m_pMaster
Master * m_pMaster
the master problem of the b&c algorithm
Definition: MinSteinerTreeDirectedCut.h:698
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::coeff
virtual double coeff(const abacus::Variable *v) const override
coefficient of variable in constraint
Definition: MinSteinerTreeDirectedCut.h:811
ogdf::MinSteinerTreeDirectedCut::useMinCardinalityCuts
void useMinCardinalityCuts(bool b)
Switch usage of the cardinality heuristic (minimum-cardinality cuts) on or off.
Definition: MinSteinerTreeDirectedCut.h:148
ogdf::MinSteinerTreeDirectedCut::Master::m_nodeIDs
NodeArray< int > m_nodeIDs
node -> id
Definition: MinSteinerTreeDirectedCut.h:545
ogdf::MinSteinerTreeDirectedCut::Master::nEdges
int nEdges() const
returns the number of edges
Definition: MinSteinerTreeDirectedCut.h:321
abacus::Variable
Forms the virtual base class for all possible variables given in pool format.
Definition: variable.h:59
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::GraphCopyBase::newNode
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Definition: GraphCopy.h:185
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: List.h:42
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::MinSteinerTreeDirectedCut::Master::m_poolSizeInitFactor
int m_poolSizeInitFactor
parameter: factor for the initial size of the cutting pool
Definition: MinSteinerTreeDirectedCut.h:581
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
abacus::VarType::Binary
@ Binary
A variable having value 0 or 1.
Definition: vartype.h:50
ogdf::MinSteinerTreeDirectedCut::Master::setMaxFlowModule
void setMaxFlowModule(MaxFlowModule< double > *module)
Set the maximum flow module to be used for separation.
Definition: MinSteinerTreeDirectedCut.h:232
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::m_hashKey
unsigned int m_hashKey
hashkey of the cut; required method for nonduplpool
Definition: MinSteinerTreeDirectedCut.h:967
abacus::Constraint::sense
CSense * sense()
Returns a pointer to the sense of the constraint.
Definition: constraint.h:115
ogdf::Logger::Level::High
@ High
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::marked
bool marked(node n) const
returns status of node n
Definition: MinSteinerTreeDirectedCut.h:941
abacus::Sub::id
int id() const
Returns the identity number of the subproblem.
Definition: sub.h:153
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint::m_factor
int m_factor
factor for edge coefficients in the constraint
Definition: MinSteinerTreeDirectedCut.h:796
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::m_coeffIn
double m_coeffIn
coefficient of ingoing edges
Definition: MinSteinerTreeDirectedCut.h:875
ogdf::MinSteinerTreeDirectedCut::Master::rootNodePH
node rootNodePH() const
root node (in m_pWeightedGraphPH)
Definition: MinSteinerTreeDirectedCut.h:469
ogdf::MinSteinerTreeDirectedCut::Master::m_nodes
node * m_nodes
id -> node
Definition: MinSteinerTreeDirectedCut.h:543
ogdf::MinSteinerTreeDirectedCut::m_maxNrAddedCuttingPlanes
int m_maxNrAddedCuttingPlanes
Definition: MinSteinerTreeDirectedCut.h:82
ogdf::MinSteinerTreeDirectedCut::Master::useMinCardinalityCuts
void useMinCardinalityCuts(bool b)
Switch usage of the cardinality heuristic (minimum-cardinality cuts) on or off.
Definition: MinSteinerTreeDirectedCut.h:280
ogdf::MinSteinerTreeDirectedCut::Master::getEdge
edge getEdge(int i) const
id -> edge
Definition: MinSteinerTreeDirectedCut.h:360
ogdf::MinSteinerTreeDirectedCut::useIndegreeEdgeConstraints
void useIndegreeEdgeConstraints(bool b)
Switch usage of indegree edge constraints (indeg(v) >= outgoing edge(v,x) for all x) on or off.
Definition: MinSteinerTreeDirectedCut.h:121
ogdf::MinSteinerTreeDirectedCut::Sub::myImprove
void myImprove()
primal heuristic procedure
Definition: MinSteinerTreeDirectedCut.h:1875
ogdf::GraphCopy::copy
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition: GraphCopy.h:457
ogdf::MinSteinerTreeDirectedCut::Master::m_root
node m_root
the virtual root of our graph. This node is a terminal.
Definition: MinSteinerTreeDirectedCut.h:554
ogdf::MinSteinerTreeDirectedCut::Master::m_timerMinSTCut
StopwatchWallClock m_timerMinSTCut
timer for minimum st-cut computations. Measures updates + algorithm
Definition: MinSteinerTreeDirectedCut.h:642
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::m_edge
edge m_edge
the edge
Definition: MinSteinerTreeDirectedCut.h:764
ogdf::MinSteinerTreeDirectedCut::Master::m_bestSolution
double * m_bestSolution
best found solution
Definition: MinSteinerTreeDirectedCut.h:557
ogdf::MinSteinerTreeDirectedCut::setMaxFlowModule
void setMaxFlowModule(MaxFlowModule< double > *module)
Set the maximum flow module to be used for separation.
Definition: MinSteinerTreeDirectedCut.h:115
abacus::Master::optimize
STATUS optimize()
Performs the optimization by branch-and-bound.
ogdf::MinSteinerTreeDirectedCut::Master::callPrimalHeuristic
bool callPrimalHeuristic() const
parameter: call primal heuristic yes/no
Definition: MinSteinerTreeDirectedCut.h:416
ogdf::MinSteinerTreeDirectedCut::Master::m_rootPH
node m_rootPH
root node in m_pWeightedGraphPH
Definition: MinSteinerTreeDirectedCut.h:576
ogdf::MinSteinerTreeDirectedCut::m_saturationStrategy
int m_saturationStrategy
Definition: MinSteinerTreeDirectedCut.h:87
ogdf::MinSteinerTreeDirectedCut::Master::cutPool
abacus::NonDuplPool< abacus::Constraint, abacus::Variable > * cutPool()
the non-duplicate cutpool for the separated Steiner cuts
Definition: MinSteinerTreeDirectedCut.h:303
ogdf::MinSteinerTreeDirectedCut::m_poolSizeInitFactor
int m_poolSizeInitFactor
Definition: MinSteinerTreeDirectedCut.h:91
ogdf::MinSteinerTreeDirectedCut::Master::m_poolSizeInit
int m_poolSizeInit
size of initial pool
Definition: MinSteinerTreeDirectedCut.h:583
ogdf::MinSteinerTreeDirectedCut::m_addIndegreeEdgeConstraints
bool m_addIndegreeEdgeConstraints
Definition: MinSteinerTreeDirectedCut.h:79
ogdf::MaxFlowModule::init
virtual void init(const Graph &graph, EdgeArray< T > *flow=nullptr)
Initialize the problem with a graph and optional flow array. If no flow array is given,...
Definition: MaxFlowModule.h:87
ogdf::MinSteinerTreeDirectedCut::Sub::separate
virtual int separate() override
calls mySeparate() if mySeparate wasn't called in another procedure
Definition: MinSteinerTreeDirectedCut.h:672
ogdf::MinSteinerTreeDirectedCut::Sub
Subproblem of Steiner tree algorithm.
Definition: MinSteinerTreeDirectedCut.h:652
ogdf::MinSteinerTreeDirectedCut::Master::weightedGraphPH
EdgeWeightedGraph< double > & weightedGraphPH()
Definition: MinSteinerTreeDirectedCut.h:460
abacus::Constraint::coeff
virtual double coeff(const Variable *v) const =0
Returns the coefficient of the variable v in the constraint.
ogdf::MinSteinerTreeDirectedCut::Master::setMaxNumberAddedCuttingPlanes
void setMaxNumberAddedCuttingPlanes(int b)
Set maximum number of added cutting planes per iteration.
Definition: MinSteinerTreeDirectedCut.h:250
ogdf::MinSteinerTreeDirectedCut
This class implements the Directed Cut Integer Linear Program for the Steiner tree problem.
Definition: MinSteinerTreeDirectedCut.h:69
ogdf::MinSteinerTreeDirectedCut::Master::m_addFlowBalanceConstraints
bool m_addFlowBalanceConstraints
parameter: add flow balance constraints for Steiner nodes n: outdeg(n) >= indeg(n)
Definition: MinSteinerTreeDirectedCut.h:598
ogdf::MinSteinerTreeDirectedCut::Master::setSeparationStrategy
void setSeparationStrategy(int b)
Set separation strategy for nested cuts.
Definition: MinSteinerTreeDirectedCut.h:266
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
ogdf::MinSteinerTreeDirectedCut::Master::separationTimer
StopwatchWallClock * separationTimer()
timer for separation
Definition: MinSteinerTreeDirectedCut.h:481
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::coefficient
double coefficient() const
objective function coefficient
Definition: MinSteinerTreeDirectedCut.h:754
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::hashKey
unsigned hashKey() const override
retuns an hashkey for the cut; required method for nonduplpool
Definition: MinSteinerTreeDirectedCut.h:944
ogdf::MinSteinerTreeDirectedCut::setEpsilon
void setEpsilon(double eps)
Set the epsilon for the LP.
Definition: MinSteinerTreeDirectedCut.h:106
ogdf::MinSteinerTreeDirectedCut::Master::useBackCuts
void useBackCuts(bool b)
Switch computation of back-cuts on or off.
Definition: MinSteinerTreeDirectedCut.h:260
ogdf::MinSteinerTreeTakahashi
This class implements the minimum Steiner tree 2-approximation algorithm by Takahashi and Matsuyama w...
Definition: MinSteinerTreeTakahashi.h:57
ogdf::AlgorithmFailureCode::Variable
@ Variable
ogdf::MinSTCutMaxFlow::cutType
cutType
The three types of cuts.
Definition: MinSTCutMaxFlow.h:108
ogdf::MinSteinerTreeDirectedCut::Master::firstSub
virtual abacus::Sub * firstSub() override
generates the first subproblem
Definition: MinSteinerTreeDirectedCut.h:306
ogdf::MinSteinerTreeDirectedCut::Master::m_nodesGToWgPH
NodeArray< node > m_nodesGToWgPH
node mapping m_pGraph -> m_pWeightedGraphPH
Definition: MinSteinerTreeDirectedCut.h:570
EdgeWeightedGraph.h
Declaration of class EdgeWeightedGraph.
ogdf::MinSteinerTreeDirectedCut::Master::terminal
node terminal(int i) const
get terminal with index i
Definition: MinSteinerTreeDirectedCut.h:336
ogdf::MinSteinerTreeDirectedCut::Master::useIndegreeEdgeConstraints
void useIndegreeEdgeConstraints(bool b)
Switch usage of indegree edge constraints (indeg(v) >= outgoing edge(v,x) for all x) on or off.
Definition: MinSteinerTreeDirectedCut.h:241
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::theNode
node theNode() const
the associated node
Definition: MinSteinerTreeDirectedCut.h:826
ogdf::MinSteinerTreeDirectedCut::Master::m_capacities
EdgeArray< double > m_capacities
edge costs
Definition: MinSteinerTreeDirectedCut.h:531
ogdf::MinSteinerTreeDirectedCut::Master::setNIterRoot
void setNIterRoot(int val)
nr of iterations in the root node
Definition: MinSteinerTreeDirectedCut.h:401
ogdf::MinSteinerTreeDirectedCut::m_eps
double m_eps
Definition: MinSteinerTreeDirectedCut.h:73
ogdf::MinSteinerTreeDirectedCut::Master::m_edgeToVar
EdgeArray< EdgeVariable * > m_edgeToVar
edge -> lp variable
Definition: MinSteinerTreeDirectedCut.h:533
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::DirectedCutConstraint
DirectedCutConstraint(abacus::Master *master, const Graph &g, const MinSTCutMaxFlow< double > *minSTCut, MinSTCutMaxFlow< double >::cutType _cutType)
Definition: MinSteinerTreeDirectedCut.h:884
abacus::Sub
The subproblem.
Definition: sub.h:68
abacus::Constraint
Forms the virtual base class for all possible constraints given in pool format.
Definition: constraint.h:56
ogdf::MinSteinerTreeDirectedCut::Master::initializeOptimization
virtual void initializeOptimization() override
insert variables and base constraints
Definition: MinSteinerTreeDirectedCut.h:1190
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint::m_e1
edge m_e1
base edge and twin of m_e2, i.e., if m_e1 = (u,v) it holds m_e2 = (v,u)
Definition: MinSteinerTreeDirectedCut.h:792
ogdf::MaxFlowModule< double >
ogdf::MinSteinerTreeDirectedCut::Master::m_relaxed
bool m_relaxed
parameter: indicates whether we solve the relaxed problem (LP) or the ILP
Definition: MinSteinerTreeDirectedCut.h:507
ogdf::Graph::newNode
node newNode(int index=-1)
Creates a new node and returns it.
Definition: Graph_d.h:1056
ogdf::MinSteinerTreeDirectedCut::Master::m_maxPoolSize
int m_maxPoolSize
statistic number of cuts in pool
Definition: MinSteinerTreeDirectedCut.h:587
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:40
ogdf::MinSteinerTreeDirectedCut::Master::setRelaxedSolValue
void setRelaxedSolValue(double val)
solution value of the root
Definition: MinSteinerTreeDirectedCut.h:398
MinSTCutMaxFlow.h
Declaration of min-st-cut algorithms parameterized by max-flow alorithm.
ogdf::MinSteinerTreeDirectedCut::Master::setPrimalHeuristic
void setPrimalHeuristic(MinSteinerTreeModule< double > *pMinSteinerTreeModule)
Set the module option for the primal heuristic.
Definition: MinSteinerTreeDirectedCut.h:293
ogdf::MinSteinerTreeDirectedCut::Master::setPoolSizeInitFactor
void setPoolSizeInitFactor(int b)
Set factor for the initial size of the cutting pool.
Definition: MinSteinerTreeDirectedCut.h:290
ogdf::MinSteinerTreeDirectedCut::Master::nodeID
int nodeID(node n) const
npde -> id of lp variable
Definition: MinSteinerTreeDirectedCut.h:348
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::MinSteinerTreeDirectedCut::Master::isTerminalPH
const NodeArray< bool > & isTerminalPH() const
terminal yes/no (in m_pWeightedGraphPH)
Definition: MinSteinerTreeDirectedCut.h:466
ogdf::MinSteinerTreeDirectedCut::useDegreeConstraints
void useDegreeConstraints(bool b)
Switch usage of degree constraints (like indeg <= 1) on or off.
Definition: MinSteinerTreeDirectedCut.h:118
ogdf::MinSteinerTreeDirectedCut::Sub::generateSon
virtual Sub * generateSon(abacus::BranchRule *rule) override
generates a b&b node
Definition: MinSteinerTreeDirectedCut.h:727
Minisat::Internal::var
int var(Lit p)
Definition: SolverTypes.h:61
ogdf::EdgeWeightedGraph::newNode
node newNode()
Definition: EdgeWeightedGraph.h:53
ogdf::MinSteinerTreeDirectedCut::Master::m_nestedCutComputation
bool m_nestedCutComputation
parameter: compute nested cuts yes/no i.e., saturate all cut edges and recompute the mincut
Definition: MinSteinerTreeDirectedCut.h:607
ogdf::MinSteinerTreeDirectedCut::Master::~Master
virtual ~Master()
destructor
Definition: MinSteinerTreeDirectedCut.h:208
ogdf::MinSteinerTreeDirectedCut::Master::separationStrategy
int separationStrategy() const
strategy for separating directed Steiner cuts; Only relevant for nested cuts
Definition: MinSteinerTreeDirectedCut.h:422
ogdf::MinSteinerTreeDirectedCut::Master::updateBestSolutionByEdges
void updateBestSolutionByEdges(const List< edge > &sol)
updates best found solution by list of edges
Definition: MinSteinerTreeDirectedCut.h:1425
ogdf::MinSteinerTreeDirectedCut::setSeparationStrategy
void setSeparationStrategy(int b)
Set separation strategy for nested cuts.
Definition: MinSteinerTreeDirectedCut.h:142
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::EdgeVariable
EdgeVariable(abacus::Master *master, int id, edge e, double coeff, double lb=0.0, double ub=1.0, abacus::VarType::TYPE vartype=abacus::VarType::Binary)
Definition: MinSteinerTreeDirectedCut.h:736
ogdf::MinSteinerTreeDirectedCut::m_primalHeuristic
MinSteinerTreeModule< double > * m_primalHeuristic
Definition: MinSteinerTreeDirectedCut.h:90
ogdf::RegisteredArray< GraphRegistry< EdgeElement >, Value, WithDefault, Graph >::init
void init(const Graph *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Definition: RegisteredArray.h:849
abacus::VarType::TYPE
TYPE
The enumeration with the different variable types.
Definition: vartype.h:47
ogdf::MinSteinerTreeDirectedCut::Master::m_edges
edge * m_edges
id -> edge
Definition: MinSteinerTreeDirectedCut.h:524
ogdf::MinSteinerTreeDirectedCut::m_configFile
const char * m_configFile
Definition: MinSteinerTreeDirectedCut.h:72
ogdf::MinSteinerTreeDirectedCut::Master::timerMinSTCut
StopwatchWallClock * timerMinSTCut()
timer for minimum st-cut computations. Measures updates + algorithm
Definition: MinSteinerTreeDirectedCut.h:484
abacus::CSense::Less
@ Less
Definition: csense.h:51
ogdf::MinSteinerTreeDirectedCut::m_minCardinalityCuts
bool m_minCardinalityCuts
Definition: MinSteinerTreeDirectedCut.h:88
ogdf::MinSteinerTreeDirectedCut::DegreeEdgeConstraint::coeff
double coeff(const abacus::Variable *v) const override
coefficient of variable in constraint
Definition: MinSteinerTreeDirectedCut.h:849
ogdf::Level
Representation of levels in hierarchies.
Definition: Level.h:60
ogdf::MinSteinerTreeDirectedCut::Master::m_terminalListPH
List< node > m_terminalListPH
list of terminal nodes (in m_pWeightedGraphPH)
Definition: MinSteinerTreeDirectedCut.h:566
ogdf::MinSteinerTreeDirectedCut::setSaturationStrategy
void setSaturationStrategy(int b)
Set saturation strategy for nested cuts.
Definition: MinSteinerTreeDirectedCut.h:145
ogdf::MinSteinerTreeDirectedCut::Sub::~Sub
virtual ~Sub()
The destructor only deletes the sons of the node.
Definition: MinSteinerTreeDirectedCut.h:660
ogdf::MinSteinerTreeDirectedCut::Master::nodes
node * nodes() const
nodes of the graph
Definition: MinSteinerTreeDirectedCut.h:351
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:46
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::id
int id() const
id of the edge (variable)
Definition: MinSteinerTreeDirectedCut.h:751
ogdf::MinSteinerTreeDirectedCut::setPoolSizeInitFactor
void setPoolSizeInitFactor(int b)
Set factor for the initial size of the cutting pool.
Definition: MinSteinerTreeDirectedCut.h:161
ogdf::MinSTCutMaxFlow::isInBackCut
bool isInBackCut(const node v) const
Returns whether this node is part of the back cut.
Definition: MinSTCutMaxFlow.h:163
ogdf::MinSteinerTreeDirectedCut::Master::setSaturationStrategy
void setSaturationStrategy(int b)
Set saturation strategy for nested cuts.
Definition: MinSteinerTreeDirectedCut.h:273
ogdf::MinSteinerTreeDirectedCut::Master::m_addGSEC2Constraints
bool m_addGSEC2Constraints
parameter: add GSEC2 constraints yes/no, i.e. x_uv + x_vu <= 1
Definition: MinSteinerTreeDirectedCut.h:592
ogdf::Logger
Centralized global and local logging facility working on streams like std::cout.
Definition: Logger.h:100
ogdf::MinSteinerTreeDirectedCut::Sub::m_maxNrCuttingPlanes
int m_maxNrCuttingPlanes
maximum nr of cutting planes to be added
Definition: MinSteinerTreeDirectedCut.h:704
ogdf::EdgeWeightedGraph::setWeight
void setWeight(const edge e, T weight)
Definition: EdgeWeightedGraph.h:62
ogdf::MinSteinerTreeDirectedCut::setMaxNumberAddedCuttingPlanes
void setMaxNumberAddedCuttingPlanes(int b)
Set maximum number of added cutting planes per iteration.
Definition: MinSteinerTreeDirectedCut.h:130
ogdf::MinSteinerTreeDirectedCut::Master::twins
const EdgeArray< edge > & twins() const
Definition: MinSteinerTreeDirectedCut.h:375
ogdf::MinSteinerTreeDirectedCut::Master::m_primalHeuristic
std::unique_ptr< MinSteinerTreeModule< double > > m_primalHeuristic
Algorithm used for the primal heuristic.
Definition: MinSteinerTreeDirectedCut.h:504
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::MinSteinerTreeDirectedCut::Sub::m_separationStrategy
int m_separationStrategy
Definition: MinSteinerTreeDirectedCut.h:708
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::m_name
const char * m_name
name of the cut; required method for nonduplpool
Definition: MinSteinerTreeDirectedCut.h:969
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint
Class for directed cuts (i.e., separated Steiner cuts)
Definition: MinSteinerTreeDirectedCut.h:882
ogdf::randomNumber
int randomNumber(int low, int high)
Returns random integer between low and high (including).
abacus::VarType::Continuous
@ Continuous
A continuous variable.
Definition: vartype.h:48
ogdf::Graph::newEdge
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
Definition: Graph_d.h:1075
ogdf::MinSteinerTreeDirectedCut::EdgeVariable
Variable for directed edges.
Definition: MinSteinerTreeDirectedCut.h:734
ogdf::MinSteinerTreeDirectedCut::Sub::m_minCardinalityCuts
bool m_minCardinalityCuts
Definition: MinSteinerTreeDirectedCut.h:716
ogdf::MinSteinerTreeDirectedCut::Master::bestSolution
double * bestSolution() const
the best found solution
Definition: MinSteinerTreeDirectedCut.h:390
ogdf::MinSteinerTreeDirectedCut::Sub::mySeparate
int mySeparate()
separation procedure
Definition: MinSteinerTreeDirectedCut.h:1596
ogdf::MinSteinerTreeDirectedCut::Master::useNestedCuts
void useNestedCuts(bool b)
Switch computation of nested cuts on or off.
Definition: MinSteinerTreeDirectedCut.h:263
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::MinSteinerTreeDirectedCut::Master::m_twin
EdgeArray< edge > m_twin
the twin edges (u,v) <-> (v,u)
Definition: MinSteinerTreeDirectedCut.h:528
ogdf::MinSteinerTreeDirectedCut::Master::capacities
const EdgeArray< double > & capacities() const
edge costs
Definition: MinSteinerTreeDirectedCut.h:366
ogdf::MinSteinerTreeDirectedCut::DegreeConstraint::m_node
node m_node
the associated node
Definition: MinSteinerTreeDirectedCut.h:830
ogdf::MinSteinerTreeDirectedCut::Master::setConfigFile
void setConfigFile(const char *filename)
Set the config file to use that overrides all other settings.
Definition: MinSteinerTreeDirectedCut.h:219
ogdf::MinSteinerTreeDirectedCut::Master::m_nTerminals
int m_nTerminals
nr of terminals
Definition: MinSteinerTreeDirectedCut.h:549
abacus::CSense::SENSE
SENSE
Definition: csense.h:51
abacus::Master::OSISOLVER
OSISOLVER
This enumeration defines which solvers can be used to solve the LP-relaxations.
Definition: master.h:209
ogdf::MinSteinerTreeDirectedCut::Master::terminateOptimization
virtual void terminateOptimization() override
store solution in EdgeArray
Definition: MinSteinerTreeDirectedCut.h:1340
ogdf::MinSteinerTreeDirectedCut::useNestedCuts
void useNestedCuts(bool b)
Switch computation of nested cuts on or off.
Definition: MinSteinerTreeDirectedCut.h:139
ogdf::MinSteinerTreeDirectedCut::Master::m_isSolutionEdge
EdgeArray< bool > m_isSolutionEdge
Definition: MinSteinerTreeDirectedCut.h:558
ogdf::MinSteinerTreeDirectedCut::EdgeVariable::target
node target() const
target node
Definition: MinSteinerTreeDirectedCut.h:760
ogdf::MinSTCutMaxFlow
Min-st-cut algorithm, that calculates the cut via maxflow.
Definition: MinSTCutMaxFlow.h:49
ogdf::MinSteinerTreeDirectedCut::Master::useGSEC2Constraints
void useGSEC2Constraints(bool b)
Switch usage of constraints x_uv + x_vu <= 1 on or off.
Definition: MinSteinerTreeDirectedCut.h:244
ogdf::MinSteinerTreeDirectedCut::DirectedCutConstraint::m_pGraph
const Graph * m_pGraph
the graph
Definition: MinSteinerTreeDirectedCut.h:954
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::GraphCopyBase::original
const Graph & original() const
Returns a reference to the original graph.
Definition: GraphCopy.h:98
ogdf::MinSteinerTreeDirectedCut::EdgeConstraint::EdgeConstraint
EdgeConstraint(abacus::Master *master, edge e1, edge e2, int factor=1.0, abacus::CSense::SENSE sense=abacus::CSense::Less, double rhs=1.0)
Definition: MinSteinerTreeDirectedCut.h:773
abacus::Master
The master of the optimization.
Definition: master.h:69
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::Logger::lout
std::ostream & lout(Level level=Level::Default, bool indent=true) const
stream for logging-output (local)
Definition: Logger.h:158
ogdf::MinSteinerTreeDirectedCut::Master::isSolutionEdge
bool isSolutionEdge(edge e) const
returns true iff original edge is contained in optimum solution
Definition: MinSteinerTreeDirectedCut.h:309
ogdf::MinSTCutMaxFlow::isInFrontCut
bool isInFrontCut(const node v) const
Returns whether this node is part of the front cut.
Definition: MinSTCutMaxFlow.h:152