Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
StarInserter.h
Go to the documentation of this file.
1
32#pragma once
33
36#include <ogdf/basic/Graph.h>
38#include <ogdf/basic/basic.h>
39#include <ogdf/basic/comparer.h>
40
41#include <memory>
42#include <unordered_map>
43
44namespace ogdf {
45template<class E>
46class List;
47template<class E>
48class SList;
49
50using PredecessorMap = std::unordered_map<node, std::unique_ptr<NodeArray<edge>>>;
51
64private:
66
68
70
77
79
81
82public:
92 EdgeOrderComparer(node origNode, node rootDualNode, const PredecessorMap& predecessors,
93 const GraphCopy& graphCopy, const DynamicDualGraph* dualGraph)
94 : m_origNode(origNode)
95 , m_rootDualNode(rootDualNode)
96 , m_predecessors(predecessors)
97 , m_graphCopy(graphCopy)
98 , m_dualGraph(dualGraph) { }
99
111 node findLCAInInsertionPathTree(node w1, node w2, edge& parentOfLCA) const {
112 const NodeArray<edge>& preds1 {*m_predecessors.at(w1)};
113 const NodeArray<edge>& preds2 {*m_predecessors.at(w2)};
114
115 // Go backwards from root until predecessor path diverges.
116 node lastDualNode1 {m_rootDualNode};
117 node lastDualNode2 {m_rootDualNode};
118 edge edgeToChild {nullptr};
119 node lca {nullptr};
120 while (lastDualNode1 == lastDualNode2) {
121 // Remember current lca.
122 parentOfLCA = edgeToChild;
123 lca = lastDualNode1;
124
125 // Go further down.
126 edgeToChild = preds1[lastDualNode1];
127 if (preds1[lastDualNode1] == nullptr || preds2[lastDualNode2] == nullptr) {
128 // If either node has no child in the insertion path tree,
129 // the lca cannot be lower.
130 break;
131 } else {
132 lastDualNode1 = preds1[lastDualNode1]->opposite(lastDualNode1);
133 lastDualNode2 = preds2[lastDualNode2]->opposite(lastDualNode2);
134 }
135 }
136
137 return lca;
138 }
139
146 int compare(const edge& e1, const edge& e2) const {
149 if (w1 == w2) {
150 return 0;
151 }
152
153 // Find lowest common ancestor in predecessor tree.
154 edge parentOfLCA {nullptr};
155 node lcaDualNode {findLCAInInsertionPathTree(w1, w2, parentOfLCA)};
156
157 // w1 and w2 must have a common ancestor.
158 OGDF_ASSERT(lcaDualNode != nullptr);
159
160 // Get the adjEntry of the primal edge of parentOfLCA which is incident
161 // to the face corresponding to lcaDualNode.
162 // This adjEntry marks the start of the cyclic order around lcaDualNode.
163 face lcaFace {m_dualGraph->primalFace(lcaDualNode)};
164 adjEntry parentAdj {nullptr};
165 if (parentOfLCA == nullptr) {
166 OGDF_ASSERT(lcaDualNode == m_rootDualNode);
167 // The lca is the root of the insertion path tree, hence it has no
168 // predecessor. Just use any adjEntry to start the cyclic order.
169 parentAdj = lcaFace->firstAdj();
170 } else {
171 // The lca is not the root of the insertion path tree.
172 // Determine the correct adjEntry of the primal of its parent-edge.
173 edge primalParentOfLCA {m_dualGraph->primalEdge(parentOfLCA)};
174 adjEntry sourceAdj {primalParentOfLCA->adjSource()};
175 adjEntry targetAdj {primalParentOfLCA->adjTarget()};
176
178 if (embedding.rightFace(sourceAdj) == lcaFace) {
179 parentAdj = sourceAdj;
180 } else {
181 OGDF_ASSERT(embedding.rightFace(targetAdj) == lcaFace);
182 parentAdj = targetAdj;
183 }
184 }
185
186 // Traverse adjEntries of face corrsponding to lcaDualNode clockwise,
187 // starting at parent edge of lcaDualNode in the insertion path tree.
188 auto cyclicNextAdj = [&parentAdj](adjEntry adj) {
189 adjEntry nextAdj = adj->faceCycleSucc();
190 return nextAdj == parentAdj ? nullptr : nextAdj;
191 };
192
193 edge pred1 {(*m_predecessors.at(w1))[lcaDualNode]};
194 edge pred2 {(*m_predecessors.at(w2))[lcaDualNode]};
195 for (adjEntry adj {parentAdj}; adj != nullptr; adj = cyclicNextAdj(adj)) {
196 edge primalEdge {adj->theEdge()};
197 node primalNode {adj->theNode()};
198 // First, if lcaFace has no pred in the insertion path of w1/w2,
199 // w1/w2 is adjacent to lcaFace.
200 // Check whether the node of the current adj is w1/w2.
201 if (pred1 == nullptr && primalNode == w1) {
202 return -1;
203 }
204 if (pred2 == nullptr && primalNode == w2) {
205 return 1;
206 }
207
208 // If w1/w2 is not adjacent to lcaFace, check whether the insertion
209 // path from lcaFace to the face adjacent to w1/w2 crosses the
210 // current edge.
211 edge dualEdge = m_dualGraph->dualEdge(primalEdge);
212 if (dualEdge == pred1) {
213 OGDF_ASSERT(dualEdge != pred2);
214 return -1;
215 }
216 if (dualEdge == pred2) {
217 OGDF_ASSERT(dualEdge != pred1);
218 return 1;
219 }
220 }
221
222 // Something went terribly wrong: The LCA of the insertion paths of w1
223 // and w2 is not actually part of the insertion paths of w1 and w2?
224 OGDF_ASSERT(false);
225 return 0;
226 }
227
229};
230
238private:
240
242
244
248
253
257
260 inline face oldPrimalFace(node dualNode) {
261 return (*m_newToOldFace)[m_dual->primalFace(dualNode)];
262 }
263
279 node getOptimalDualNode(node origNode, const EdgeArray<int>* pCostOrig,
280 PredecessorMap& predecessors);
281
292 void makePredsConsistent(node origNode, node optimalDualNode, PredecessorMap& predecessors);
293
304 adjEntry getCrossedAdjEntry(edge primalEdgeToSplit, node leftDualNode);
305
327 adjEntry getAdjEntry(node primalNode, node rightDualNode, node otherPrimalNode);
328
347 adjEntry getAdjEntry(node primalNode, node rightDualNode, edge primalEdge, bool first);
348
368 edge collectAdjEntries(node w, node insertedNode, node optimalDualNode,
369 const PredecessorMap& predecessors, List<adjEntry>& crossedEdges);
370
387 void transferCrossedEdges(const List<adjEntry>& crossedEdges,
388 SList<adjEntry>& finalCrossedEdges, bool startAtSource);
389
396 void initMemberData(GraphCopy& graphCopy, DynamicDualGraph& dualGraph);
397
406 void updateMemberData(edge origEdge, bool startAtSource);
407
408public:
410 StarInserter() : m_combEmbedding {nullptr}, m_dual {nullptr} { }
411
413
416 StarInserter(const StarInserter& inserter) { }
417
420
423
425
435 virtual void call(GraphCopy& graphCopy, DynamicDualGraph& dualGraph, node origNode,
436 const EdgeArray<int>* pCostOrig);
437};
438
439}
Declaration of CombinatorialEmbedding and face.
Includes declaration of dual graph class.
Includes declaration of graph class.
Declaration of graph copy classes.
Basic declarations, included by all source files.
Class for adjacency list elements.
Definition Graph_d.h:143
adjEntry faceCycleSucc() const
Returns the cyclic successor in face.
Definition Graph_d.h:213
Combinatorial embeddings of planar graphs with modification functionality.
Combinatorial embeddings of planar graphs.
face rightFace(adjEntry adj) const
Returns the face to the right of adj, i.e., the face containing adj.
A dual graph including its combinatorial embedding of an embedded graph.
Definition DualGraph.h:61
const face & primalFace(node v) const
Returns the face in the embedding of the primal graph corresponding to v.
Definition DualGraph.h:168
const edge & primalEdge(edge e) const
Returns the edge in the primal graph corresponding to e.
Definition DualGraph.h:161
Embedding & getPrimalEmbedding() const
Returns a reference to the combinatorial embedding of the primal graph.
Definition DualGraph.h:141
const edge & dualEdge(edge e) const
Returns the edge in the dual graph corresponding to e.
Definition DualGraph.h:182
Class for the representation of edges.
Definition Graph_d.h:364
node opposite(node v) const
Returns the adjacent node different from v.
Definition Graph_d.h:414
Orders edges such that they do not cross each other when embeddded as insertion paths.
node findLCAInInsertionPathTree(node w1, node w2, edge &parentOfLCA) const
Returns the lowest common ancestor of w1 and w2 in the insertion path tree given by m_predecessors.
const PredecessorMap & m_predecessors
Insertion path tree, given by several insertion paths.
node m_origNode
Common (original) node of compared edges.
int compare(const edge &e1, const edge &e2) const
Compares two edges as described for EdgeOrderComparer.
const DynamicDualGraph * m_dualGraph
Dual graph of m_graphCopy.
EdgeOrderComparer(node origNode, node rootDualNode, const PredecessorMap &predecessors, const GraphCopy &graphCopy, const DynamicDualGraph *dualGraph)
Creates a new EdgeOrderComparer.
node m_rootDualNode
Dual node, root of the insertion path tree.
const GraphCopy & m_graphCopy
Planarization.
RegisteredArray for labeling the faces of a CombinatorialEmbedding.
Faces in a combinatorial embedding.
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:390
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition GraphCopy.h:463
Doubly linked lists (maintaining the length of the list).
Definition List.h:1451
Class for the representation of nodes.
Definition Graph_d.h:241
Singly linked lists (maintaining the length of the list).
Definition SList.h:845
Inserts a star (a vertex and its incident edges) optimally into an embedding.
EdgeArray< edge > * m_edgeInChainToSplit
Maps each edge e originally contained in m_graphCopy to the edge in the same chain which should be sp...
~StarInserter()
Destructor.
adjEntry getAdjEntry(node primalNode, node rightDualNode, edge primalEdge, bool first)
Returns the adjEntry of primalNode whose right face is incident to primalEdge.
void transferCrossedEdges(const List< adjEntry > &crossedEdges, SList< adjEntry > &finalCrossedEdges, bool startAtSource)
Transfers the adjEntries from the List crossedEdges to the SList finalCrossedEdges such that they can...
CombinatorialEmbedding * m_combEmbedding
Embedding of m_graphCopy.
virtual void call(GraphCopy &graphCopy, DynamicDualGraph &dualGraph, node origNode, const EdgeArray< int > *pCostOrig)
Inserts the node origNode and its incident edges into graphCopy.
StarInserter()
Creates a StarInserter instance with default settings.
void updateMemberData(edge origEdge, bool startAtSource)
Update member variables, in particular m_newToOldFace and m_edgeInChainToSplit, after an edge was ins...
FaceArray< face > * m_newToOldFace
Maps new faces (created after the insertion of edge paths) to old (non-split) faces....
GraphCopy * m_graphCopy
Planarization.
void makePredsConsistent(node origNode, node optimalDualNode, PredecessorMap &predecessors)
Modify the insertion paths predecessors such that they do not cross each other anymore,...
adjEntry getCrossedAdjEntry(edge primalEdgeToSplit, node leftDualNode)
Returns the adjEntry of primalEdgeToSplit whose left face corresponds to leftDualNode.
node getOptimalDualNode(node origNode, const EdgeArray< int > *pCostOrig, PredecessorMap &predecessors)
Computes the optimal dual node to insert origNode and the insertion paths of its incident edges.
EdgeArray< edge > * m_originalEdge
Maps the parts of a chain in m_graphCopy to the respective copy edge contained in m_graphCopy before ...
edge collectAdjEntries(node w, node insertedNode, node optimalDualNode, const PredecessorMap &predecessors, List< adjEntry > &crossedEdges)
Collects adjEntries which can be passed to GraphCopy::insertEdgePathEmbedded to embed the edge insert...
DynamicDualGraph * m_dual
Dual graph of m_combEmbedding.
StarInserter & operator=(const StarInserter &inserter)
Assignment operator, copies option settings only.
adjEntry getAdjEntry(node primalNode, node rightDualNode, node otherPrimalNode)
Returns the adjEntry of primalNode whose right face corresponds to rightDualNode (if otherPrimaNode i...
void initMemberData(GraphCopy &graphCopy, DynamicDualGraph &dualGraph)
Initialize all member variables.
face oldPrimalFace(node dualNode)
Returns the primal face of dualNode which existed before any new edges were inserted.
StarInserter(const StarInserter &inserter)
Creates a StarInserter instance with the same settings as inserter.
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
Declarations for Comparer objects.
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF dynamic library (shared object / DLL),...
Definition config.h:117
#define OGDF_AUGMENT_COMPARER(type)
Add this macro to your class to turn it into a full comparer.
Definition comparer.h:183
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
std::unordered_map< node, std::unique_ptr< NodeArray< edge > > > PredecessorMap