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