Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinSteinerTreeShore.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 // enable this to print messages
36 // for all branches (edge inclusion or exclusion)
37 // additionally a SVG image is generated for each
38 // recursion depth
39 //#define OGDF_MINSTEINERTREE_SHORE_LOGGING
40 
41 #include <ogdf/basic/EdgeArray.h>
42 #include <ogdf/basic/List.h>
43 #include <ogdf/basic/NodeArray.h>
44 #include <ogdf/basic/NodeSet.h>
47 
48 #include <memory>
49 
50 namespace ogdf {
51 
62 template<typename T>
64 public:
65  MinSteinerTreeShore() : MAX_WEIGHT(std::numeric_limits<T>::max()) {};
66  virtual ~MinSteinerTreeShore() {};
67 
68 protected:
84  virtual T computeSteinerTree(const EdgeWeightedGraph<T>& G, const List<node>& terminals,
85  const NodeArray<bool>& isTerminal, EdgeWeightedGraphCopy<T>*& finalSteinerTree) override;
86 
87  const T MAX_WEIGHT;
88 
89 private:
92 
94  std::unique_ptr<NodeSet<>> m_terminals;
100 
109  bool validateMapping() const;
110 
119  T weightOf(edge e) const;
120 
137  T bnbInternal(T prevCost, List<edge>& currentEdges);
138 
146  edge deleteEdge(edge e);
147 
158  edge newEdge(node source, node target, const edge originalEdge);
159 
168  void moveSource(edge e, node v);
169 
178  void moveTarget(edge e, node v);
179 
191  void setTerminal(const node v, bool makeTerminal);
192 
205  bool isTerminal(const node v) const;
206 
219  void setEdgeLookup(const node u, const node v, const edge e);
220 
233  edge lookupEdge(const node u, const node v) const;
234 
248  edge determineBranchingEdge(T prevCost) const;
249 
257  T solve(List<edge>& chosenEdges);
258 
263  void printSVG();
264 };
265 
266 template<typename T>
268  const List<node>& terminals, const NodeArray<bool>& isTerminal,
269  EdgeWeightedGraphCopy<T>*& finalSteinerTree) {
270  m_originalGraph = &G;
271  m_originalTerminals = &terminals;
272 
273  m_upperBound = MAX_WEIGHT;
274  m_graph.clear();
275  m_mapping.init(m_graph);
276  m_terminals.reset(new NodeSet<>(m_graph));
277  int nodeCount = m_originalGraph->numberOfNodes();
278  m_edges = Array2D<edge>(0, nodeCount, 0, nodeCount, nullptr);
279 
280  NodeArray<node> copiedNodes(*m_originalGraph);
281 
282  for (node v : m_originalGraph->nodes) {
283  node copiedNode = m_graph.newNode();
284  copiedNodes[v] = copiedNode;
285  }
286 
287  for (edge e : m_originalGraph->edges) {
288  node source = copiedNodes[e->source()], target = copiedNodes[e->target()];
289 
290  newEdge(source, target, e);
291  }
292 
293  for (node v : *m_originalTerminals) {
294  setTerminal(copiedNodes[v], true);
295  }
296 
297  List<edge> chosenEdges;
298  T result = solve(chosenEdges);
299 
300  finalSteinerTree = new EdgeWeightedGraphCopy<T>();
301  finalSteinerTree->setOriginalGraph(*m_originalGraph);
302 
303  for (edge e : chosenEdges) {
304  node v = e->source();
305  node w = e->target();
306 
307  OGDF_ASSERT(v != nullptr);
308  OGDF_ASSERT(w != nullptr);
309  OGDF_ASSERT(e->graphOf() == m_originalGraph);
310  OGDF_ASSERT(v->graphOf() == m_originalGraph);
311  OGDF_ASSERT(w->graphOf() == m_originalGraph);
312 
313  if (finalSteinerTree->copy(v) == nullptr) {
314  finalSteinerTree->newNode(v);
315  }
316  if (finalSteinerTree->copy(w) == nullptr) {
317  finalSteinerTree->newNode(w);
318  }
319  finalSteinerTree->newEdge(e, m_originalGraph->weight(e));
320  }
321 
322  return result;
323 }
324 
325 template<typename T>
327  T result = MAX_WEIGHT;
328 
329  if (e != nullptr) {
330  OGDF_ASSERT(e->graphOf() == &m_graph);
331  OGDF_ASSERT(m_mapping[e] != nullptr);
332  OGDF_ASSERT(m_mapping[e]->graphOf() == m_originalGraph);
333  result = m_originalGraph->weight(m_mapping[e]);
334  }
335 
336  return result;
337 }
338 
339 template<typename T>
341  for (edge e : m_graph.edges) {
342  OGDF_ASSERT(m_mapping[e] != nullptr);
343  OGDF_ASSERT(m_mapping[e]->graphOf() == m_originalGraph);
344  }
345  return true;
346 }
347 
348 template<typename T>
350  return m_edges(u->index(), v->index());
351 }
352 
353 template<typename T>
354 void MinSteinerTreeShore<T>::setEdgeLookup(const node u, const node v, const edge e) {
355  m_edges(u->index(), v->index()) = m_edges(v->index(), u->index()) = e;
356 }
357 
358 template<typename T>
360  edge result = m_mapping[e];
361  setEdgeLookup(e->source(), e->target(), nullptr);
362  m_graph.delEdge(e);
363  e->~EdgeElement();
364 
365  return result;
366 }
367 
368 template<typename T>
370  edge result = m_graph.newEdge(source, target);
371  m_mapping[result] = e;
372  setEdgeLookup(source, target, result);
373 
374  return result;
375 }
376 
377 template<typename T>
379  OGDF_ASSERT(e != nullptr);
380  setEdgeLookup(e->source(), e->target(), nullptr);
381  setEdgeLookup(v, e->target(), e);
382  m_graph.moveSource(e, v);
383 }
384 
385 template<typename T>
387  OGDF_ASSERT(e != nullptr);
388  setEdgeLookup(e->source(), e->target(), nullptr);
389  setEdgeLookup(e->source(), v, e);
390  m_graph.moveTarget(e, v);
391 }
392 
393 template<typename T>
395  return m_terminals->isMember(v);
396 }
397 
398 template<typename T>
399 void MinSteinerTreeShore<T>::setTerminal(const node v, bool makeTerminal) {
400  if (makeTerminal) {
401  m_terminals->insert(v);
402  } else {
403  m_terminals->remove(v);
404  }
405 }
406 
407 template<typename T>
409  m_chosenEdges.clear();
410 
411  m_recursionDepth = 0;
412  List<edge> tmp;
413  T result = bnbInternal(0, tmp);
414 
415  for (edge e : m_chosenEdges) {
416  chosenEdges.pushFront(e);
417  }
418 
419  return result;
420 }
421 
422 template<typename T>
424  edge result = nullptr;
425  T maxPenalty = -1;
426 
427  // calculate penalties for nodes
428  T sumOfMinWeights = 0; // b
429  T sumOfMinTermWeights = 0; // c
430  T absoluteMinTermWeight = MAX_WEIGHT;
431  for (ListConstIterator<node> it = m_terminals->nodes().begin();
432  sumOfMinWeights < MAX_WEIGHT && it.valid(); ++it) {
433  const node t = *it;
434  T minTermWeight = MAX_WEIGHT, minWeight = MAX_WEIGHT, secondMinWeight = MAX_WEIGHT;
435  edge minEdge = nullptr;
436 
437  // investigate all edges of each terminal
438  // calculate lower boundary and find branching edge
439  for (adjEntry adj = t->firstAdj(); adj; adj = adj->succ()) {
440  edge e = adj->theEdge();
441  if (weightOf(e) < minWeight) {
442  secondMinWeight = minWeight;
443  minWeight = weightOf(e);
444  minEdge = e;
445  } else {
446  if (weightOf(e) < secondMinWeight) {
447  secondMinWeight = weightOf(e);
448  }
449  }
450 
451  if (isTerminal(adj->twinNode()) && weightOf(e) < minTermWeight) {
452  minTermWeight = weightOf(e);
453  if (minTermWeight < absoluteMinTermWeight) {
454  absoluteMinTermWeight = minTermWeight;
455  }
456  }
457  }
458 
459  if (sumOfMinTermWeights < MAX_WEIGHT && minTermWeight < MAX_WEIGHT) {
460  sumOfMinTermWeights += minTermWeight;
461  } else {
462  sumOfMinTermWeights = MAX_WEIGHT;
463  }
464  OGDF_ASSERT(absoluteMinTermWeight <= sumOfMinTermWeights);
465 
466  // is terminal isolated or has only one edge?
467  // if so we can break here
468  if (minWeight == MAX_WEIGHT || secondMinWeight == MAX_WEIGHT) {
469  result = minEdge;
470  if (minWeight == MAX_WEIGHT) {
471  sumOfMinWeights = MAX_WEIGHT;
472  }
473  } else {
474  sumOfMinWeights += minWeight;
475  // update branching edge if need be
476  T penalty = secondMinWeight - minWeight;
477  if (penalty > maxPenalty) {
478  maxPenalty = penalty;
479  result = minEdge;
480  }
481  }
482  }
483 
484  // compare bounds for this graph
485  if (result != nullptr) {
486  T maxCost = m_upperBound - prevCost;
487  if (sumOfMinTermWeights < MAX_WEIGHT) {
488  sumOfMinTermWeights -= absoluteMinTermWeight;
489  }
490  if (maxCost <= sumOfMinWeights && maxCost <= sumOfMinTermWeights) {
491  result = nullptr;
492  }
493  }
494 
495  return result;
496 }
497 
498 template<typename T>
499 T MinSteinerTreeShore<T>::bnbInternal(T prevCost, List<edge>& currentEdges) {
500  T result = MAX_WEIGHT;
501  m_recursionDepth++;
502 
503 #ifdef OGDF_MINSTEINERTREE_SHORE_LOGGING
504  printSVG();
505 #endif
506 
507  if (prevCost <= m_upperBound) {
508  if (m_terminals->size() < 2) {
509  // update currently chosen edges
510  if (prevCost != m_upperBound || m_chosenEdges.empty()) {
511  m_chosenEdges = List<edge>(currentEdges);
512  }
513  // all terminals are connected
514  m_upperBound = prevCost;
515  result = prevCost;
516  } else {
517  edge branchingEdge = determineBranchingEdge(prevCost);
518  T branchingEdgeWeight = weightOf(branchingEdge);
519 
520 #ifdef OGDF_MINSTEINERTREE_SHORE_LOGGING
521  for (int i = 0; i < m_recursionDepth; i++) {
522  std::cout << " ";
523  }
524  std::cout << "branching on edge: " << branchingEdge << std::endl;
525 #endif
526  // branching edge has been found or there is no feasible solution
527  if (branchingEdgeWeight < MAX_WEIGHT) {
528  // chose node to remove
529  node nodeToRemove = branchingEdge->source();
530  node targetNode = branchingEdge->target();
531 
532  // This seems to speed up things.
533  if (nodeToRemove->degree() < targetNode->degree()) {
534  nodeToRemove = branchingEdge->target();
535  targetNode = branchingEdge->source();
536  }
537 
538  // remove branching edge
539  edge origBranchingEdge = deleteEdge(branchingEdge);
540 
541  List<node> delEdges, movedEdges;
542  List<edge> origDelEdges;
543 
544  // first branch: Inclusion of the edge
545  // remove source node of edge and calculate new edge weights
546  OGDF_ASSERT(targetNode != nullptr);
547  OGDF_ASSERT(nodeToRemove != nullptr);
548 
549  // remove edges in case of multigraph
550  while (m_graph.searchEdge(targetNode, nodeToRemove) != nullptr) {
551  edge e = m_graph.searchEdge(targetNode, nodeToRemove);
552  delEdges.pushFront(e->target());
553  delEdges.pushFront(e->source());
554  origDelEdges.pushFront(m_mapping[e]);
555  deleteEdge(e);
556  }
557  while (m_graph.searchEdge(nodeToRemove, targetNode) != nullptr) {
558  edge e = m_graph.searchEdge(targetNode, nodeToRemove);
559  delEdges.pushFront(e->target());
560  delEdges.pushFront(e->source());
561  origDelEdges.pushFront(m_mapping[e]);
562  deleteEdge(e);
563  }
564 
565  OGDF_ASSERT(m_graph.searchEdge(targetNode, nodeToRemove) == nullptr);
566  OGDF_ASSERT(m_graph.searchEdge(nodeToRemove, targetNode) == nullptr);
567 
568  adjEntry adjNext;
569  for (adjEntry adj = nodeToRemove->firstAdj(); adj; adj = adjNext) {
570  adjNext = adj->succ();
571  edge e = adj->theEdge();
572 
573  OGDF_ASSERT(e != branchingEdge);
574  OGDF_ASSERT(e->target() == nodeToRemove || e->source() == nodeToRemove);
575  OGDF_ASSERT(adj->twinNode() != targetNode);
576 
577  edge f = lookupEdge(targetNode, adj->twinNode());
578  bool deletedEdgeE = false;
579  if (f != nullptr) {
580  if (weightOf(f) < weightOf(e)) {
581  delEdges.pushFront(e->target());
582  delEdges.pushFront(e->source());
583  origDelEdges.pushFront(m_mapping[e]);
584  deleteEdge(e);
585 
586  deletedEdgeE = true;
587  } else {
588  delEdges.pushFront(f->target());
589  delEdges.pushFront(f->source());
590  origDelEdges.pushFront(m_mapping[f]);
591  deleteEdge(f);
592  }
593  }
594  if (!deletedEdgeE) {
595  if (e->target() == nodeToRemove) {
596  OGDF_ASSERT(e->source() != targetNode);
597  movedEdges.pushFront(e->source());
598  moveTarget(e, targetNode);
599  } else {
600  OGDF_ASSERT(e->source() == nodeToRemove);
601  OGDF_ASSERT(e->target() != targetNode);
602  movedEdges.pushFront(e->target());
603  moveSource(e, targetNode);
604  }
605  }
606  }
607  // nodeToRemove is isolated at this point
608  // thus no need to actually remove it
609  // (easier to keep track of CopyGraph mapping)
610 
611  // remove node from terminals too
612  bool targetNodeIsTerminal = isTerminal(targetNode),
613  nodeToRemoveIsTerminal = isTerminal(nodeToRemove);
614 
615  OGDF_ASSERT(targetNodeIsTerminal || nodeToRemoveIsTerminal);
616  setTerminal(nodeToRemove, false);
617  setTerminal(targetNode, true);
618 
619 #ifdef OGDF_MINSTEINERTREE_SHORE_LOGGING
620  for (int i = 0; i < m_recursionDepth; i++) {
621  std::cout << " ";
622  }
623  std::cout << "inclusion branch" << std::endl;
624 #endif
625  // calculate result on modified graph
626  currentEdges.pushFront(origBranchingEdge);
627  result = bnbInternal(branchingEdgeWeight + prevCost, currentEdges);
628  OGDF_ASSERT(currentEdges.front() == origBranchingEdge);
629  currentEdges.popFront();
630 
631  // restore previous graph
632 
633  // restore terminals
634  setTerminal(nodeToRemove, nodeToRemoveIsTerminal);
635  setTerminal(targetNode, targetNodeIsTerminal);
636 
637  // restore moved edges
638  while (!movedEdges.empty()) {
639  node v = movedEdges.popFrontRet();
640 
641  edge e = lookupEdge(v, targetNode);
642  OGDF_ASSERT(e != nullptr);
643  OGDF_ASSERT(e->opposite(targetNode) != nodeToRemove);
644 
645  if (e->source() == v) {
646  moveTarget(e, nodeToRemove);
647  } else {
648  moveSource(e, nodeToRemove);
649  }
650  }
651 
652  // restore deleted edges
653  while (!delEdges.empty()) {
654  OGDF_ASSERT(!origDelEdges.empty());
655 
656  node source = delEdges.popFrontRet();
657  node target = delEdges.popFrontRet();
658 
659  newEdge(source, target, origDelEdges.popFrontRet());
660  }
661  OGDF_ASSERT(origDelEdges.empty());
662 
663 #ifdef OGDF_MINSTEINERTREE_SHORE_LOGGING
664  for (int i = 0; i < m_recursionDepth; i++) {
665  std::cout << " ";
666  }
667  std::cout << "exclusion branch" << std::endl;
668 #endif
669  // sencond branch: Exclusion of the edge
670  T exEdgeResult = bnbInternal(prevCost, currentEdges);
671 
672  // decide which branch returned best result
673  if (exEdgeResult < result) {
674  result = exEdgeResult;
675  }
676 
677  // finally: restore the branching edge
678  newEdge(nodeToRemove, targetNode, origBranchingEdge);
679  }
680  }
681  OGDF_ASSERT(validateMapping());
682  }
683  m_recursionDepth--;
684  return result;
685 }
686 
687 template<typename T>
689  EdgeWeightedGraphCopy<T> copiedGraph;
690  copiedGraph.setOriginalGraph(m_graph);
691  List<node> nodes;
692  m_graph.allNodes(nodes);
693  NodeArray<bool> copiedIsTerminal(m_graph);
694  for (node v : nodes) {
695  copiedGraph.newNode(v);
696  copiedIsTerminal[v] = isTerminal(v);
697  }
698  List<edge> edges;
699  m_graph.allEdges(edges);
700  for (edge e : edges) {
701  copiedGraph.newEdge(e, weightOf(e));
702  }
703  std::stringstream filename;
704  filename << "bnb_internal_" << m_recursionDepth << ".svg";
705  this->drawSteinerTreeSVG(copiedGraph, copiedIsTerminal, filename.str().c_str());
706 }
707 
708 }
ogdf::MinSteinerTreeShore::~MinSteinerTreeShore
virtual ~MinSteinerTreeShore()
Definition: MinSteinerTreeShore.h:66
NodeSet.h
Declaration and implementation of ogdf::NodeSet.
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MinSteinerTreeShore::m_edges
Array2D< edge > m_edges
Definition: MinSteinerTreeShore.h:97
ogdf::MinSteinerTreeShore::m_terminals
std::unique_ptr< NodeSet<> > m_terminals
Definition: MinSteinerTreeShore.h:94
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::List::popFront
void popFront()
Removes the first element from the list.
Definition: List.h:1575
ogdf::MinSteinerTreeShore::m_mapping
EdgeArray< edge > m_mapping
Definition: MinSteinerTreeShore.h:95
ogdf::NodeElement::index
int index() const
Returns the (unique) node index.
Definition: Graph_d.h:267
ogdf::MinSteinerTreeShore::setTerminal
void setTerminal(const node v, bool makeTerminal)
Updates the status of the given node to either terminal or Steiner node.
Definition: MinSteinerTreeShore.h:399
ogdf::MinSteinerTreeShore::isTerminal
bool isTerminal(const node v) const
Returns whether this node is a terminal or a Steiner node.
Definition: MinSteinerTreeShore.h:394
ogdf::EdgeWeightedGraphCopy::setOriginalGraph
void setOriginalGraph(const Graph *wG) override
Associates the graph copy with G, but does not create any nodes or edges.
Definition: EdgeWeightedGraphCopy.h:158
ogdf::List::popFrontRet
E popFrontRet()
Removes the first element from the list and returns it.
Definition: List.h:1581
ogdf::MinSteinerTreeShore::setEdgeLookup
void setEdgeLookup(const node u, const node v, const edge e)
Sets the edge incident to both node u and v.
Definition: MinSteinerTreeShore.h:354
ogdf::MinSteinerTreeShore::validateMapping
bool validateMapping() const
Used to validate the current mapping of edges to orignal edges Used solely for debugging.
Definition: MinSteinerTreeShore.h:340
ogdf::MinSteinerTreeShore::m_upperBound
T m_upperBound
Definition: MinSteinerTreeShore.h:96
ogdf::ListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: List.h:143
ogdf::MinSteinerTreeShore::deleteEdge
edge deleteEdge(edge e)
Removes the specified edge from the graph.
Definition: MinSteinerTreeShore.h:359
ogdf::MinSteinerTreeShore::printSVG
void printSVG()
Prints the current recursion status as a SVG image of the current reduced STP.
Definition: MinSteinerTreeShore.h:688
ogdf::EdgeWeightedGraphCopy::newEdge
edge newEdge(node u, node v, T weight)
Definition: EdgeWeightedGraphCopy.h:165
ogdf::NodeSet
Node sets.
Definition: GraphSets.h:52
ogdf::Array2D
The parameterized class Array2D implements dynamic two-dimensional arrays.
Definition: Array2D.h:47
ogdf::MinSteinerTreeShore::computeSteinerTree
virtual T computeSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Builds a minimum Steiner tree given a weighted graph and a list of terminals.
Definition: MinSteinerTreeShore.h:267
ogdf::MinSteinerTreeShore::m_originalTerminals
const List< node > * m_originalTerminals
Definition: MinSteinerTreeShore.h:91
ogdf::MinSteinerTreeShore::m_recursionDepth
int m_recursionDepth
Definition: MinSteinerTreeShore.h:99
ogdf::MinSteinerTreeShore::m_chosenEdges
List< edge > m_chosenEdges
Definition: MinSteinerTreeShore.h:98
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:135
EdgeWeightedGraphCopy.h
Extends the GraphCopy concept to weighted graphs.
ogdf::MinSteinerTreeModule
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
Definition: MinSteinerTreeModule.h:59
MinSteinerTreeModule.h
Declaration of ogdf::MinSteinerTreeModule.
ogdf::MinSteinerTreeShore::moveTarget
void moveTarget(edge e, node v)
Moves the target of the edge to the specified node.
Definition: MinSteinerTreeShore.h:386
ogdf::EdgeElement::graphOf
const Graph * graphOf() const
Returns the graph containing this node (debug only).
Definition: Graph_d.h:433
ogdf::NodeElement::degree
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition: Graph_d.h:276
ogdf::List::pushFront
iterator pushFront(const E &x)
Adds element x at the beginning of the list.
Definition: List.h:1524
ogdf::MinSteinerTreeShore
Implementation of Shore, Foulds and Gibbons exact branch and bound algorithm for solving Steiner tree...
Definition: MinSteinerTreeShore.h:63
ogdf::EdgeWeightedGraph
Definition: EdgeWeightedGraph.h:39
ogdf::AdjElement::succ
adjEntry succ() const
Returns the successor in the adjacency list.
Definition: Graph_d.h:211
EdgeArray.h
Declaration and implementation of EdgeArray class.
ogdf::MinSteinerTreeShore::MAX_WEIGHT
const T MAX_WEIGHT
Definition: MinSteinerTreeShore.h:87
ogdf::MinSteinerTreeShore::moveSource
void moveSource(edge e, node v)
Moves the source of the edge to the specified node.
Definition: MinSteinerTreeShore.h:378
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::GraphCopyBase::newNode
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Definition: GraphCopy.h:185
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: List.h:42
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
ogdf::GraphCopy::copy
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition: GraphCopy.h:457
NodeArray.h
Declaration and implementation of NodeArray class.
ogdf::MinSteinerTreeShore::newEdge
edge newEdge(node source, node target, const edge originalEdge)
Creates a new edge.
Definition: MinSteinerTreeShore.h:369
ogdf::MinSteinerTreeShore::m_originalGraph
const EdgeWeightedGraph< T > * m_originalGraph
Definition: MinSteinerTreeShore.h:90
std
Definition: GML.h:110
ogdf::MinSteinerTreeShore::MinSteinerTreeShore
MinSteinerTreeShore()
Definition: MinSteinerTreeShore.h:65
ogdf::NodeElement::firstAdj
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Definition: Graph_d.h:279
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:40
ogdf::EdgeElement::opposite
node opposite(node v) const
Returns the adjacent node different from v.
Definition: Graph_d.h:406
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
List.h
Declaration of doubly linked lists and iterators.
ogdf::NodeElement::graphOf
const Graph * graphOf() const
Returns the graph containing this node (debug only).
Definition: Graph_d.h:337
ogdf::MinSteinerTreeShore::determineBranchingEdge
edge determineBranchingEdge(T prevCost) const
Decides which edge to branch on.
Definition: MinSteinerTreeShore.h:423
ogdf::MinSteinerTreeShore::m_graph
Graph m_graph
Definition: MinSteinerTreeShore.h:93
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:46
ogdf::MinSteinerTreeShore::lookupEdge
edge lookupEdge(const node u, const node v) const
Retrieves the edge incident to both node u and v.
Definition: MinSteinerTreeShore.h:349
ogdf::MinSteinerTreeShore::solve
T solve(List< edge > &chosenEdges)
Solves the current STP instance.
Definition: MinSteinerTreeShore.h:408
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::MinSteinerTreeShore::bnbInternal
T bnbInternal(T prevCost, List< edge > &currentEdges)
Calculates the optimal Steinter tree recursivly.
Definition: MinSteinerTreeShore.h:499
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::List::clear
void clear()
Removes all elements from the list.
Definition: List.h:1616
ogdf::MinSteinerTreeShore::weightOf
T weightOf(edge e) const
Returns the cost of the specified edge.
Definition: MinSteinerTreeShore.h:326