Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

BlowupComponents.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/List.h>
38 #include <ogdf/basic/basic.h>
39 
40 #include <iostream>
41 
43 template<typename T>
45 } // namespace ogdf::steiner_tree::goemans
46 
47 //#define OGDF_STEINER_TREE_GOEMANS_BLOWUP_COMPONENTS_LOGGING
48 
49 namespace ogdf {
50 namespace steiner_tree {
51 namespace goemans {
52 
54 template<typename T>
56 protected:
57  // To represent Gamma(X) [the set of all components in the blowup graph], we give
58  // - terminals, source and target the component id 0
59  // - all other nodes a component id > 0. Nodes with same id belong to the same component.
60  // Note that this is also fine for 2-components with only one edge, since this
61  // is a core edge and hence a dummy node is inserted.
63  // We also save lists of terminals for each component in the specified array buffer.
65  // To efficiently traverse the found component, we save the edge from the root of the component
67  // Finally a component -> cost array.
69 
70  int maxId; // == the size of the arraybuffers
71 
73  void initializeComponent(edge rootEdge, const BlowupGraph<T>& blowupGraph) {
74  List<node> queue;
75  const node start = rootEdge->target();
76  queue.pushBack(start);
79  auto& terms = componentTerminals[maxId];
80  if (!blowupGraph.getOriginal(start)) { // start node is a core edge
81  componentCost.push(blowupGraph.getCost(rootEdge));
82  } else {
84  }
85  T& cost = componentCost[maxId];
86  ++maxId;
87  while (!queue.empty()) {
88  const node v = queue.popBackRet();
89  componentId[v] = maxId;
90  for (adjEntry adj : v->adjEntries) {
91  const node w = adj->twinNode();
92  if (componentId[w] < 0) {
93  // count coreEdge cost only once
94  if (blowupGraph.getOriginal(v)) { // v is no core edge
95  cost += blowupGraph.getCost(adj->theEdge());
96  }
97  if (blowupGraph.isTerminal(w)) {
98  terms.push(w);
99  } else {
100  queue.pushBack(w);
101  }
102  }
103  }
104  }
105 #ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_COMPONENTS_LOGGING
106  std::cout << " * component with terminals " << terms << " starting with edge " << rootEdge
107  << " having cost " << cost << " and capacity "
108  << blowupGraph.getCapacity(rootEdge) << std::endl;
109 #endif
110  }
111 
112 public:
114  BlowupComponents(const BlowupGraph<T>& blowupGraph)
115  : componentId(blowupGraph.getGraph(), -1), maxId(0) {
116  componentId[blowupGraph.getSource()] = 0;
117  componentId[blowupGraph.getPseudotarget()] = 0;
118  componentId[blowupGraph.getTarget()] = 0;
119 
120 #ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_COMPONENTS_LOGGING
121  std::cout << "Finding components in blowup graph:" << std::endl;
122 #endif
123  for (node t : blowupGraph.terminals()) {
124  for (adjEntry rootAdj : t->adjEntries) {
125  const edge rootEdge = rootAdj->theEdge();
126  if (rootEdge->source() != t) {
127  continue;
128  }
129  const node r = rootAdj->twinNode();
130  OGDF_ASSERT(r == rootEdge->target());
131  if (componentId[r] < 0) {
132  initializeComponent(rootEdge, blowupGraph);
133  }
134  }
135  }
136 
137  // now set terminals to id 0 [XXX: why dont we keep -1?]
138  for (node t : blowupGraph.terminals()) {
139  componentId[t] = 0;
140  }
141  }
142 
144  const ArrayBuffer<node>& terminals(int id) const {
145  OGDF_ASSERT(id > 0);
146  return componentTerminals[id - 1];
147  }
148 
150  int id(node v) const { return componentId[v]; }
151 
153  const T& cost(int id) const {
154  OGDF_ASSERT(id > 0);
155  return componentCost[id - 1];
156  }
157 
159  int size() const { return maxId; }
160 
162  edge rootEdge(int id) const {
163  OGDF_ASSERT(id > 0);
164  return componentRootEdge[id - 1];
165  }
166 
168  void setRootEdge(int id, edge e) // beware of using!
169  {
170  OGDF_ASSERT(id > 0);
171  componentRootEdge[id - 1] = e;
172  OGDF_ASSERT(componentTerminals[id - 1].linearSearch(e->source()) != -1);
173  }
174 };
175 
176 }
177 }
178 }
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
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
ogdf::steiner_tree::goemans::BlowupComponents::size
int size() const
Return number of components.
Definition: BlowupComponents.h:159
Graph.h
Includes declaration of graph class.
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::steiner_tree::goemans::BlowupComponents::componentTerminals
ArrayBuffer< ArrayBuffer< node > > componentTerminals
Definition: BlowupComponents.h:64
ogdf::steiner_tree::goemans::BlowupComponents::maxId
int maxId
Definition: BlowupComponents.h:70
ogdf::steiner_tree::goemans
Definition: Approximation.h:65
ogdf::steiner_tree::goemans::BlowupComponents::componentId
NodeArray< int > componentId
Definition: BlowupComponents.h:62
ogdf::steiner_tree::goemans::BlowupComponents::componentRootEdge
ArrayBuffer< edge > componentRootEdge
Definition: BlowupComponents.h:66
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::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
r
int r[]
Definition: hierarchical-ranking.cpp:13
ogdf::steiner_tree::goemans::BlowupGraph::getCost
T getCost(edge e) const
Returns the cost of e.
Definition: BlowupGraph.h:521
ogdf::steiner_tree::goemans::BlowupComponents::BlowupComponents
BlowupComponents(const BlowupGraph< T > &blowupGraph)
Find all components in the blowup graph and initialize information them.
Definition: BlowupComponents.h:114
GraphList.h
Decralation of GraphElement and GraphList classes.
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::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:217
ogdf::steiner_tree::goemans::BlowupGraph::getSource
node getSource() const
Returns the source node.
Definition: BlowupGraph.h:506
ogdf::steiner_tree::goemans::BlowupGraph::getPseudotarget
node getPseudotarget() const
Returns the pseudotarget node.
Definition: BlowupGraph.h:509
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
ogdf::steiner_tree::goemans::BlowupComponents::setRootEdge
void setRootEdge(int id, edge e)
Set the edge coming from the root for a given component.
Definition: BlowupComponents.h:168
ogdf::steiner_tree::goemans::BlowupComponents::componentCost
ArrayBuffer< T > componentCost
Definition: BlowupComponents.h:68
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::BlowupGraph::getTarget
node getTarget() const
Returns the target node.
Definition: BlowupGraph.h:512
ogdf::List::popBackRet
E popBackRet()
Removes the last element from the list and returns it.
Definition: List.h:1604
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:175
ogdf::steiner_tree::goemans::BlowupComponents::id
int id(node v) const
Return the component id a given node is contained in.
Definition: BlowupComponents.h:150
ogdf::steiner_tree::goemans::BlowupComponents::terminals
const ArrayBuffer< node > & terminals(int id) const
Return list of terminals for a given component.
Definition: BlowupComponents.h:144
ogdf::steiner_tree::goemans::BlowupComponents::cost
const T & cost(int id) const
Return total cost of a given component.
Definition: BlowupComponents.h:153
basic.h
Basic declarations, included by all source files.
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::BlowupComponents::initializeComponent
void initializeComponent(edge rootEdge, const BlowupGraph< T > &blowupGraph)
Initialize all information about the component starting with rootEdge in the blowup graph.
Definition: BlowupComponents.h:73
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::steiner_tree::goemans::BlowupComponents::rootEdge
edge rootEdge(int id) const
Return the edge coming from the root of a given component.
Definition: BlowupComponents.h:162
List.h
Declaration of doubly linked lists and iterators.
ogdf::steiner_tree::goemans::BlowupGraph
A special-purpose blowup graph for gammoid computation: directed, with special source and target,...
Definition: BlowupComponents.h:44
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1547
ogdf::steiner_tree::goemans::BlowupGraph::getCapacity
int getCapacity(edge e) const
Returns the capacity of e.
Definition: BlowupGraph.h:515