Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Approximation.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/ArrayBuffer.h>
35 #include <ogdf/basic/Graph.h>
36 #include <ogdf/basic/GraphList.h>
37 #include <ogdf/basic/basic.h>
38 #include <ogdf/basic/comparer.h>
45 
46 #include <iostream>
47 #include <memory>
48 #include <random>
49 #include <utility>
50 
51 namespace ogdf::steiner_tree {
52 template<typename T, typename ExtraDataType>
53 class FullComponentWithExtraStore;
54 } // namespace ogdf::steiner_tree
55 
56 //#define OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
57 
58 namespace ogdf {
59 template<class E>
60 class List;
61 template<typename T>
62 class EdgeWeightedGraph;
63 
64 namespace steiner_tree {
65 namespace goemans {
66 
68 template<typename T>
74 
75  const double m_eps;
76 
77  std::minstd_rand m_rng;
78 
80  struct TemporaryEdges : ArrayBuffer<edge> {
82  TemporaryEdges(BlowupGraph<T>& blowupGraph) : m_blowupGraph(blowupGraph) { }
83 
85  edge add(node v, node w, T cost, int capacity) {
86  edge e = m_blowupGraph.newEdge(v, w, cost, capacity);
87  this->push(e);
88  return e;
89  }
90 
92  ~TemporaryEdges() { m_blowupGraph.delEdges(*this); }
93 
94  private:
96  };
97 
99  int gammoidGetRank(const BlowupGraph<T>& blowupGraph) const {
100  MaxFlowGoldbergTarjan<int> maxFlow(blowupGraph.getGraph());
101  return maxFlow.computeValue(blowupGraph.capacities(), blowupGraph.getSource(),
102  blowupGraph.getTarget());
103  }
104 
107  int findComponentAndMaxBasis(std::unique_ptr<ArrayBuffer<std::pair<node, int>>>& maxBasis,
108  BlowupGraph<T>& blowupGraph, const BlowupComponents<T>& gamma) {
109  // there should always be saturated flow to the component roots
110  // (contracted matroid)
111  EdgeArray<int> lB(blowupGraph.getGraph(), 0);
112  for (adjEntry adj : blowupGraph.getSource()->adjEntries) {
113  const edge e = adj->theEdge();
114  lB[e] = blowupGraph.getCapacity(e);
115  }
116 
117  // compute weights of core edges and add source->core edges
118  TemporaryEdges sourceCoreEdges(blowupGraph);
119  EdgeArray<double> cost(blowupGraph.getGraph(), 0);
120  for (node v : blowupGraph.core()) {
121  // compute weight of core edge
122  double weight = blowupGraph.computeCoreWeight(v);
123 
124  // add edges from source to core edges v
125  edge e = sourceCoreEdges.add(blowupGraph.getSource(), v, 0,
126  blowupGraph.getCoreCapacity(v));
127  cost[e] = -weight;
128  }
129 
130  NodeArray<int> supply(blowupGraph.getGraph(), 0);
131  EdgeArray<int> flow(blowupGraph.getGraph());
133 
134  for (int id = 1; id <= gamma.size(); ++id) {
135  /* We want to find maximum-weight basis B \in B^K_Q
136  * B_Q = minimal edge set to remove after contracting Q to obtain feasible solution (blowup graph)
137  * = bases of gammoid M_Q
138  * B^K_Q = { B \in B_Q | B \subseteq K } [K is the set of core edges]
139  * = bases of gammoid M^K_Q
140  * M^K_Q is gammoid "obtained by restricting M_Q to K"
141  * M_Q = M'_Q / X' (M'_Q contracted by X') is a gammoid
142  * M'_Q = gammoid from X \cup X' to Y in D' with arc-disjointness instead of vertex-disjointness
143  * D' is D like for separation but without source node and with interim node v_e for each edge e
144  * X = inserted nodes v_e in each edge in blowup graph
145  * X' = the (arbitrary) roots of each component
146  * Y = Q \cup {t}
147  * that means:
148  * I (subset of X) is an independent set of M_Q
149  * <=> (if X' is always an independent set in M'_Q ... which we assume here)
150  * I \cup X' is an independent set of M'_Q
151  * Restricting to K means:
152  * only put v_e in X with e \in K (that is, we only need to *generate* v_e if e \in K)
153  * Hence:
154  * - we generate D'^K (this is blowupGraph)
155  * - compute the max flow from X^K \cup X' to Q \cup {t}
156  * - ASSERT that X' is "saturated"!
157  * - check which subset of X is saturated -> these are the nodes representing the edge set we need
158  */
159  // add edges from component's terminals to target
160  TemporaryEdges Q_to_target(blowupGraph);
161  for (node t : gamma.terminals(id)) {
162  Q_to_target.add(t, blowupGraph.getTarget(), 0,
163  blowupGraph.getLCM() * blowupGraph.getY());
164  // the last value is an upper bound for the capacity
165  }
166  // TODO: we could also use static edges from all terminals to the target
167  // and just change their capacities each time; needs extra data structures
168 
169  std::unique_ptr<ArrayBuffer<std::pair<node, int>>> basis(
170  new ArrayBuffer<std::pair<node, int>>);
171 
172  int rank = gammoidGetRank(blowupGraph);
173  OGDF_ASSERT(rank >= blowupGraph.getY() + blowupGraph.getLCM());
174  supply[blowupGraph.getSource()] = rank;
175  supply[blowupGraph.getTarget()] = -rank;
176 
177 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
178  std::cout << "Computing min-cost flow for blowup component " << id << " of "
179  << gamma.size() << std::endl;
180  std::cout << " * terminals of component are " << gamma.terminals(id) << std::endl;
181  for (node v : blowupGraph.getGraph().nodes) {
182  if (supply[v] > 0) {
183  std::cout << " * supply node " << v << " with supply " << supply[v] << std::endl;
184  }
185  if (supply[v] < 0) {
186  std::cout << " * demand node " << v << " with demand " << -supply[v] << std::endl;
187  }
188  }
189  for (edge e : blowupGraph.getGraph().edges) {
190  std::cout << " * edge " << e << " with cost " << blowupGraph.getCost(e)
191  << " and flow bounds [" << lB[e] << ", " << blowupGraph.getCapacity(e)
192  << "]" << std::endl;
193  }
194 #endif
195 
196  // find maximum weight basis
197 #ifdef OGDF_DEBUG
198  bool feasible =
199 #endif
200  mcf.call(blowupGraph.getGraph(), lB, blowupGraph.capacities(), cost, supply,
201  flow);
202  OGDF_ASSERT(feasible);
203  OGDF_ASSERT(mcf.checkComputedFlow(blowupGraph.getGraph(), lB, blowupGraph.capacities(),
204  cost, supply, flow));
205 
206  double weight(0);
207  for (edge e : sourceCoreEdges) {
208  if (flow[e] > 0) {
209  basis->push(std::make_pair(e->target(), flow[e]));
210  weight -= flow[e] * cost[e];
211  }
212  }
213 
214 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
215  std::cout << "Basis weight is " << weight << std::endl
216  << "Checking if " << gamma.cost(id) << "(component cost) * "
217  << blowupGraph.getLCM() << "(lcm) <= " << weight << "(basis weight)"
218  << std::endl;
219 #endif
220 
221  // we choose the component with max cost*N <= weight
222  if (gamma.cost(id) * blowupGraph.getLCM() <= weight + m_eps) {
223 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
224  std::cout << "Using basis because it is feasible." << std::endl;
225 #endif
226  maxBasis.swap(basis);
227  return id;
228  }
229  }
230  return 0; // no component chosen, fail
231  }
232 
236  std::unique_ptr<ArrayBuffer<std::pair<node, int>>>& maxBasis,
237  const BlowupGraph<T>& blowupGraph, const BlowupComponents<T>& gamma) {
238  // find cheapest component
239  int compId = 0;
240  double cost = 0;
241  for (int id = 1; id <= gamma.size(); ++id) {
242  if (gamma.cost(id) > cost) {
243  cost = gamma.cost(id);
244  compId = id;
245  }
246  }
247  // use all core edges as basis
248  maxBasis.reset(new ArrayBuffer<std::pair<node, int>>());
249  for (node v : blowupGraph.core()) {
250  maxBasis->push(std::make_pair(v, blowupGraph.getCoreCapacity(v)));
251  }
252  return compId;
253  }
254 
256  void addComponent(NodeArray<bool>& isNewTerminal, const BlowupGraph<T>& blowupGraph,
257  const edge rootEdge) {
258  OGDF_ASSERT(blowupGraph.isTerminal(rootEdge->source()));
259  ArrayBuffer<node> stack;
260  stack.push(rootEdge->target());
261  while (!stack.empty()) {
262  const node v = stack.popRet();
263  if (blowupGraph.isTerminal(v)) {
264  continue;
265  }
266  const node vO = blowupGraph.getOriginal(v);
267  if (vO) {
268  isNewTerminal[vO] = true;
269  }
270  for (adjEntry adj : v->adjEntries) {
271  const node w = adj->theEdge()->target();
272  if (v != w) { // outgoing edge
273  stack.push(w);
274  }
275  }
276  }
277  }
278 
280  void removeFractionalBasisAndCleanup(ArrayBuffer<std::pair<node, int>>& basis,
281  BlowupGraph<T>& blowupGraph, BlowupComponents<T>& gamma) {
282 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
283  std::cout << "Remove basis from blowup graph" << std::endl;
284 #endif
285  // remove B from K (K := K \ B) and from blowup graph (X := X - B)
286  // and, while at it, remove cleanup edges from blowup graph (X := X - F)
287  // and fix components that have no incoming edges
288  ArrayBuffer<Prioritized<node, int>> fractionalCoreEdges; // we defer fractional basis elements
289  for (auto p : basis) {
290  const node v = p.first;
291  const int count = p.second;
292  int origCap = blowupGraph.getCoreCapacity(v);
293  OGDF_ASSERT(count <= origCap);
294 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
295  std::cout << " * node " << v << " with count " << count << " (of " << origCap << ")"
296  << std::endl;
297 #endif
298  if (count < origCap) { // only remove a fraction?
299  fractionalCoreEdges.push(Prioritized<node, int>(v, -count));
300 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
301  std::cout << " -> deferred because fractional" << std::endl;
302 #endif
303  } else {
304  // we are deleting the core edge from the whole component
305  blowupGraph.delCore(v);
306  blowupGraph.removeBasis(v);
307 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
308  std::cout << " -> done" << std::endl;
309 #endif
310  }
311  }
312  fractionalCoreEdges.quicksort(); // sort decreasing by flow value
313 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
314  if (!fractionalCoreEdges.empty()) {
315  std::cout << "Deferred core edges:" << std::endl;
316  }
317 #endif
318  for (auto p : fractionalCoreEdges) {
319  const node v = p.item();
320  const int count = -p.priority();
321  int origCap = blowupGraph.getCoreCapacity(v);
322 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
323  std::cout << " * node " << v << " with count " << count << " of " << origCap << std::endl;
324 #endif
325  OGDF_ASSERT(count <= origCap);
326  // copy (split) the component
327  blowupGraph.copyComponent(blowupGraph.findRootEdge(v), count, origCap - count);
328  // we are deleting the core edge from the whole component
329  blowupGraph.delCore(v);
330  blowupGraph.removeBasis(v);
331  }
332  }
333 
334 public:
336  Approximation(const EdgeWeightedGraph<T>& G, const List<node>& terminals,
337  const NodeArray<bool>& isTerminal,
338  const FullComponentWithExtraStore<T, double>& fullCompStore,
339  const std::minstd_rand& rng, double eps = 1e-8)
340  : m_G(G)
341  , m_isTerminal(isTerminal)
342  , m_terminals(terminals)
343  , m_fullCompStore(fullCompStore)
344  , m_eps(eps)
345  , m_rng(rng) { }
346 
349  void solve(NodeArray<bool>& isNewTerminal);
350 };
351 
352 template<typename T>
354 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
355  std::cout << "Start solving based on LP solution" << std::endl;
356  int iteration = 0;
357 #endif
359  BlowupGraph<T> blowupGraph(m_G, m_terminals, m_fullCompStore, cer, m_eps);
360 
361  while (blowupGraph.terminals().size() > 1) { // T is not a Steiner tree
362 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
363  std::cout << "Iteration " << ++iteration << " with " << blowupGraph.terminals().size()
364  << " terminals" << std::endl;
365 #endif
366  BlowupComponents<T> gamma(blowupGraph); // Gamma(X)
367 
368  OGDF_ASSERT(isLoopFree(blowupGraph.getGraph()));
369 
370  // take a component Q in Gamma(X)
371  std::unique_ptr<ArrayBuffer<std::pair<node, int>>> maxBasis;
372  int compId = blowupGraph.getY() > 0
373  ? findComponentAndMaxBasis(maxBasis, blowupGraph, gamma)
374  : findCheapestComponentAndRemainingBasis(maxBasis, blowupGraph, gamma);
375  OGDF_ASSERT(compId != 0);
376 
377  // add component Q to T
378  addComponent(isNewTerminal, blowupGraph, gamma.rootEdge(compId));
379 
380  // remove (maybe fractional) basis and do all the small things necessary for update
381  removeFractionalBasisAndCleanup(*maxBasis, blowupGraph, gamma);
382 
383  // contract (X := X / Q)
384  blowupGraph.contract(gamma.terminals(compId));
385 
386  if (blowupGraph.terminals().size() > 1) {
387  blowupGraph.updateSpecialCapacities();
388  }
389  }
390 }
391 
392 }
393 }
394 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:53
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::MinCostFlowReinelt
Computes a min-cost flow using a network simplex method.
Definition: MinCostFlowReinelt.h:52
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
ogdf::steiner_tree::goemans::Approximation::solve
void solve(NodeArray< bool > &isNewTerminal)
Perform the actual approximation algorithm on the LP solution.
Definition: Approximation.h:353
Graph.h
Includes declaration of graph class.
ogdf::MinCostFlowModule::checkComputedFlow
static bool checkComputedFlow(const Graph &G, const EdgeArray< int > &lowerBound, const EdgeArray< int > &upperBound, const EdgeArray< TCost > &cost, const NodeArray< int > &supply, const EdgeArray< int > &flow, TCost &value)
checks if a computed flow is a feasible solution to the given problem instance.
Definition: MinCostFlowModule.h:244
ogdf::ArrayBuffer< edge >::capacity
int capacity() const
Returns the current capacity of the datastructure. Note that this value is rather irrelevant if the a...
Definition: ArrayBuffer.h:247
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:238
ogdf::steiner_tree::goemans::BlowupGraph::getGraph
const Graph & getGraph() const
Definition: BlowupGraph.h:503
MinCostFlowReinelt.h
Definition of ogdf::MinCostFlowReinelt class template.
ogdf::steiner_tree::goemans::BlowupGraph::findRootEdge
edge findRootEdge(node v)
Finds the root node of a component given by v, an arbitrary inner nonterminal of the component.
Definition: BlowupGraph.h:690
ogdf::steiner_tree::goemans::BlowupGraph::removeBasis
void removeBasis(node v)
Removes a basis and cleans up.
Definition: BlowupGraph.h:634
ogdf::MinCostFlowReinelt::call
virtual bool call(const Graph &G, const EdgeArray< int > &lowerBound, const EdgeArray< int > &upperBound, const EdgeArray< TCost > &cost, const NodeArray< int > &supply, EdgeArray< int > &flow, NodeArray< TCost > &dual) override
Computes a min-cost flow in the directed graph G using a network simplex method.
Definition: MinCostFlowReinelt.h:154
ogdf::MaxFlowGoldbergTarjan
Computes a max flow via Preflow-Push (global relabeling and gap relabeling heuristic).
Definition: MaxFlowGoldbergTarjan.h:60
ogdf::ArrayBuffer::popRet
E popRet()
Removes the newest element from the buffer and returns it.
Definition: ArrayBuffer.h:232
ogdf::steiner_tree::goemans::Approximation::TemporaryEdges
Add edges into a blowup graph and delete them on destruction.
Definition: Approximation.h:80
BlowupComponents.h
Definition of the ogdf::steiner_tree::goemans::BlowupComponents class template.
ogdf::steiner_tree::goemans::Approximation::TemporaryEdges::TemporaryEdges
TemporaryEdges(BlowupGraph< T > &blowupGraph)
Construct object for a specific blowupGraph.
Definition: Approximation.h:82
ogdf::steiner_tree::goemans::Approximation::m_eps
const double m_eps
epsilon for double operations
Definition: Approximation.h:75
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::steiner_tree::goemans::BlowupGraph::terminals
const List< node > & terminals() const
Returns a reference to the list containing all terminals in the blowup graph.
Definition: BlowupGraph.h:533
ogdf::steiner_tree::goemans::BlowupGraph::getY
int getY() const
Returns the y-value of all terminals.
Definition: BlowupGraph.h:530
ogdf::steiner_tree::goemans::Approximation::gammoidGetRank
int gammoidGetRank(const BlowupGraph< T > &blowupGraph) const
Computes the rank of the gammoid (given by the blowup graph)
Definition: Approximation.h:99
ogdf::steiner_tree
Definition: MinSteinerTreeMehlhorn.h:297
ogdf::steiner_tree::goemans::BlowupGraph::getOriginal
node getOriginal(node v) const
Returns the original node of v.
Definition: BlowupGraph.h:524
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:160
ogdf::steiner_tree::goemans::Approximation::removeFractionalBasisAndCleanup
void removeFractionalBasisAndCleanup(ArrayBuffer< std::pair< node, int >> &basis, BlowupGraph< T > &blowupGraph, BlowupComponents< T > &gamma)
Remove a given basis and cleanup, the basis may be given fractionally.
Definition: Approximation.h:280
ogdf::steiner_tree::goemans::Approximation::addComponent
void addComponent(NodeArray< bool > &isNewTerminal, const BlowupGraph< T > &blowupGraph, const edge rootEdge)
Add a component of the blowup graph to the final solution (by changing nonterminals to terminals)
Definition: Approximation.h:256
ogdf::steiner_tree::goemans::BlowupGraph::core
const List< node > & core() const
Return list of core edges (implemented by nodes)
Definition: BlowupGraph.h:748
ogdf::ArrayBuffer::quicksort
void quicksort()
Sorts buffer using Quicksort.
Definition: ArrayBuffer.h:428
ogdf::steiner_tree::goemans::Approximation::findCheapestComponentAndRemainingBasis
int findCheapestComponentAndRemainingBasis(std::unique_ptr< ArrayBuffer< std::pair< node, int >>> &maxBasis, const BlowupGraph< T > &blowupGraph, const BlowupComponents< T > &gamma)
For the end of the algorithm: find cheapest component and choose all remaining core edges as basis.
Definition: Approximation.h:235
MaxFlowGoldbergTarjan.h
Declaration and implementation of Goldberg-Tarjan max-flow algorithm with global relabeling and gap r...
ogdf::steiner_tree::goemans::Approximation::m_G
const EdgeWeightedGraph< T > & m_G
Definition: Approximation.h:70
ogdf::steiner_tree::goemans::Approximation::findComponentAndMaxBasis
int findComponentAndMaxBasis(std::unique_ptr< ArrayBuffer< std::pair< node, int >>> &maxBasis, BlowupGraph< T > &blowupGraph, const BlowupComponents< T > &gamma)
Finds the best component and its maximum-weight basis in the given blowup graph with given core and w...
Definition: Approximation.h:107
ogdf::steiner_tree::goemans::BlowupGraph::getCost
T getCost(edge e) const
Returns the cost of e.
Definition: BlowupGraph.h:521
ogdf::EdgeWeightedGraph
Definition: GraphIO.h:56
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::steiner_tree::goemans::BlowupGraph::delCore
void delCore(node e)
Remove a core edge.
Definition: BlowupGraph.h:752
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:271
ogdf::steiner_tree::goemans::BlowupGraph::getCoreCapacity
T getCoreCapacity(node v) const
Get capacity of a core edge.
Definition: BlowupGraph.h:543
ogdf::ArrayBuffer< edge >::push
void push(edge e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:217
ogdf::steiner_tree::goemans::Approximation::Approximation
Approximation(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, const FullComponentWithExtraStore< T, double > &fullCompStore, const std::minstd_rand &rng, double eps=1e-8)
Initialize everything.
Definition: Approximation.h:336
ogdf::steiner_tree::goemans::BlowupGraph::getSource
node getSource() const
Returns the source node.
Definition: BlowupGraph.h:506
BlowupGraph.h
Definition of ogdf::steiner_tree::goemans::BlowupGraph class template.
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
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::steiner_tree::goemans::BlowupComponents
Obtain and provides information about components in a given blowup graph.
Definition: BlowupComponents.h:55
ogdf::steiner_tree::goemans::Approximation::m_terminals
const List< node > & m_terminals
Definition: Approximation.h:72
ogdf::steiner_tree::goemans::BlowupGraph::getTarget
node getTarget() const
Returns the target node.
Definition: BlowupGraph.h:512
ogdf::isLoopFree
bool isLoopFree(const Graph &G)
Returns true iff G contains no self-loop.
ogdf::steiner_tree::goemans::Approximation::TemporaryEdges::add
edge add(node v, node w, T cost, int capacity)
Add a temporary edge to the blowup graph.
Definition: Approximation.h:85
ogdf::steiner_tree::goemans::BlowupGraph::getLCM
int getLCM() const
Returns the least common multiple of all denominators.
Definition: BlowupGraph.h:527
ogdf::steiner_tree::goemans::BlowupGraph::updateSpecialCapacities
void updateSpecialCapacities()
Updates capacities from source to terminals and terminals to pseudotarget.
Definition: BlowupGraph.h:571
ogdf::steiner_tree::goemans::BlowupGraph::copyComponent
void copyComponent(const edge origEdge, const int origCap, const int copyCap)
Copy a component in the blowup graph and set original capacity to origCap and capacity of copy to cop...
Definition: BlowupGraph.h:712
basic.h
Basic declarations, included by all source files.
ogdf::steiner_tree::goemans::Approximation::m_rng
std::minstd_rand m_rng
Definition: Approximation.h:77
ogdf::steiner_tree::goemans::BlowupGraph::contract
void contract(node &v, node t)
Contracts node v and terminal t into v.
Definition: BlowupGraph.h:602
ogdf::steiner_tree::goemans::BlowupGraph::capacities
const EdgeArray< int > & capacities() const
Returns a reference to the edge array containing all capacities.
Definition: BlowupGraph.h:518
ogdf::Math::gamma
constexpr double gamma
The Euler-Mascheroni constant gamma.
Definition: Math.h:78
ogdf::steiner_tree::goemans::BlowupGraph::isTerminal
bool isTerminal(node v) const
Returns true if and only if v is a terminal.
Definition: BlowupGraph.h:536
ogdf::steiner_tree::goemans::Approximation::m_isTerminal
const NodeArray< bool > & m_isTerminal
Definition: Approximation.h:71
ogdf::Prioritized
Augments any data elements of type X with keys of type Priority. This class is also its own Comparer.
Definition: comparer.h:295
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::steiner_tree::goemans::Approximation::TemporaryEdges::m_blowupGraph
BlowupGraph< T > & m_blowupGraph
Definition: Approximation.h:95
ogdf::steiner_tree::goemans::CoreEdgeRandomSpanningTree
Computes a random set of core edges.
Definition: CoreEdgeRandomSpanningTree.h:50
ogdf::steiner_tree::goemans::BlowupGraph
A special-purpose blowup graph for gammoid computation: directed, with special source and target,...
Definition: BlowupComponents.h:44
CoreEdgeRandomSpanningTree.h
Definition of ogdf::steiner_tree::goemans::CoreEdgeRandomSpanningTree class template.
ogdf::MaxFlowGoldbergTarjan::computeValue
TCap computeValue(const EdgeArray< TCap > &cap, const node &s, const node &t)
Compute only the value of the flow.
Definition: MaxFlowGoldbergTarjan.h:244
ogdf::steiner_tree::goemans::Approximation::m_fullCompStore
const FullComponentWithExtraStore< T, double > & m_fullCompStore
all enumerated full components, with solution
Definition: Approximation.h:73
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
comparer.h
Declarations for Comparer objects.
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::steiner_tree::goemans::Approximation::TemporaryEdges::~TemporaryEdges
~TemporaryEdges()
Remove the edges again.
Definition: Approximation.h:92
ogdf::steiner_tree::FullComponentWithExtraStore< T, double >
simple_graph_alg.h
Declaration of simple graph algorithms.
ogdf::steiner_tree::goemans::BlowupGraph::computeCoreWeight
double computeCoreWeight(node v) const
Compute the weight of a core edge.
Definition: BlowupGraph.h:559
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716
ogdf::steiner_tree::goemans::Approximation
The actual 1.39-approximation algorithm by Goemans et al. with a set of terminalized nodes as result.
Definition: Approximation.h:69
ogdf::steiner_tree::goemans::BlowupGraph::getCapacity
int getCapacity(edge e) const
Returns the capacity of e.
Definition: BlowupGraph.h:515