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>
38
39#include <map>
40#include <memory>
41#include <set>
42
43namespace ogdf {
44namespace planar_separators {
45
50public:
51 virtual ~BFSTree() = default;
52
57 virtual GraphCopy* getGraph() const = 0;
58
63 virtual node getRoot() const = 0;
64
69 virtual int getGraphSize() const = 0;
70
77 virtual bool isInTree(edge e) const = 0;
78
85 virtual int getLevelOfNode(node n) const = 0;
86
93 virtual node getParentOfNode(node n) const = 0;
94
101 virtual int getDescendantsOfNode(node n) const = 0;
102
109 virtual List<node> getChildrenOfNode(node n) const = 0;
110
117 virtual adjEntry getAdjToParent(node n) const = 0;
118};
119
124public:
131 ArrayBFSTree(GraphCopy& G, node rootNode) : pGraph {&G}, root {rootNode} { init(); }
132
136 void init() {
137 // init arrays
138 levelOfNode.init(*pGraph, -1);
139 parentOfNode.init(*pGraph, nullptr);
140 childrenOfNode.init(*pGraph);
141 edgeToParent.init(*pGraph, nullptr);
142 descendantsOfNode.init(*pGraph,
143 1); // number of descendants of a node, the node itself counts as its own descendant
144 inTree.init(*pGraph, false);
145 mark.init(*pGraph, false); // records if that node was visited by BFS
146
147 // mark root node
148 mark[root] = true;
149 }
150
151 GraphCopy* getGraph() const override { return pGraph; }
152
153 node getRoot() const override { return root; }
154
155 int getGraphSize() const override {
156 OGDF_ASSERT(pGraph != nullptr);
157 return pGraph->numberOfNodes();
158 }
159
160 bool isInTree(edge e) const override { return inTree[e]; }
161
162 int getLevelOfNode(node n) const override { return levelOfNode[n]; }
163
164 node getParentOfNode(node n) const override { return parentOfNode[n]; }
165
166 int getDescendantsOfNode(node n) const override { return descendantsOfNode[n]; }
167
168 List<node> getChildrenOfNode(node n) const override { return childrenOfNode[n]; }
169
170 adjEntry getAdjToParent(node n) const override { return edgeToParent[n]; }
171
172#ifdef OGDF_HEAVY_DEBUG
173 // this is very expensive
174 void assertTreeConsistency() const {
175 NodeArray<int> marked;
176 marked.init(*pGraph);
177 for (node no : pGraph->nodes) {
178 marked[no] = no->index();
179 }
180
181 for (edge e : pGraph->edges) {
182 if (isInTree(e)) {
183 node s = e->source();
184 node t = e->target();
185 OGDF_ASSERT(marked[s] != marked[t]);
186 int newIdx = marked[s] < marked[t] ? marked[s] : marked[t];
187 int otherIdx = marked[s] < marked[t] ? marked[t] : marked[s];
188
189 for (node no : pGraph->nodes) {
190 if (marked[no] == otherIdx) {
191 marked[no] = newIdx;
192 }
193 }
194 }
195 }
196
197 // afterwards, assert that all nodes are in fact marked
198 int lowest = marked[pGraph->firstNode()];
199 for (edge e : pGraph->edges) {
200 if (!isInTree(e)) {
201 OGDF_ASSERT(marked[e->source()] == lowest && marked[e->target()] == lowest);
202 }
203 }
204 }
205#endif
206
207
208protected:
210 node root; // root node
211
212 NodeArray<int> levelOfNode; // holds for each node on which level it is
213 NodeArray<node> parentOfNode; // holds for each node which node is his parent in the tree
214 NodeArray<List<node>> childrenOfNode; // holds for each node a list of children in the tree
215 NodeArray<adjEntry> edgeToParent; // holds for each node the edge which connects it to its parent
216 NodeArray<int> descendantsOfNode; // holds for each node how many descendants it has in the tree
218 EdgeArray<bool> inTree; // hold for each edge whether it is in the BFS tree
219};
220
225public:
234 BFSTreeClassical(GraphCopy& G, node rootNode, unsigned int heightMaxIterations,
235 bool findLevelsSimple = false);
236
238
245 void construct(node rootNode, unsigned int numIterations);
246
251
257 void createNewRoot(bool useTriBFS = false);
258
265 int getSizeOfLevel(int level) const;
266
273 List<node> getLevel(int level) const;
274
282 List<node> getNodesFromTo(int start, int end) const;
283
290 List<node> getNodesFrom(int start) const;
291
300 void restructure(List<node>& separator, List<node>& second, bool useTriBFS = false);
301
309
316 bool isVisited(node n) const { return mark[n]; }
317
318 int getSeparatorLevel() const { return currentLevel; }
319
320 int get_t0() const { return t0; }
321
322 int get_t1() const { return t1; }
323
324 int get_t2() const { return t2; }
325
326protected:
332
337
338
339private:
340 List<List<node>> levels; // contains all levels, each as a list of nodes
341
343 bool simple; // stupid workaround for being able to change generation of level t0 and t2
344
345 // construction
346 int currentLevel = 0;
347 bool belowMiddle = true;
348 double m_ratio;
349
350 // separator levels
351 int t0;
352 int t1;
353 int t2;
354 int k; // number of nodes in levels 0 through t1
355
356 void visit(node v, node parent, adjEntry adj, SListPure<node>& bfs);
357};
358
363public:
365
366 virtual ~Postprocessor() {};
367
377 virtual bool apply(const Graph& G, List<node>& separator, List<node>& first,
378 List<node>& second) = 0;
379
384 virtual std::string getName() const = 0;
385};
386
391public:
398 NodeExpulsor(bool balance = true) : keepBalance {balance} { }
399
400 bool apply(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) override;
401
402 std::string getName() const override { return "NE"; }
403
404private:
406};
407
414public:
415 bool apply(const Graph& G, List<node>& separator, List<node>& first, List<node>& second) override;
416
417 std::string getName() const override { return "DMD"; }
418
419private:
420 NodeArray<short> assignments; // assigns numbers to nodes: 0 = n is in separator, 1 = n is in shorter list, 2 = n is in longer list
421
422 List<node> bipartSep; // clones of separator nodes in the bipartite graph
423 List<node> bipartB; // clones of B-nodes in the bipartite graph
424
425 // arrays from original graph G
426 NodeArray<bool> isInS; // contains whether a node is in the separator or not
427 NodeArray<node> clone; // maps from G to bipartite graph
428
429 // arrays from bipartite graph
430 NodeArray<node> unclone; // maps from bipartite graph to G
431 EdgeArray<bool> flow; // contains whether an edge is in the matching or not
432
433 // Dulmage Mendelsohn Decomposition
437
441
445 void reset();
446
456 void setupAssignments(const Graph& G, const List<node>& separator, const List<node>& first,
457 const List<node>& second);
458
466
476 List<node>& second) const;
477
483 void calculateRemainders(const Graph& graph);
484
496
509
521};
522
527public:
534 Cycle(BFSTree* tree, edge startEdge);
535
537 tree = other.tree;
538 nodes = std::move(other.nodes);
539 edges = std::move(other.edges);
540 isOnCycle = std::move(other.isOnCycle);
541 isEdgeOnCycle = std::move(other.isEdgeOnCycle);
542 cycleRoot = other.cycleRoot;
543 costClock = other.costClock;
544 costCounter = other.costCounter;
545 isClockwise = other.isClockwise;
546
547 other.tree = nullptr;
548 other.cycleRoot = nullptr;
549
550 return *this;
551 }
552
554 : tree {other.tree}
555 , nodes(std::move(other.nodes))
556 , edges(std::move(other.edges))
557 , isOnCycle(std::move(other.isOnCycle))
558 , isEdgeOnCycle(std::move(other.isEdgeOnCycle))
559 , cycleRoot {other.cycleRoot}
560 , costClock {other.costClock}
561 , costCounter {other.costCounter}
562 , isClockwise {other.isClockwise} {
563 other.tree = nullptr;
564 other.cycleRoot = nullptr;
565 }
566
572 int getSize() const { return nodes.size(); }
573
580 bool getClockwise() const { return isClockwise; }
581
587 const List<node>& getNodes() const { return nodes; }
588
594 const List<adjEntry>& getEdges() const { return edges; }
595
601 const node& getRoot() const { return cycleRoot; }
602
609 int getInsideCost() const;
610
617 int getOutsideCost() const;
618
626
630 void print() const;
631
644 bool useRoot = false);
645
646private:
650 class Iterator {
651 private:
652 const Cycle* cycle;
654 const bool isClockwise;
655
663 adjEntry next;
664
665 if (isClockwise) {
666 if (cycle->isEdgeOnCycle[m_current->theEdge()]) {
667 next = current->twin()->cyclicSucc();
668 } else {
669 next = current->cyclicSucc();
670 }
671 } else {
672 if (cycle->isEdgeOnCycle[m_current->theEdge()]) {
673 next = current->twin()->cyclicPred();
674 } else {
675 next = current->cyclicPred();
676 }
677 }
678 if (next->theEdge() == cycle->getCurrentExpandEdge()->theEdge()) {
679 return nullptr;
680 }
681 return next;
682 }
683
684 public:
692 : cycle {cyc}, m_current {cyc->getCurrentExpandEdge()}, isClockwise {clockwise} {
693 ++(*this);
694 }
695
701 Iterator(const Cycle* cyc) : cycle(cyc), m_current(nullptr), isClockwise {false} { }
702
707 bool isOutEdge() {
708 return m_current->theNode() == cycle->cycleRoot
709 && m_current == cycle->tree->getAdjToParent(cycle->cycleRoot);
710 }
711
712 adjEntry operator*() const { return m_current; }
713
715 m_current = next(m_current);
716 while (m_current != nullptr
717 && cycle->isEdgeOnCycle[m_current->theEdge()]) { //m_current == cycle->sep.edgeToParent[m_current->theNode()]) {
718 m_current = next(m_current);
719 }
720 return *this;
721 }
722
724 Iterator tmp = *this;
725 ++(*this);
726 return tmp;
727 }
728
729 friend bool operator==(const Iterator& a, const Iterator& b) {
730 return a.m_current == b.m_current;
731 };
732
733 friend bool operator!=(const Iterator& a, const Iterator& b) {
734 return a.m_current != b.m_current;
735 };
736 };
737
738 BFSTree* tree; // the BFS-Tree with which this cycle is associated
739
740 List<node> nodes; // nodes on the cycle
741 List<adjEntry> edges; // edges on the cycle
742 NodeArray<bool> isOnCycle; // holds for each node whether it is on the cycle or not
743 EdgeArray<bool> isEdgeOnCycle; // holds for each edge whether it is on the cycle or not
744
745 node cycleRoot; // root node of the cycle, i.e. node in which its two arms meet
746
747 int costClock {0}; // cost of clockwise nodes
748 int costCounter {0}; // cost of counter-clockwise nodes
750
761
768 Cycle(BFSTree* tree, bool clockwise);
769
777 void init(List<node>& nodeList, List<adjEntry>& edgeList, node root);
778
780 Iterator begin() const { return Iterator(this, isClockwise); }
781
782 Iterator end() const { return Iterator(this); }
783
788
790
792
794
796
803
815
829 const adjEntry yw);
830
842 std::pair<node, node> findPathToCycle(node& y, List<node>& pathNodes,
844
860 const List<adjEntry>& pathAdjEntries, const node z, const node propRoot,
862
878 const node z, const node propRoot, const adjEntry vy, List<node>& oldNodes,
880
889
900 bool useRoot = false) const;
901
906};
907
908} // namespace planar_separators
909
910using namespace planar_separators;
911
913
917public:
919
921
927 void addPostProcessor(Postprocessor& post) { postProcessors.push_back(&post); }
928
932 void clearPostProcessors() { postProcessors.clear(); }
933
934 void setStartIndex(int index) { startNodeIndex = index; }
935
951 virtual bool separate(const Graph& G, List<node>& separator, List<node>& first,
953 if (setup(G, separator, first, second, checkPreconditions)) {
954 return true;
955 }
956
957 reset(); // reset everything to ensure the module can be reused
958
959 bool result = doSeparate(G, separator, first, second); // call core algorithm
960
961 if (result) {
962 cleanup(G, separator, first, second);
963
964 postProcess(G, separator, first, second);
965 }
966
967 return result;
968 }
969
979 virtual bool separate(const Graph& G, NodeArray<short>& assignments,
980 bool checkPreconditions = true) final {
981 OGDF_ASSERT(assignments.graphOf() == &G);
982
984 List<node> first;
986
987 bool result = separate(G, separator, first, second, checkPreconditions);
988
989 if (!result) {
990 return false;
991 }
992
993 for (node n : separator) {
994 assignments[n] = 0;
995 }
996 for (node n : first) {
997 assignments[n] = 1;
998 }
999 for (node n : second) {
1000 assignments[n] = 2;
1001 }
1002 return true;
1003 }
1004
1011 virtual std::string getName() const {
1012 std::string name = getSpecificName();
1013 for (const auto& post : postProcessors) {
1014 name += "_" + post->getName();
1015 }
1016 return name;
1017 }
1018
1024 std::string getExitPoint() const { return exitPoint; }
1025
1034 virtual double getMaxSeparatorSize(int n) const = 0;
1035
1036protected:
1037 std::vector<Postprocessor*> postProcessors;
1038
1039 std::shared_ptr<GraphCopy> graph;
1040
1041 int startNodeIndex = -1;
1042
1043 // the algorithms can return at different points - this variable stores where that happened, for analysis only
1044 std::string exitPoint;
1045
1052 node getStartNode(const Graph& G) const {
1053 if (startNodeIndex == -1) {
1054 return G.chooseNode();
1055 } else {
1056 return G.chooseNode([&](node n) { return (n->index() == startNodeIndex); });
1057 }
1058 }
1059
1070 virtual bool doSeparate(const Graph& G, List<node>& separator, List<node>& first,
1071 List<node>& second) = 0;
1072
1085 bool checkPreconditions = true) {
1086 exitPoint = "graph_trivial";
1087 if (G.empty()) {
1088 return true; // an empty graph is separated without us doing anything
1089 }
1090
1092
1093 graph = std::make_shared<GraphCopy>(G);
1094
1095 // call separateComponents to check if we even need to do anything, return success if not
1096 if (separateComponents(*graph, separator, first, second)) {
1097 return true;
1098 }
1099
1100 // even checking these conditions is expensive, so if you know that they all hold, you can skip this
1101 if (checkPreconditions) {
1102 if (!graph->representsCombEmbedding()) {
1103 planarEmbedPlanarGraph(*graph);
1104 }
1105 if (!isSimpleUndirected(*graph)) {
1106 makeSimpleUndirected(*graph);
1107 }
1108 }
1109
1110 OGDF_ASSERT(graph->representsCombEmbedding());
1111 OGDF_ASSERT(isConnected(*graph));
1113
1114 return false;
1115 }
1116
1128 if (first.empty() && second.empty()) {
1129 for (int i = 0; i < G.numberOfNodes() / 2.0; i++) {
1130 first.pushBack(separator.popFrontRet());
1131 }
1132 return true;
1133 }
1134 return false;
1135 }
1136
1149 List<node>& second, bool skip = false) const;
1150
1161 for (Postprocessor* post : postProcessors) {
1162 post->apply(G, separator, first, second);
1163 }
1164 return true;
1165 }
1166
1173 virtual std::string getSpecificName() const = 0;
1174
1178 virtual void reset() {};
1179
1180private:
1190 int connectedComponents(const Graph& G, NodeArray<int>& component,
1191 std::map<int, int>& compSizes) const;
1192};
1193
1194
1195}
Includes declaration of graph class.
Declaration of graph copy classes.
Class for adjacency list elements.
Definition Graph_d.h:79
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
Definition Graph_d.h:109
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition Graph_d.h:291
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:97
adjEntry cyclicPred() const
Returns the cyclic predecessor in the adjacency list.
Definition Graph_d.h:295
node theNode() const
Returns the node whose adjacency list contains this element.
Definition Graph_d.h:103
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:254
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:521
Doubly linked lists (maintaining the length of the list).
Definition List.h:1435
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1531
bool empty() const
Returns true iff the list is empty.
Definition List.h:270
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
const Graph * graphOf() const
Returns a pointer to the associated graph.
Definition NodeArray.h:173
void init()
Reinitializes the array. Associates the array with no graph.
Definition NodeArray.h:266
Class for the representation of nodes.
Definition Graph_d.h:177
int index() const
Returns the (unique) node index.
Definition Graph_d.h:211
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.
Singly linked lists.
Definition SList.h:179
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 DLL.
Definition config.h:101
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:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
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:110
Declaration of simple graph algorithms.