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