Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
PlanarSeparatorModule.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <ogdf/basic/Graph.h>
37#include <ogdf/basic/List.h>
38#include <ogdf/basic/basic.h>
41
42#include <functional>
43#include <map>
44#include <memory>
45#include <string>
46#include <utility>
47#include <vector>
48
49namespace ogdf {
50template<class E>
51class SListPure;
52
53namespace planar_separators {
54
59public:
60 virtual ~BFSTree() = default;
61
66 virtual GraphCopy* getGraph() const = 0;
67
72 virtual node getRoot() const = 0;
73
78 virtual int getGraphSize() const = 0;
79
86 virtual bool isInTree(edge e) const = 0;
87
94 virtual int getLevelOfNode(node n) const = 0;
95
102 virtual node getParentOfNode(node n) const = 0;
103
110 virtual int getDescendantsOfNode(node n) const = 0;
111
118 virtual List<node> getChildrenOfNode(node n) const = 0;
119
126 virtual adjEntry getAdjToParent(node n) const = 0;
127};
128
133public:
140 ArrayBFSTree(GraphCopy& G, node rootNode) : pGraph {&G}, root {rootNode} { init(); }
141
145 void init() {
146 // init arrays
147 levelOfNode.init(*pGraph, -1);
148 parentOfNode.init(*pGraph, nullptr);
149 childrenOfNode.init(*pGraph);
150 edgeToParent.init(*pGraph, nullptr);
151 descendantsOfNode.init(*pGraph,
152 1); // number of descendants of a node, the node itself counts as its own descendant
153 inTree.init(*pGraph, false);
154 mark.init(*pGraph, false); // records if that node was visited by BFS
155
156 // mark root node
157 mark[root] = true;
158 }
159
160 GraphCopy* getGraph() const override { return pGraph; }
161
162 node getRoot() const override { return root; }
163
164 int getGraphSize() const override {
165 OGDF_ASSERT(pGraph != nullptr);
166 return pGraph->numberOfNodes();
167 }
168
169 bool isInTree(edge e) const override { return inTree[e]; }
170
171 int getLevelOfNode(node n) const override { return levelOfNode[n]; }
172
173 node getParentOfNode(node n) const override { return parentOfNode[n]; }
174
175 int getDescendantsOfNode(node n) const override { return descendantsOfNode[n]; }
176
177 List<node> getChildrenOfNode(node n) const override { return childrenOfNode[n]; }
178
179 adjEntry getAdjToParent(node n) const override { return edgeToParent[n]; }
180
181#ifdef OGDF_HEAVY_DEBUG
182 // this is very expensive
183 void assertTreeConsistency() const {
184 NodeArray<int> marked;
185 marked.init(*pGraph);
186 for (node no : pGraph->nodes) {
187 marked[no] = no->index();
188 }
189
190 for (edge e : pGraph->edges) {
191 if (isInTree(e)) {
192 node s = e->source();
193 node t = e->target();
194 OGDF_ASSERT(marked[s] != marked[t]);
195 int newIdx = marked[s] < marked[t] ? marked[s] : marked[t];
196 int otherIdx = marked[s] < marked[t] ? marked[t] : marked[s];
197
198 for (node no : pGraph->nodes) {
199 if (marked[no] == otherIdx) {
200 marked[no] = newIdx;
201 }
202 }
203 }
204 }
205
206 // afterwards, assert that all nodes are in fact marked
207 int lowest = marked[pGraph->firstNode()];
208 for (edge e : pGraph->edges) {
209 if (!isInTree(e)) {
210 OGDF_ASSERT(marked[e->source()] == lowest && marked[e->target()] == lowest);
211 }
212 }
213 }
214#endif
215
216
217protected:
219 node root; // root node
220
221 NodeArray<int> levelOfNode; // holds for each node on which level it is
222 NodeArray<node> parentOfNode; // holds for each node which node is his parent in the tree
223 NodeArray<List<node>> childrenOfNode; // holds for each node a list of children in the tree
224 NodeArray<adjEntry> edgeToParent; // holds for each node the edge which connects it to its parent
225 NodeArray<int> descendantsOfNode; // holds for each node how many descendants it has in the tree
227 EdgeArray<bool> inTree; // hold for each edge whether it is in the BFS tree
228};
229
234public:
243 BFSTreeClassical(GraphCopy& G, node rootNode, unsigned int heightMaxIterations,
244 bool findLevelsSimple = false);
245
247
254 void construct(node rootNode, unsigned int numIterations);
255
260
266 void createNewRoot(bool useTriBFS = false);
267
274 int getSizeOfLevel(int level) const;
275
282 List<node> getLevel(int level) const;
283
291 List<node> getNodesFromTo(int start, int end) const;
292
299 List<node> getNodesFrom(int start) const;
300
309 void restructure(List<node>& separator, List<node>& second, bool useTriBFS = false);
310
317 void removeSeparatorLevels(List<node>& separator, List<node>& second);
318
325 bool isVisited(node n) const { return mark[n]; }
326
327 int getSeparatorLevel() const { return currentLevel; }
328
329 int get_t0() const { return t0; }
330
331 int get_t1() const { return t1; }
332
333 int get_t2() const { return t2; }
334
335protected:
341
346
347
348private:
349 List<List<node>> levels; // contains all levels, each as a list of nodes
350
352 bool simple; // stupid workaround for being able to change generation of level t0 and t2
353
354 // construction
355 int currentLevel = 0;
356 bool belowMiddle = true;
357 double m_ratio;
358
359 // separator levels
360 int t0;
361 int t1;
362 int t2;
363 int k; // number of nodes in levels 0 through t1
364
365 void visit(node v, node parent, adjEntry adj, SListPure<node>& bfs);
366};
367
372public:
374
375 virtual ~Postprocessor() {};
376
386 virtual bool apply(const Graph& G, List<node>& separator, List<node>& first,
387 List<node>& second) = 0;
388
393 virtual std::string getName() const = 0;
394};
395
400public:
407 NodeExpulsor(bool balance = true) : keepBalance {balance} { }
408
409 bool apply(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) override;
410
411 std::string getName() const override { return "NE"; }
412
413private:
415};
416
423public:
424 bool apply(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) override;
425
426 std::string getName() const override { return "DMD"; }
427
428private:
429 NodeArray<short> assignments; // assigns numbers to nodes: 0 = n is in separator, 1 = n is in shorter list, 2 = n is in longer list
430
431 List<node> bipartSep; // clones of separator nodes in the bipartite graph
432 List<node> bipartB; // clones of B-nodes in the bipartite graph
433
434 // arrays from original graph G
435 NodeArray<bool> isInS; // contains whether a node is in the separator or not
436 NodeArray<node> clone; // maps from G to bipartite graph
437
438 // arrays from bipartite graph
439 NodeArray<node> unclone; // maps from bipartite graph to G
440 EdgeArray<bool> flow; // contains whether an edge is in the matching or not
441
442 // Dulmage Mendelsohn Decomposition
446
450
454 void reset();
455
465 void setupAssignments(const Graph& G, const List<node>& separator, const List<node>& first,
466 const List<node>& second);
467
474 void bipartiteGraph(Graph& graph, const List<node>& separator);
475
484 void translateAssignments(const Graph& G, List<node>& separator, List<node>& first,
485 List<node>& second) const;
486
492 void calculateRemainders(const Graph& graph);
493
503 void chooseBalancedDecomposition(const Graph& G, List<node>& separator, List<node>& first,
504 List<node>& second);
505
516 bool alternatingBFS(const Graph& G, const List<node>& startNodes, List<node>& reachableSep,
517 List<node>& reachableB);
518
528 void decompose(const Graph& graph, const List<node>& bipart, List<node>& reachableSep,
529 List<node>& reachableB);
530};
531
536public:
543 Cycle(BFSTree* tree, edge startEdge);
544
546 tree = other.tree;
547 nodes = std::move(other.nodes);
548 edges = std::move(other.edges);
549 isOnCycle = std::move(other.isOnCycle);
550 isEdgeOnCycle = std::move(other.isEdgeOnCycle);
551 cycleRoot = other.cycleRoot;
552 costClock = other.costClock;
553 costCounter = other.costCounter;
554 isClockwise = other.isClockwise;
555
556 other.tree = nullptr;
557 other.cycleRoot = nullptr;
558
559 return *this;
560 }
561
562 Cycle(Cycle&& other)
563 : tree {other.tree}
564 , nodes(std::move(other.nodes))
565 , edges(std::move(other.edges))
566 , isOnCycle(std::move(other.isOnCycle))
567 , isEdgeOnCycle(std::move(other.isEdgeOnCycle))
568 , cycleRoot {other.cycleRoot}
569 , costClock {other.costClock}
570 , costCounter {other.costCounter}
571 , isClockwise {other.isClockwise} {
572 other.tree = nullptr;
573 other.cycleRoot = nullptr;
574 }
575
581 int getSize() const { return nodes.size(); }
582
589 bool getClockwise() const { return isClockwise; }
590
596 const List<node>& getNodes() const { return nodes; }
597
603 const List<adjEntry>& getEdges() const { return edges; }
604
610 const node& getRoot() const { return cycleRoot; }
611
618 int getInsideCost() const;
619
626 int getOutsideCost() const;
627
635
639 void print() const;
640
652 void fillLists(List<node>& separator, List<node>& first, List<node>& second,
653 bool useRoot = false);
654
655private:
659 class Iterator {
660 private:
661 const Cycle* cycle;
663 const bool isClockwise;
664
671 adjEntry next(adjEntry current) const {
672 adjEntry next;
673
674 if (isClockwise) {
675 if (cycle->isEdgeOnCycle[m_current->theEdge()]) {
676 next = current->twin()->cyclicSucc();
677 } else {
678 next = current->cyclicSucc();
679 }
680 } else {
681 if (cycle->isEdgeOnCycle[m_current->theEdge()]) {
682 next = current->twin()->cyclicPred();
683 } else {
684 next = current->cyclicPred();
685 }
686 }
687 if (next->theEdge() == cycle->getCurrentExpandEdge()->theEdge()) {
688 return nullptr;
689 }
690 return next;
691 }
692
693 public:
700 Iterator(const Cycle* cyc, bool clockwise)
701 : cycle {cyc}, m_current {cyc->getCurrentExpandEdge()}, isClockwise {clockwise} {
702 ++(*this);
703 }
704
710 Iterator(const Cycle* cyc) : cycle(cyc), m_current(nullptr), isClockwise {false} { }
711
716 bool isOutEdge() {
717 return m_current->theNode() == cycle->cycleRoot
718 && m_current == cycle->tree->getAdjToParent(cycle->cycleRoot);
719 }
720
721 adjEntry operator*() const { return m_current; }
722
724 m_current = next(m_current);
725 while (m_current != nullptr
726 && cycle->isEdgeOnCycle[m_current->theEdge()]) { //m_current == cycle->sep.edgeToParent[m_current->theNode()]) {
727 m_current = next(m_current);
728 }
729 return *this;
730 }
731
733 Iterator tmp = *this;
734 ++(*this);
735 return tmp;
736 }
737
738 friend bool operator==(const Iterator& a, const Iterator& b) {
739 return a.m_current == b.m_current;
740 };
741
742 friend bool operator!=(const Iterator& a, const Iterator& b) {
743 return a.m_current != b.m_current;
744 };
745 };
746
747 BFSTree* tree; // the BFS-Tree with which this cycle is associated
748
749 List<node> nodes; // nodes on the cycle
750 List<adjEntry> edges; // edges on the cycle
751 NodeArray<bool> isOnCycle; // holds for each node whether it is on the cycle or not
752 EdgeArray<bool> isEdgeOnCycle; // holds for each edge whether it is on the cycle or not
753
754 node cycleRoot; // root node of the cycle, i.e. node in which its two arms meet
755
756 int costClock {0}; // cost of clockwise nodes
757 int costCounter {0}; // cost of counter-clockwise nodes
759
769 Cycle(BFSTree* tree, List<node>& nodeList, List<adjEntry>& edgeList, node root, bool clockwise);
770
777 Cycle(BFSTree* tree, bool clockwise);
778
786 void init(List<node>& nodeList, List<adjEntry>& edgeList, node root);
787
789 Iterator begin() const { return Iterator(this, isClockwise); }
790
791 Iterator end() const { return Iterator(this); }
792
797
799
801
803
805
812
824
837 Cycle expandWithoutTreeEdges(node y, const node v, const node w, const adjEntry vy,
838 const adjEntry yw);
839
851 std::pair<node, node> findPathToCycle(node& y, List<node>& pathNodes,
852 List<adjEntry>& pathAdjEntries) const;
853
868 bool findAlphaCycle(Cycle& cyc, const List<node>& pathNodes,
869 const List<adjEntry>& pathAdjEntries, const node z, const node propRoot,
870 const adjEntry yw, List<node>& oldNodes, List<adjEntry>& oldEdges) const;
871
886 void findBetaCycle(Cycle& cyc, const List<node>& pathNodes, const List<adjEntry>& pathAdjEntries,
887 const node z, const node propRoot, const adjEntry vy, List<node>& oldNodes,
888 List<adjEntry>& oldEdges, bool foundRootOnAlpha) const;
889
897 void increaseCost(adjEntry adj, bool clockwise);
898
909 bool useRoot = false) const;
910
915};
916
917} // namespace planar_separators
918
919using namespace planar_separators;
920
922
926public:
928
930
936 void addPostProcessor(Postprocessor& post) { postProcessors.push_back(&post); }
937
941 void clearPostProcessors() { postProcessors.clear(); }
942
943 void setStartIndex(int index) { startNodeIndex = index; }
944
960 virtual bool separate(const Graph& G, List<node>& separator, List<node>& first,
961 List<node>& second, bool checkPreconditions = true) final {
962 if (setup(G, separator, first, second, checkPreconditions)) {
963 return true;
964 }
965
966 reset(); // reset everything to ensure the module can be reused
967
968 bool result = doSeparate(G, separator, first, second); // call core algorithm
969
970 if (result) {
971 cleanup(G, separator, first, second);
972
973 postProcess(G, separator, first, second);
974 }
975
976 return result;
977 }
978
988 virtual bool separate(const Graph& G, NodeArray<short>& assignments,
989 bool checkPreconditions = true) final {
990 OGDF_ASSERT(assignments.graphOf() == &G);
991
992 List<node> separator;
993 List<node> first;
994 List<node> second;
995
996 bool result = separate(G, separator, first, second, checkPreconditions);
997
998 if (!result) {
999 return false;
1000 }
1001
1002 for (node n : separator) {
1003 assignments[n] = 0;
1004 }
1005 for (node n : first) {
1006 assignments[n] = 1;
1007 }
1008 for (node n : second) {
1009 assignments[n] = 2;
1010 }
1011 return true;
1012 }
1013
1020 virtual std::string getName() const {
1021 std::string name = getSpecificName();
1022 for (const auto& post : postProcessors) {
1023 name += "_" + post->getName();
1024 }
1025 return name;
1026 }
1027
1033 std::string getExitPoint() const { return exitPoint; }
1034
1043 virtual double getMaxSeparatorSize(int n) const = 0;
1044
1045protected:
1046 std::vector<Postprocessor*> postProcessors;
1047
1048 std::shared_ptr<GraphCopy> graph;
1049
1050 int startNodeIndex = -1;
1051
1052 // the algorithms can return at different points - this variable stores where that happened, for analysis only
1053 std::string exitPoint;
1054
1061 node getStartNode(const Graph& G) const {
1062 if (startNodeIndex == -1) {
1063 return G.chooseNode();
1064 } else {
1065 return G.chooseNode([&](node n) { return (n->index() == startNodeIndex); });
1066 }
1067 }
1068
1079 virtual bool doSeparate(const Graph& G, List<node>& separator, List<node>& first,
1080 List<node>& second) = 0;
1081
1093 bool setup(const Graph& G, List<node>& separator, List<node>& first, List<node>& second,
1094 bool checkPreconditions = true) {
1095 exitPoint = "graph_trivial";
1096 if (G.empty()) {
1097 return true; // an empty graph is separated without us doing anything
1098 }
1099
1101
1102 graph = std::make_shared<GraphCopy>(G);
1103
1104 // call separateComponents to check if we even need to do anything, return success if not
1105 if (separateComponents(*graph, separator, first, second)) {
1106 return true;
1107 }
1108
1109 // even checking these conditions is expensive, so if you know that they all hold, you can skip this
1110 if (checkPreconditions) {
1111 if (!graph->representsCombEmbedding()) {
1112 planarEmbedPlanarGraph(*graph);
1113 }
1114 if (!isSimpleUndirected(*graph)) {
1115 makeSimpleUndirected(*graph);
1116 }
1117 }
1118
1119 OGDF_ASSERT(graph->representsCombEmbedding());
1120 OGDF_ASSERT(isConnected(*graph));
1122
1123 return false;
1124 }
1125
1136 bool cleanup(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) {
1137 if (first.empty() && second.empty()) {
1138 for (int i = 0; i < G.numberOfNodes() / 2.0; i++) {
1139 first.pushBack(separator.popFrontRet());
1140 }
1141 return true;
1142 }
1143 return false;
1144 }
1145
1158 List<node>& second, bool skip = false) const;
1159
1169 bool postProcess(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) {
1170 for (Postprocessor* post : postProcessors) {
1171 post->apply(G, separator, first, second);
1172 }
1173 return true;
1174 }
1175
1182 virtual std::string getSpecificName() const = 0;
1183
1187 virtual void reset() {};
1188
1189private:
1199 int connectedComponents(const Graph& G, NodeArray<int>& component,
1200 std::map<int, int>& compSizes) const;
1201};
1202
1203
1204}
Includes declaration of graph class.
Declaration of graph copy classes.
Decralation of GraphElement and GraphList classes.
Declaration of doubly linked lists and iterators.
Basic declarations, included by all source files.
Class for adjacency list elements.
Definition Graph_d.h:143
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
Definition Graph_d.h:173
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition Graph_d.h:355
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:161
adjEntry cyclicPred() const
Returns the cyclic predecessor in the adjacency list.
Definition Graph_d.h:359
node theNode() const
Returns the node whose adjacency list contains this element.
Definition Graph_d.h:167
Class for the representation of edges.
Definition Graph_d.h:364
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:390
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:866
Doubly linked lists (maintaining the length of the list).
Definition List.h:1451
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1547
E popFrontRet()
Removes the first element from the list and returns it.
Definition List.h:1591
bool empty() const
Returns true iff the list is empty.
Definition List.h:286
Class for the representation of nodes.
Definition Graph_d.h:241
int index() const
Returns the (unique) node index.
Definition Graph_d.h:275
Abstract description of all planar separator algorithms.
virtual bool separate(const Graph &G, NodeArray< short > &assignments, bool checkPreconditions=true) final
Separates a planar graph.
int connectedComponents(const Graph &G, NodeArray< int > &component, std::map< int, int > &compSizes) const
Finds all connected components within the graph.
void addPostProcessor(Postprocessor &post)
Adds a postprocessor to this separator, which will always be applied.
bool setup(const Graph &G, List< node > &separator, List< node > &first, List< node > &second, bool checkPreconditions=true)
Performs some initial setup to ensure that all preconditions hold and takes trivial steps to separate...
node getStartNode(const Graph &G) const
Selects the starting node for the BFS.
virtual std::string getName() const
Returns the full name of this algorithm.
bool cleanup(const Graph &G, List< node > &separator, List< node > &first, List< node > &second)
Performs built-in post-processing: For small instances, it can happen that all nodes are assigned to ...
std::vector< Postprocessor * > postProcessors
virtual bool doSeparate(const Graph &G, List< node > &separator, List< node > &first, List< node > &second)=0
Core of the specific separation algorithm - override this in inheriting classes.
virtual std::string getSpecificName() const =0
Returns the unique name of the core algorithm, to be combined with postprocessors later.
virtual void reset()
Reset everything to enable reuse of the module.
std::shared_ptr< GraphCopy > graph
virtual double getMaxSeparatorSize(int n) const =0
Provides the maximal separator size that this algorithm guarantees as a function of the number of nod...
bool separateComponents(GraphCopy &G, List< node > &separator, List< node > &first, List< node > &second, bool skip=false) const
Checks if the graph consists of multiple connected components, takes necessary steps for fixing that,...
std::string getExitPoint() const
Returns the exitPoint, i.e.
void clearPostProcessors()
Deletes all appended postprocessors from this separator.
virtual bool separate(const Graph &G, List< node > &separator, List< node > &first, List< node > &second, bool checkPreconditions=true) final
Separates a planar graph.
bool postProcess(const Graph &G, List< node > &separator, List< node > &first, List< node > &second)
Apply all postprocessors.
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Singly linked lists.
Definition SList.h:191
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition Graph_d.h:717
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition Graph_d.h:659
Graph * graphOf() const
Returns a pointer to the associated graph.
Definition Graph_d.h:666
Abstract BFSTree that is realized via NodeArrays.
int getLevelOfNode(node n) const override
Returns the level (=depth in the tree) for a node.
adjEntry getAdjToParent(node n) const override
Returns the adjEntry that leads up to the parent of n.
node getRoot() const override
Gets the current root node of the tree.
void init()
Initializes all internal arrays.
int getGraphSize() const override
Gets the number of nodes of the graph.
node getParentOfNode(node n) const override
Returns the node that is the parent of n in the tree.
int getDescendantsOfNode(node n) const override
Returns the total number of children, grandchildren etc.
bool isInTree(edge e) const override
Checks if an edge is a tree-edge.
GraphCopy * getGraph() const override
Allows access to a copy of the graph.
ArrayBFSTree(GraphCopy &G, node rootNode)
Constructor.
List< node > getChildrenOfNode(node n) const override
Returns all (immediate) children of a node.
BFS tree used by both classical algorithms (LT and Dual).
void createNewRoot(bool useTriBFS=false)
Creates a new root node for the graph, replacing all levels below t0.
List< node > getNodesFrom(int start) const
Returns all nodes from a given level onwards.
List< node > getNodesFromTo(int start, int end) const
Returns all nodes between two levels.
void findLevels()
Finds the levels t0 and t2 of the tree that might serve as separators.
void removeSeparatorLevels(List< node > &separator, List< node > &second)
Removes the two separator levels t0 and t2 from the tree.
void findLevelsSimple()
Simplified version of findLevels that simply finds a level smaller than sqrt(n).
int getSizeOfLevel(int level) const
Gets the size of a specific level.
List< node > getLevel(int level) const
Returns a level of the tree.
void reconstruct()
Reconstructs the tree using triangulating bfs.
void restructure(List< node > &separator, List< node > &second, bool useTriBFS=false)
Restructures the tree by adding a new root and deleting all nodes below t0 and above t2,...
bool isVisited(node n) const
Checks whether a node is visited by BFS.
void construct(node rootNode, unsigned int numIterations)
Constructs the tree.
void visit(node v, node parent, adjEntry adj, SListPure< node > &bfs)
BFSTreeClassical(GraphCopy &G, node rootNode, unsigned int heightMaxIterations, bool findLevelsSimple=false)
Constructor.
Abstract description of a Breadth First Search tree.
virtual node getParentOfNode(node n) const =0
Returns the node that is the parent of n in the tree.
virtual List< node > getChildrenOfNode(node n) const =0
Returns all (immediate) children of a node.
virtual int getDescendantsOfNode(node n) const =0
Returns the total number of children, grandchildren etc.
virtual bool isInTree(edge e) const =0
Checks if an edge is a tree-edge.
virtual int getGraphSize() const =0
Gets the number of nodes of the graph.
virtual node getRoot() const =0
Gets the current root node of the tree.
virtual int getLevelOfNode(node n) const =0
Returns the level (=depth in the tree) for a node.
virtual GraphCopy * getGraph() const =0
Allows access to a copy of the graph.
virtual adjEntry getAdjToParent(node n) const =0
Returns the adjEntry that leads up to the parent of n.
Special iterator to walk over the inward-pointing edges of the cycle.
friend bool operator!=(const Iterator &a, const Iterator &b)
Iterator(const Cycle *cyc, bool clockwise)
Constructor.
bool isOutEdge()
Checks whether the current adjEntry is the one that leads up to the root.
adjEntry next(adjEntry current) const
Yields the next adjEntry, given the current one (internal use only).
friend bool operator==(const Iterator &a, const Iterator &b)
Auxiliary data structure to represent Cycles in planar graphs.
void fillLists(List< node > &separator, List< node > &first, List< node > &second, bool useRoot=false)
Fills the lists of nodes, by putting all nodes on this cycle into the list of separator nodes and put...
int getSize() const
Returns the size of the cycle = the number of nodes on the cycle.
Iterator begin() const
Iterators for clockwise iteration over edges on the "inside", starting and ending at currentExpandEdg...
Cycle expandWithoutTreeEdges(node y, const node v, const node w, const adjEntry vy, const adjEntry yw)
Expand the cycle if none of the inner edges of the triangle is a tree edge.
bool findAlphaCycle(Cycle &cyc, const List< node > &pathNodes, const List< adjEntry > &pathAdjEntries, const node z, const node propRoot, const adjEntry yw, List< node > &oldNodes, List< adjEntry > &oldEdges) const
Used during expansion without tree edges.
Cycle(BFSTree *tree, List< node > &nodeList, List< adjEntry > &edgeList, node root, bool clockwise)
Constructor.
void findBetaCycle(Cycle &cyc, const List< node > &pathNodes, const List< adjEntry > &pathAdjEntries, const node z, const node propRoot, const adjEntry vy, List< node > &oldNodes, List< adjEntry > &oldEdges, bool foundRootOnAlpha) const
Used during expansion without tree edges.
int getInsideCost() const
Gets the cost on the inside of the cycle.
Cycle expandCycle()
Expands the cycle, as described by Lipton and Tarjan 1979, by examining the triangle adjacent to the ...
Cycle(BFSTree *tree, edge startEdge)
Constructor.
void collectChildrenOfNode(const node no, NodeArray< bool > &marked, List< node > &list, bool useRoot=false) const
Recursively creates a list containing all descendants of a node.
std::pair< node, node > findPathToCycle(node &y, List< node > &pathNodes, List< adjEntry > &pathAdjEntries) const
Used during expansion without tree edges.
void popBackNode()
Access methods for adding and removing nodes from the cycle.
const node & getRoot() const
Gives access to the root node of the cycle.
adjEntry getCurrentExpandEdge() const
Gets the current non-tree edge on the cycle, which is the one that will be used to expand the cycle f...
void init(List< node > &nodeList, List< adjEntry > &edgeList, node root)
Initializes the cycle (used by constructors).
void pushFrontEdge(adjEntry adj)
void print() const
Utility method for printing the cycle to the console.
Cycle(BFSTree *tree, bool clockwise)
Constructor.
const List< adjEntry > & getEdges() const
Gets the adjEntries on the cycle.
const List< node > & getNodes() const
Gets the nodes on the cycle.
void expandWithTreeEdge(node y, node v, node w, adjEntry vy, adjEntry yw)
Expand the Cycle when one of the inner edges of the triangle is a tree edge.
int getOutsideCost() const
Gets the cost on the outside of the cycle.
void computeCosts()
Computes the costs on both sides of the cycle.
void increaseCost(adjEntry adj, bool clockwise)
Increases the cost on the inside of this cycle by following the given adjEntry and adding the cost of...
bool getClockwise() const
Checks if the cycle is clockwise, i.e.
Dulmage-Mendelsohn-Decomposition.
void chooseBalancedDecomposition(const Graph &G, List< node > &separator, List< node > &first, List< node > &second)
Given the subsets SI / SX / SR and BI / BX / BR, creates a separator with minimal size so that the tw...
std::string getName() const override
Returns the human-readable identifier of this postprocessor.
bool apply(const Graph &G, List< node > &separator, List< node > &first, List< node > &second) override
Applies the postprocessor to a given separation.
bool alternatingBFS(const Graph &G, const List< node > &startNodes, List< node > &reachableSep, List< node > &reachableB)
Performs an alternating breadth first search to find all nodes in the separator that are reachable,...
void decompose(const Graph &graph, const List< node > &bipart, List< node > &reachableSep, List< node > &reachableB)
Given all nodes in the bipartite graph, selects starting points for the BFS and finds the reachable n...
void reset()
Resets the component so it can be reused.
void setupAssignments(const Graph &G, const List< node > &separator, const List< node > &first, const List< node > &second)
Fills a the NodeArray assignments with the values 0, 1 and 2 to represent the assignments of nodes to...
void bipartiteGraph(Graph &graph, const List< node > &separator)
Creates a bipartite graph from the nodes in the separator and those in the bigger component.
void calculateRemainders(const Graph &graph)
Calculates the subset SR and BR once SI / SX and BI / BX have been found.
void translateAssignments(const Graph &G, List< node > &separator, List< node > &first, List< node > &second) const
Translates the assignments stored in the NodeArray assignments back to the lists, which can then be r...
NodeExpulsor: Remove all nodes that are not connected to both halves of the separation.
std::string getName() const override
Returns the human-readable identifier of this postprocessor.
NodeExpulsor(bool balance=true)
Constructor.
bool apply(const Graph &G, List< node > &separator, List< node > &first, List< node > &second) override
Applies the postprocessor to a given separation.
Abstract description of postprocessors.
virtual bool apply(const Graph &G, List< node > &separator, List< node > &first, List< node > &second)=0
Applies the postprocessor to a given separation.
virtual std::string getName() const =0
Returns the human-readable identifier of this postprocessor.
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF dynamic library (shared object / DLL),...
Definition config.h:117
Declaration of extended graph algorithms.
bool isConnected(const Graph &G)
Returns true iff G is connected.
bool isSimpleUndirected(const Graph &G)
Returns true iff G contains neither self-loops nor undirected parallel edges.
void makeSimpleUndirected(Graph &G)
Removes all self-loops and all but one edge of each bundle of undirected parallel edges.
bool planarEmbedPlanarGraph(Graph &G)
Constructs a planar embedding of G. It assumes that G is planar!
bool isPlanar(const Graph &G)
Returns true, if G is planar, false otherwise.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
Definition GML.h:111
Declaration of simple graph algorithms.