Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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.