Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
LayersBlockEmbedder.h
Go to the documentation of this file.
1
33#pragma once
34
39
40namespace ogdf {
41namespace embedder {
42
44template<class BaseEmbedder, class T>
45class LayersBlockEmbedder : public BaseEmbedder {
46protected:
50 adjEntry m_adjExternal = nullptr;
51 // 1. Compute embedding of block
54
55 // 2. Copy block embedding into graph embedding and call recursively
56 // embedBlock for all cut vertices in bT
58 face f = CE.leftFace(m_adjExternal);
59
60 if (*BaseEmbedder::pAdjExternal == nullptr) {
61 node on = BaseEmbedder::pBCTree->original(nSG_to_nG[m_adjExternal->theNode()]);
62
63 for (adjEntry ae : on->adjEntries) {
64 if (ae->theEdge()
65 == BaseEmbedder::pBCTree->original(eSG_to_eG[m_adjExternal->theEdge()])) {
66 *BaseEmbedder::pAdjExternal = ae->twin();
67 break;
68 }
69 }
70 }
71
72 bool DGcomputed = false;
73 int extFaceID = 0;
74
75 // when the following objects get allocated,
76 // the DGcomputed bool is set to true
77 Graph* p_DG = nullptr;
80 List<List<adjEntry>>* p_faces = nullptr;
81 NodeArray<int>* p_distances = nullptr;
82
83 for (node nSG : SG.nodes) {
85 node nG = BaseEmbedder::pBCTree->original(nH);
86 adjEntry ae = nSG->firstAdj();
87
89 if (BaseEmbedder::pBCTree->bcproper(nG) == cT) {
90 pAfter = &after;
91 } else {
93 }
94
95 if (BaseEmbedder::pBCTree->typeOfGNode(nG) == BCTree::GNodeType::CutVertex) {
96 node cT2 = BaseEmbedder::pBCTree->bcproper(nG);
97 bool doRecurse = true;
98
99 if (cT2 == cT) {
100 node parent_bT_of_cT2 = nullptr;
101
102 for (adjEntry adj : cT2->adjEntries) {
103 edge e_cT2_to_bT2 = adj->theEdge();
104
105 if (e_cT2_to_bT2->source() == cT2) {
107 break;
108 }
109 }
110
111 OGDF_ASSERT(parent_bT_of_cT2 != nullptr);
112
113 if (BaseEmbedder::treeNodeTreated[parent_bT_of_cT2]) {
114 doRecurse = false;
115 }
116 }
117
118
119 // find adjacency entry of nSG which lies on external face f:
120 bool aeExtExists = false;
121 for (adjEntry aeFace : f->entries) {
122 if (aeFace->theNode() == nSG) {
123 ae = aeFace->succ() == nullptr ? nSG->firstAdj() : aeFace->succ();
124 aeExtExists = true;
125 break;
126 }
127 }
128
129 if (doRecurse) {
130 if (!aeExtExists) {
131 if (!DGcomputed) {
132 p_DG = new Graph();
137 DGcomputed = true;
138
139 //compute dual graph of skeleton graph:
141 for (node nBG : SG.nodes) {
142 for (adjEntry ae_nBG : nBG->adjEntries) {
143 (*p_adjacencyList)[nBG].pushBack(ae_nBG);
144 }
145 }
146
148 for (node nBG : SG.nodes) {
149 for (adjEntry adj : nBG->adjEntries) {
150 if (!adjEntryTreated[nBG].search(adj).valid()) {
152 adjEntry adj2 = adj;
153
154 do {
155 newFace.pushBack(adj2);
156 adjEntryTreated[adj2->theNode()].pushBack(adj2);
158 (*p_adjacencyList)[adj2->twinNode()];
159 adj2 = *ladj.cyclicPred(ladj.search(adj2->twin()));
160 } while (adj2 != adj);
161
162 p_faces->pushBack(newFace);
163 }
164 }
165 }
166
167 for (int i = 0; i < p_faces->size(); i++) {
168 p_fPG_to_nDG->push(p_DG->newNode());
169 }
170
172 int i = 0;
173
174 for (const List<adjEntry>& Li : *p_faces) {
175 int f1_id = i;
176
177 for (adjEntry adj2 : Li) {
178 int f2_id = 0;
179 int j = 0;
180
181 for (List<adjEntry>& Lj : *p_faces) {
182 bool do_break = false;
183
184 for (adjEntry adj4 : Lj) {
185 if (adj4 == adj2->twin()) {
186 f2_id = j;
187 do_break = true;
188 break;
189 }
190 }
191
192 if (do_break) {
193 break;
194 }
195
196 j++;
197 }
198
199 if (f1_id != f2_id
201 .search((*p_fPG_to_nDG)[f2_id])
202 .valid()
203 && !adjFaces[(*p_fPG_to_nDG)[f2_id]]
204 .search((*p_fPG_to_nDG)[f1_id])
205 .valid()) {
206 adjFaces[(*p_fPG_to_nDG)[f1_id]].pushBack(
207 (*p_fPG_to_nDG)[f2_id]);
208 p_DG->newEdge((*p_fPG_to_nDG)[f1_id], (*p_fPG_to_nDG)[f2_id]);
209 }
210
211 if (adj2 == f->firstAdj()) {
213 }
214 }
215
216 i++;
217 }
218
219 // compute shortest path from every face to the external face:
221 p_DG->allEdges(DG_edges);
222
223 for (edge e : DG_edges) {
224 node s = e->source();
225 node t = e->target();
226 p_DG->newEdge(t, s);
227 }
228
230 node efDG = (*p_fPG_to_nDG)[extFaceID];
231 EdgeArray<int> el(*p_DG, 1);
232 p_distances->init(*p_DG);
234 shortestPath.call(*p_DG, efDG, el, *p_distances, pi);
235 }
236
237 // choose face with minimal shortest path:
239 int optFaceDist = -1;
240
241 for (int fID = 0; fID < p_faces->size(); ++fID) {
244 bool contains_nSG = false;
245
246 for (adjEntry adj : theFace) {
247 if (adj->theNode() == nSG) {
248 contains_nSG = true;
249 ae_nSG = adj;
250 break;
251 }
252 }
253
254 if (contains_nSG) {
255 int thisDist = (*p_distances)[(*p_fPG_to_nDG)[fID]];
256
257 if (optFaceDist == -1 || optFaceDist > thisDist) {
260 ae = ae_nSG->succ() == nullptr ? nSG->firstAdj() : ae_nSG->succ();
261 }
262 }
263 }
264 }
265
266 for (adjEntry adj : cT2->adjEntries) {
267 node bT2 = adj->theEdge()->opposite(cT2);
268
269 if (!BaseEmbedder::treeNodeTreated[bT2]) {
270 this->embedBlock(bT2, cT2, *pAfter);
271 }
272 }
273 }
274 }
275
276 // embed all edges of block bT:
277 bool after_ae = true;
278 for (adjEntry aeNode = ae; after_ae || aeNode != ae;
279 aeNode = aeNode->succ() == nullptr ? nSG->firstAdj() : aeNode->succ()) {
280 edge eG = BaseEmbedder::pBCTree->original(eSG_to_eG[aeNode->theEdge()]);
281 if (nG == eG->source()) {
282 if (pAfter->valid()) {
283 *pAfter = BaseEmbedder::newOrder[nG].insertAfter(eG->adjSource(), *pAfter);
284 } else {
285 *pAfter = BaseEmbedder::newOrder[nG].pushBack(eG->adjSource());
286 }
287 } else {
288 if (pAfter->valid()) {
289 *pAfter = BaseEmbedder::newOrder[nG].insertAfter(eG->adjTarget(), *pAfter);
290 } else {
291 *pAfter = BaseEmbedder::newOrder[nG].pushBack(eG->adjTarget());
292 }
293 }
294
295 after_ae &= aeNode->succ() != nullptr;
296 }
297
298 if (*pAfter != after) {
299 delete pAfter;
300 }
301 }
302
303 if (DGcomputed) {
304 delete p_DG;
305 delete p_fPG_to_nDG;
306 delete p_adjacencyList;
307 delete p_faces;
308 delete p_distances;
309 }
310 }
311};
312
313}
314}
Declaration of class BCTree.
Declaration of CombinatorialEmbedding and face.
Computes an embedding of a biconnected graph with maximum external face.
Declaration of class ShortestPathWithBFM which computes shortest paths via Bellman-Ford-Moore.
Class for adjacency list elements.
Definition Graph_d.h:79
adjEntry succ() const
Returns the successor in the adjacency list.
Definition Graph_d.h:155
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:97
node theNode() const
Returns the node whose adjacency list contains this element.
Definition Graph_d.h:103
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:56
@ CutVertex
a cut-vertex
Combinatorial embeddings of planar graphs with modification functionality.
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
edge succ() const
Returns the successor in the list of all edges.
Definition Graph_d.h:370
node target() const
Returns the target node of the edge.
Definition Graph_d.h:338
static void embed(Graph &G, adjEntry &adjExternal, const NodeArray< T > &nodeLength, const EdgeArray< T > &edgeLength, const node &n=nullptr)
Embeds G by computing and extending a maximum face in G containing n.
Faces in a combinatorial embedding.
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
Encapsulates a pointer to a list element.
Definition List.h:103
const_iterator cyclicPred(const_iterator it) const
Returns a const iterator to the cyclic predecessor of it.
Definition List.h:485
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
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
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition Graph_d.h:208
Computes single-source shortest-paths with Bellman-Ford-Moore's algorithm.
Common functionality for layer-based embedding algorithms.
void internalEmbedBlock(Graph &SG, NodeArray< T > &nodeLengthSG, EdgeArray< T > &edgeLengthSG, NodeArray< node > &nSG_to_nG, EdgeArray< edge > &eSG_to_eG, node nodeInBlockSG, node cT, ListIterator< adjEntry > &after)
#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.