Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

FullComponentGeneratorDreyfusWagner.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/Hashing.h>
35 #include <ogdf/basic/Math.h>
38 
39 namespace ogdf {
40 namespace steiner_tree {
41 
50 template<typename T>
58 
60 
62  struct DWMData {
63  T cost;
66 
67  DWMData(T _cost, NodePairs _nodepairs) : cost(_cost), nodepairs(_nodepairs) { }
68 
69  explicit DWMData(T _cost = std::numeric_limits<T>::max()) : cost(_cost) { }
70 
72  void invalidate() {
73  nodepairs.clear();
74  subgraphs.clear();
75  }
76 
78  bool valid() const { return cost == 0 || !(nodepairs.empty() && subgraphs.empty()); }
79 
81  void add(const DWMData* other) {
82  if (valid()) {
83  if (other->valid()) {
84  subgraphs.push(other);
85  } else {
86  invalidate();
87  }
88  }
89  cost += other->cost;
90  }
91 
93  void clear() {
94  invalidate();
95  cost = 0; // make it valid again
96  }
97 
99  void add(NodePair nodepair, T c) {
100  if (valid()) {
101  nodepairs.push(nodepair);
102  }
103  cost += c;
104  }
105  };
106 
108  struct DWMSplit {
109  T cost = std::numeric_limits<T>::max();
110  const DWMData* subgraph1 = nullptr;
111  const DWMData* subgraph2 = nullptr;
112 
114  void set(const DWMData* s1, const DWMData* s2) {
115  subgraph1 = s1;
116  subgraph2 = s2;
117  cost = s1->cost + s2->cost;
118  }
119  };
120 
123 
126 
128  const DWMData* dataOf(const List<node>& key) const {
129  OGDF_ASSERT(key.size() > 1);
130  OGDF_ASSERT(m_map.member(key));
131  return &m_map.lookup(key)->info();
132  }
133 
135  T costOf(const List<node>& key) const {
136  OGDF_ASSERT(key.size() > 1);
137  if (key.size() == 2) { // a shortcut to avoid using the hash table
138 #ifdef OGDF_FULL_COMPONENT_GENERATION_TERMINAL_SSSP_AWARE
139  if (m_isTerminal[key.front()]) {
140  return m_distance[key.front()][key.back()];
141  } else {
142  OGDF_ASSERT(m_isTerminal[key.back()]);
143  return m_distance[key.back()][key.front()];
144  }
145 #else
146  return m_distance[key.front()][key.back()];
147 #endif
148  }
149  return dataOf(key)->cost;
150  }
151 
153  bool safeIfSumSmaller(const T summand1, const T summand2, const T compareValue) const {
154 #ifdef OGDF_FULL_COMPONENT_GENERATION_ALWAYS_SAFE
155  return summand1 + summand2 < compareValue;
156 #else
157  return summand1 < std::numeric_limits<T>::max() && summand2 < std::numeric_limits<T>::max()
158  && summand1 + summand2 < compareValue;
159 #endif
160  }
161 
173  static void sortedInserter(node w, List<node>& list, bool& inserted, node newNode) {
174  if (!inserted && w->index() > newNode->index()) {
175  list.pushBack(newNode);
176  inserted = true;
177  }
178  list.pushBack(w);
179  }
180 
182  void makeKey(List<node>& newSubset, node v) const {
183  bool inserted = false;
184  m_terminalSubset.forEachMember([&](node w) { sortedInserter(w, newSubset, inserted, v); });
185  if (!inserted) {
186  newSubset.pushBack(v);
187  }
188  }
189 
191  void makeKey(List<node>& newSubset, List<node>& newComplement,
192  const SubsetEnumerator<node>& subset, node v) const {
193  bool insertedIntoSubset = false;
194  bool insertedIntoComplement = false;
195  // Interestingly std::bind is much slower than using lambdas (at least on g++ 6.3)
197  [&](node w) { sortedInserter(w, newSubset, insertedIntoSubset, v); },
198  [&](node w) { sortedInserter(w, newComplement, insertedIntoComplement, v); });
199  if (!insertedIntoSubset) {
200  newSubset.pushBack(v);
201  }
202  if (!insertedIntoComplement) {
203  newComplement.pushBack(v);
204  }
205  }
206 
213  if (split[v].subgraph1 != nullptr) { // already computed
214  return;
215  }
216 
217  DWMSplit& best = split[v];
218  for (subset.begin(1, subset.numberOfMembersAndNonmembers() / 2); subset.valid();
219  subset.next()) {
220  List<node> newSubset, newComplement;
221  makeKey(newSubset, newComplement, subset, v);
222 
223  if (safeIfSumSmaller(costOf(newSubset), costOf(newComplement), best.cost)) {
224  best.set(dataOf(newSubset), dataOf(newComplement));
225  }
226  }
227  }
228 
231  const List<node>& terminals) {
232  List<node> newSubset;
233  makeKey(newSubset, v);
234 
235  if (!m_map.member(newSubset)) { // not already defined
236  T oldCost = costOf(terminals);
237  DWMData best;
238  auto addPair = [&](node v1, node v2, T dist) {
239  best.add(NodePair(v1, v2), dist);
240  if (m_pred[v1][v2] == nullptr) {
241  best.invalidate();
242  }
243  };
244  for (node w : m_G.nodes) {
245  T dist = m_distance[v][w];
246  if (m_terminalSubset.hasMember(w)) {
247  // we attach edge vw to tree containing terminal w
248  if (safeIfSumSmaller(oldCost, dist, best.cost)) {
249  best.clear();
250  best.add(dataOf(terminals));
251  addPair(v, w, dist);
252  }
253  } else {
254  // we attach edge vw to tree split[w]
255  OGDF_ASSERT(!m_terminalSubset.hasMember(v));
256  computeSplit(split, w, subset);
257  if (safeIfSumSmaller(split[w].cost, dist, best.cost)) {
258  best.clear();
259  best.add(split[w].subgraph1);
260  best.add(split[w].subgraph2);
261  if (v != w) {
262  addPair(v, w, dist);
263  }
264  }
265  }
266  }
267  m_map.fastInsert(newSubset, best);
268  }
269  }
270 
272  template<typename CONTAINER>
273  void computePartialSolutions(const CONTAINER& nodeContainer) {
274  List<node> terminals;
275  m_terminalSubset.list(terminals);
276  SubsetEnumerator<node> subset(terminals); // done here because of linear running time
278  for (node v : nodeContainer) {
279  if (!m_terminalSubset.hasMember(v)) {
280  computePartialSolution(split, v, subset, terminals);
281  }
282  }
283  }
284 
286  void initializeMap() {
287  for (node v : m_G.nodes) {
288  for (node t : m_terminals) {
289  if (t != v) {
290  List<node> key;
291  key.pushBack(t);
292  if (v->index() < t->index()) {
293  key.pushFront(v);
294  } else {
295  key.pushBack(v);
296  }
297 
298  if (!m_map.member(key)) { // not already defined
299  if (m_pred[t][v] == nullptr) {
300  m_map.fastInsert(key, DWMData(m_distance[t][v]));
301  OGDF_ASSERT(!dataOf(key)->valid() || m_distance[t][v] == 0);
302  } else {
303  NodePairs nodepairs;
304  nodepairs.push(NodePair(key.front(), key.back()));
305  m_map.fastInsert(key, DWMData(m_distance[t][v], nodepairs));
306  OGDF_ASSERT(dataOf(key)->valid());
307  }
308  }
309  }
310  }
311  }
312  }
313 
315  T getSteinerTreeFor(const DWMData& data, EdgeWeightedGraphCopy<T>& tree) const {
316  T cost(0);
317  if (data.valid()) {
318  // add edges
319  for (auto nodepair : data.nodepairs) {
320  node uO = nodepair.source;
321  node vO = nodepair.target;
322  node uC = tree.copy(uO);
323  node vC = tree.copy(vO);
324  if (uC == nullptr) {
325  uC = tree.newNode(uO);
326  }
327  if (vC == nullptr) {
328  vC = tree.newNode(vO);
329  }
330 #ifdef OGDF_FULL_COMPONENT_GENERATION_TERMINAL_SSSP_AWARE
331  const T dist = m_isTerminal[uO] ? m_distance[uO][vO] : m_distance[vO][uO];
332 #else
333  const T dist = m_distance[uO][vO];
334 #endif
335  tree.newEdge(uC, vC, dist);
336  cost += dist;
337  }
338 
339  // recurse
340  for (const DWMData* subgraph : data.subgraphs) {
341  cost += getSteinerTreeFor(*subgraph, tree);
342  }
343  }
344 
346  return cost;
347  }
348 
349 public:
354  const NodeArray<bool>& isTerminal, const NodeArray<NodeArray<T>>& distance,
355  const NodeArray<NodeArray<edge>>& pred)
356  : m_G(G)
357  , m_terminals(terminals)
358  , m_isTerminal(isTerminal)
359  , m_distance(distance)
360  , m_pred(pred)
362  , m_map(1 << 22) // we initially allocate 4MB*sizeof(DWMData) for hashing
363  {
364  initializeMap();
365  }
366 
367  void call(int restricted) {
368  OGDF_ASSERT(restricted >= 2);
369  Math::updateMin(restricted, m_terminals.size());
370  for (m_terminalSubset.begin(2, restricted - 1); m_terminalSubset.valid();
371  m_terminalSubset.next()) {
372  if (m_terminalSubset.size() != restricted - 1) {
374  } else { // maximal terminal subset
375  // save time by only adding terminals instead of all nodes
377  }
378  }
379  }
380 
383  T getSteinerTreeFor(const List<node>& terminals, EdgeWeightedGraphCopy<T>& tree) const {
384  tree.setOriginalGraph(m_G);
385  T cost(getSteinerTreeFor(*dataOf(terminals), tree));
387  return cost;
388  }
389 
391  bool isValidComponent(const EdgeWeightedGraphCopy<T>& graph) const {
392  if (graph.empty()) {
393  return false;
394  }
395  for (node v : graph.nodes) {
396  if (m_isTerminal[graph.original(v)] // is a terminal
397  && v->degree() > 1) { // but not a leaf
398  return false;
399  }
400  }
401  return true;
402  }
403 };
404 
405 template<typename T>
407  static const unsigned int c_prime = 0x7fffffff; // mersenne prime 2**31 - 1
408  // would be nicer: 0x1fffffffffffffff; // mersenne prime 2**61 - 1
409  const int m_random;
410 
411 public:
413  SortedNodeListHashFunc() : m_random(randomNumber(2, c_prime - 1)) { }
414 
416  unsigned int hash(const List<node>& key) const {
417  unsigned int hash = 0;
418  for (node v : key) {
419  hash = (hash * m_random + v->index()) % c_prime;
420  }
421  return hash;
422  }
423 };
424 
425 }
426 }
ogdf::ArrayBuffer< NodePair >
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::call
void call(int restricted)
Definition: FullComponentGeneratorDreyfusWagner.h:367
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData
Subgraphs (given by other subgraphs and additional node pairs) and their cost for a partial solution.
Definition: FullComponentGeneratorDreyfusWagner.h:62
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::SortedNodeListHashFunc::SortedNodeListHashFunc
SortedNodeListHashFunc()
Initializes the random number.
Definition: FullComponentGeneratorDreyfusWagner.h:413
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::SortedNodeListHashFunc
Definition: FullComponentGeneratorDreyfusWagner.h:406
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMSplit::cost
T cost
Definition: FullComponentGeneratorDreyfusWagner.h:109
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::costOf
T costOf(const List< node > &key) const
Returns the cost of the partial solution given by key.
Definition: FullComponentGeneratorDreyfusWagner.h:135
ogdf::Graph::empty
bool empty() const
Returns true iff the graph is empty, i.e., contains no nodes.
Definition: Graph_d.h:971
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::makeKey
void makeKey(List< node > &newSubset, node v) const
Makes a list from the current terminal subset including an correctly inserted node v.
Definition: FullComponentGeneratorDreyfusWagner.h:182
ogdf::SubsetEnumerator
Enumerator for k-subsets of a given type.
Definition: SubsetEnumerator.h:88
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_terminalSubset
SubsetEnumerator< node > m_terminalSubset
Handling subsets of terminals.
Definition: FullComponentGeneratorDreyfusWagner.h:57
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::invalidate
void invalidate()
Invalidates the data.
Definition: FullComponentGeneratorDreyfusWagner.h:72
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:230
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::computeSplit
void computeSplit(NodeArray< DWMSplit > &split, node v, SubsetEnumerator< node > &subset) const
Populates split that contains a partial solution for an included nonterminal v in m_G.
Definition: FullComponentGeneratorDreyfusWagner.h:212
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::DWMData
DWMData(T _cost, NodePairs _nodepairs)
Definition: FullComponentGeneratorDreyfusWagner.h:67
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::computePartialSolution
void computePartialSolution(NodeArray< DWMSplit > &split, node v, SubsetEnumerator< node > &subset, const List< node > &terminals)
Computes a partial solution for given terminals and node v.
Definition: FullComponentGeneratorDreyfusWagner.h:230
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::getSteinerTreeFor
T getSteinerTreeFor(const List< node > &terminals, EdgeWeightedGraphCopy< T > &tree) const
Constructs a Steiner tree for the given set of terminals if it is valid, otherwise an empty tree is r...
Definition: FullComponentGeneratorDreyfusWagner.h:383
Hashing.h
Declaration of classes used for hashing.
ogdf::NodeElement::index
int index() const
Returns the (unique) node index.
Definition: Graph_d.h:267
ogdf::NodePair
Definition: Graph_d.h:2101
ogdf::SubsetEnumerator::begin
void begin(int low, int high)
Initializes the SubsetEnumerator to enumerate subsets of cardinalities from low to high.
Definition: SubsetEnumerator.h:120
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMSplit::set
void set(const DWMData *s1, const DWMData *s2)
Sets subgraph1 and subgraph2 and computes cost.
Definition: FullComponentGeneratorDreyfusWagner.h:114
ogdf::Hashing
Hashing with chaining and table doubling.
Definition: Hashing.h:261
ogdf::SubsetEnumerator::valid
bool valid() const
Checks if the current subset is valid. If not, the subset is either not initialized or all subsets ha...
Definition: SubsetEnumerator.h:145
ogdf::sync_plan::split
std::pair< node, node > split(Graph &G, sync_plan::PipeBij &bij, const EdgeArray< edge > *new_edges=nullptr, const EdgeArray< bool > *reverse_edges=nullptr, node src=nullptr, node tgt=nullptr)
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_isTerminal
const NodeArray< bool > & m_isTerminal
A reference to the terminal incidence vector.
Definition: FullComponentGeneratorDreyfusWagner.h:54
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner
A generator for restricted full components (for Steiner tree approximations) based on the Dreyfus-Wag...
Definition: FullComponentGeneratorDreyfusWagner.h:51
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMSplit::subgraph1
const DWMData * subgraph1
Definition: FullComponentGeneratorDreyfusWagner.h:110
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_distance
const NodeArray< NodeArray< T > > & m_distance
A reference to the full distance matrix.
Definition: FullComponentGeneratorDreyfusWagner.h:55
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::valid
bool valid() const
Returns true iff the data is valid.
Definition: FullComponentGeneratorDreyfusWagner.h:78
EdgeWeightedGraphCopy.h
Extends the GraphCopy concept to weighted graphs.
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::DWMData
DWMData(T _cost=std::numeric_limits< T >::max())
Definition: FullComponentGeneratorDreyfusWagner.h:69
ogdf::isAcyclicUndirected
bool isAcyclicUndirected(const Graph &G, List< edge > &backedges)
Returns true iff the undirected graph G is acyclic.
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::sortedInserter
static void sortedInserter(node w, List< node > &list, bool &inserted, node newNode)
Is being used as a callback to ogdf::SubsetEnumerator's forEach* methods to get the subset plus a cor...
Definition: FullComponentGeneratorDreyfusWagner.h:173
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:924
ogdf::NodeElement::degree
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition: Graph_d.h:276
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::cost
T cost
Definition: FullComponentGeneratorDreyfusWagner.h:63
ogdf::List::pushFront
iterator pushFront(const E &x)
Adds element x at the beginning of the list.
Definition: List.h:1524
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_map
Hashing< List< node >, DWMData, SortedNodeListHashFunc > m_map
A hash array for keys of size > 2.
Definition: FullComponentGeneratorDreyfusWagner.h:122
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_pred
const NodeArray< NodeArray< edge > > & m_pred
A reference to the full predecessor matrix.
Definition: FullComponentGeneratorDreyfusWagner.h:56
ogdf::EdgeWeightedGraph
Definition: EdgeWeightedGraph.h:39
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_G
const EdgeWeightedGraph< T > & m_G
A reference to the graph instance.
Definition: FullComponentGeneratorDreyfusWagner.h:52
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::getSteinerTreeFor
T getSteinerTreeFor(const DWMData &data, EdgeWeightedGraphCopy< T > &tree) const
Adds edges to construct a Steiner tree from the given data (recursively) if the data is valid.
Definition: FullComponentGeneratorDreyfusWagner.h:315
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::m_terminals
const List< node > & m_terminals
A reference to the index-sorted list of terminals.
Definition: FullComponentGeneratorDreyfusWagner.h:53
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::FullComponentGeneratorDreyfusWagner
FullComponentGeneratorDreyfusWagner(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, const NodeArray< NodeArray< T >> &distance, const NodeArray< NodeArray< edge >> &pred)
The constructor.
Definition: FullComponentGeneratorDreyfusWagner.h:353
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::SortedNodeListHashFunc::hash
unsigned int hash(const List< node > &key) const
The actual hash function.
Definition: FullComponentGeneratorDreyfusWagner.h:416
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:209
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::safeIfSumSmaller
bool safeIfSumSmaller(const T summand1, const T summand2, const T compareValue) const
Checks overflow-safe if summand1 plus summand2 is less than compareValue.
Definition: FullComponentGeneratorDreyfusWagner.h:153
ogdf::Math::updateMin
void updateMin(T &min, const T &newValue)
Stores the minimum of min and newValue in min.
Definition: Math.h:98
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: List.h:42
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::SubsetEnumerator::forEachMemberAndNonmember
void forEachMemberAndNonmember(std::function< void(const T &)> funcIn, std::function< void(const T &)> funcNotIn) const
Calls funcIn for each subset member and funcNotIn for each other element of the set.
Definition: SubsetEnumerator.h:215
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::clear
void clear()
Remove all subgraphs and edges and set cost to zero.
Definition: FullComponentGeneratorDreyfusWagner.h:93
Math.h
Mathematical Helpers.
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::subgraphs
ArrayBuffer< const DWMData * > subgraphs
Definition: FullComponentGeneratorDreyfusWagner.h:65
ogdf::EdgeStandardType::tree
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::add
void add(const DWMData *other)
Adds other subgraph to ours.
Definition: FullComponentGeneratorDreyfusWagner.h:81
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::SortedNodeListHashFunc::m_random
const int m_random
Definition: FullComponentGeneratorDreyfusWagner.h:409
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::initializeMap
void initializeMap()
Initializes the hash array with all node-terminal-pairs.
Definition: FullComponentGeneratorDreyfusWagner.h:286
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::makeKey
void makeKey(List< node > &newSubset, List< node > &newComplement, const SubsetEnumerator< node > &subset, node v) const
Makes a list from subset and its complement, each including an correctly inserted node v.
Definition: FullComponentGeneratorDreyfusWagner.h:191
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::isValidComponent
bool isValidComponent(const EdgeWeightedGraphCopy< T > &graph) const
Checks if a given graph is a valid full component.
Definition: FullComponentGeneratorDreyfusWagner.h:391
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:40
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::add
void add(NodePair nodepair, T c)
Adds a nodepair of cost c.
Definition: FullComponentGeneratorDreyfusWagner.h:99
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::computePartialSolutions
void computePartialSolutions(const CONTAINER &nodeContainer)
Computes all partial solutions for given m_terminalSubset.
Definition: FullComponentGeneratorDreyfusWagner.h:273
ogdf::SubsetEnumerator::next
void next()
Obtains the next subset if possible. The result should be checked using the valid() method.
Definition: SubsetEnumerator.h:165
ogdf::List::size
int size() const
Returns the number of elements in the list.
Definition: List.h:1478
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMData::nodepairs
NodePairs nodepairs
Definition: FullComponentGeneratorDreyfusWagner.h:64
ogdf::ArrayBuffer::clear
void clear()
Clears the buffer.
Definition: ArrayBuffer.h:95
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMSplit
A collection of two subgraphs and their total cost.
Definition: FullComponentGeneratorDreyfusWagner.h:108
ogdf::randomNumber
int randomNumber(int low, int high)
Returns random integer between low and high (including).
Minisat::Internal::hash
static uint32_t hash(uint32_t x)
Definition: Map.h:38
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::DWMSplit::subgraph2
const DWMData * subgraph2
Definition: FullComponentGeneratorDreyfusWagner.h:111
ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner::dataOf
const DWMData * dataOf(const List< node > &key) const
Returns a pointer to the relevant data of the partial solution given by key.
Definition: FullComponentGeneratorDreyfusWagner.h:128
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::isTree
bool isTree(const Graph &G)
Returns true iff G is a tree, i.e. contains no undirected cycle and is connected.
Definition: simple_graph_alg.h:914
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::GraphCopyBase::original
const Graph & original() const
Returns a reference to the original graph.
Definition: GraphCopy.h:98
ogdf::SubsetEnumerator::numberOfMembersAndNonmembers
int numberOfMembersAndNonmembers() const
Returns the cardinality of the (super-)set. This is the maximum size that can be used for a subset.
Definition: SubsetEnumerator.h:141
SubsetEnumerator.h
A class that allows to enumerate k-subsets.