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
37#include <ogdf/basic/Graph.h>
39#include <ogdf/basic/List.h>
40#include <ogdf/basic/basic.h>
44
45namespace ogdf {
46namespace embedder {
47
49template<class BaseEmbedder, class T>
50class LayersBlockEmbedder : public BaseEmbedder {
51protected:
52 void internalEmbedBlock(Graph& SG, NodeArray<T>& nodeLengthSG, EdgeArray<T>& edgeLengthSG,
53 NodeArray<node>& nSG_to_nG, EdgeArray<edge>& eSG_to_eG, node nodeInBlockSG, node cT,
55 adjEntry m_adjExternal = nullptr;
56 // 1. Compute embedding of block
57 EmbedderMaxFaceBiconnectedGraphsLayers<T>::embed(SG, m_adjExternal, nodeLengthSG,
58 edgeLengthSG, nodeInBlockSG);
59
60 // 2. Copy block embedding into graph embedding and call recursively
61 // embedBlock for all cut vertices in bT
63 face f = CE.leftFace(m_adjExternal);
64
65 if (*BaseEmbedder::pAdjExternal == nullptr) {
66 node on = BaseEmbedder::pBCTree->original(nSG_to_nG[m_adjExternal->theNode()]);
67
68 for (adjEntry ae : on->adjEntries) {
69 if (ae->theEdge()
70 == BaseEmbedder::pBCTree->original(eSG_to_eG[m_adjExternal->theEdge()])) {
71 *BaseEmbedder::pAdjExternal = ae->twin();
72 break;
73 }
74 }
75 }
76
77 bool DGcomputed = false;
78 int extFaceID = 0;
79
80 // when the following objects get allocated,
81 // the DGcomputed bool is set to true
82 Graph* p_DG = nullptr;
83 ArrayBuffer<node>* p_fPG_to_nDG = nullptr;
84 NodeArray<List<adjEntry>>* p_adjacencyList = nullptr;
85 List<List<adjEntry>>* p_faces = nullptr;
86 NodeArray<int>* p_distances = nullptr;
87
88 for (node nSG : SG.nodes) {
89 node nH = nSG_to_nG[nSG];
90 node nG = BaseEmbedder::pBCTree->original(nH);
91 adjEntry ae = nSG->firstAdj();
92
94 if (BaseEmbedder::pBCTree->bcproper(nG) == cT) {
95 pAfter = &after;
96 } else {
97 pAfter = new ListIterator<adjEntry>();
98 }
99
100 if (BaseEmbedder::pBCTree->typeOfGNode(nG) == BCTree::GNodeType::CutVertex) {
101 node cT2 = BaseEmbedder::pBCTree->bcproper(nG);
102 bool doRecurse = true;
103
104 if (cT2 == cT) {
105 node parent_bT_of_cT2 = nullptr;
106
107 for (adjEntry adj : cT2->adjEntries) {
108 edge e_cT2_to_bT2 = adj->theEdge();
109
110 if (e_cT2_to_bT2->source() == cT2) {
111 parent_bT_of_cT2 = e_cT2_to_bT2->target();
112 break;
113 }
114 }
115
116 OGDF_ASSERT(parent_bT_of_cT2 != nullptr);
117
118 if (BaseEmbedder::treeNodeTreated[parent_bT_of_cT2]) {
119 doRecurse = false;
120 }
121 }
122
123
124 // find adjacency entry of nSG which lies on external face f:
125 bool aeExtExists = false;
126 for (adjEntry aeFace : f->entries) {
127 if (aeFace->theNode() == nSG) {
128 ae = aeFace->succ() == nullptr ? nSG->firstAdj() : aeFace->succ();
129 aeExtExists = true;
130 break;
131 }
132 }
133
134 if (doRecurse) {
135 if (!aeExtExists) {
136 if (!DGcomputed) {
137 p_DG = new Graph();
138 p_fPG_to_nDG = new ArrayBuffer<node>();
139 p_adjacencyList = new NodeArray<List<adjEntry>>();
140 p_faces = new List<List<adjEntry>>;
141 p_distances = new NodeArray<int>;
142 DGcomputed = true;
143
144 //compute dual graph of skeleton graph:
145 p_adjacencyList->init(SG);
146 for (node nBG : SG.nodes) {
147 for (adjEntry ae_nBG : nBG->adjEntries) {
148 (*p_adjacencyList)[nBG].pushBack(ae_nBG);
149 }
150 }
151
152 NodeArray<List<adjEntry>> adjEntryTreated(SG);
153 for (node nBG : SG.nodes) {
154 for (adjEntry adj : nBG->adjEntries) {
155 if (!adjEntryTreated[nBG].search(adj).valid()) {
156 List<adjEntry> newFace;
157 adjEntry adj2 = adj;
158
159 do {
160 newFace.pushBack(adj2);
161 adjEntryTreated[adj2->theNode()].pushBack(adj2);
162 List<adjEntry>& ladj =
163 (*p_adjacencyList)[adj2->twinNode()];
164 adj2 = *ladj.cyclicPred(ladj.search(adj2->twin()));
165 } while (adj2 != adj);
166
167 p_faces->pushBack(newFace);
168 }
169 }
170 }
171
172 for (int i = 0; i < p_faces->size(); i++) {
173 p_fPG_to_nDG->push(p_DG->newNode());
174 }
175
176 NodeArray<List<node>> adjFaces(*p_DG);
177 int i = 0;
178
179 for (const List<adjEntry>& Li : *p_faces) {
180 int f1_id = i;
181
182 for (adjEntry adj2 : Li) {
183 int f2_id = 0;
184 int j = 0;
185
186 for (List<adjEntry>& Lj : *p_faces) {
187 bool do_break = false;
188
189 for (adjEntry adj4 : Lj) {
190 if (adj4 == adj2->twin()) {
191 f2_id = j;
192 do_break = true;
193 break;
194 }
195 }
196
197 if (do_break) {
198 break;
199 }
200
201 j++;
202 }
203
204 if (f1_id != f2_id
205 && !adjFaces[(*p_fPG_to_nDG)[f1_id]]
206 .search((*p_fPG_to_nDG)[f2_id])
207 .valid()
208 && !adjFaces[(*p_fPG_to_nDG)[f2_id]]
209 .search((*p_fPG_to_nDG)[f1_id])
210 .valid()) {
211 adjFaces[(*p_fPG_to_nDG)[f1_id]].pushBack(
212 (*p_fPG_to_nDG)[f2_id]);
213 p_DG->newEdge((*p_fPG_to_nDG)[f1_id], (*p_fPG_to_nDG)[f2_id]);
214 }
215
216 if (adj2 == f->firstAdj()) {
217 extFaceID = f1_id;
218 }
219 }
220
221 i++;
222 }
223
224 // compute shortest path from every face to the external face:
225 List<edge> DG_edges;
226 p_DG->allEdges(DG_edges);
227
228 for (edge e : DG_edges) {
229 node s = e->source();
230 node t = e->target();
231 p_DG->newEdge(t, s);
232 }
233
234 ShortestPathWithBFM shortestPath;
235 node efDG = (*p_fPG_to_nDG)[extFaceID];
236 EdgeArray<int> el(*p_DG, 1);
237 p_distances->init(*p_DG);
238 NodeArray<edge> pi(*p_DG);
239 shortestPath.call(*p_DG, efDG, el, *p_distances, pi);
240 }
241
242 // choose face with minimal shortest path:
243 List<adjEntry> optFace;
244 int optFaceDist = -1;
245
246 for (int fID = 0; fID < p_faces->size(); ++fID) {
247 List<adjEntry> theFace = *(p_faces->get(fID));
248 adjEntry ae_nSG;
249 bool contains_nSG = false;
250
251 for (adjEntry adj : theFace) {
252 if (adj->theNode() == nSG) {
253 contains_nSG = true;
254 ae_nSG = adj;
255 break;
256 }
257 }
258
259 if (contains_nSG) {
260 int thisDist = (*p_distances)[(*p_fPG_to_nDG)[fID]];
261
262 if (optFaceDist == -1 || optFaceDist > thisDist) {
263 optFace = theFace;
264 optFaceDist = thisDist;
265 ae = ae_nSG->succ() == nullptr ? nSG->firstAdj() : ae_nSG->succ();
266 }
267 }
268 }
269 }
270
271 for (adjEntry adj : cT2->adjEntries) {
272 node bT2 = adj->theEdge()->opposite(cT2);
273
274 if (!BaseEmbedder::treeNodeTreated[bT2]) {
275 this->embedBlock(bT2, cT2, *pAfter);
276 }
277 }
278 }
279 }
280
281 // embed all edges of block bT:
282 bool after_ae = true;
283 for (adjEntry aeNode = ae; after_ae || aeNode != ae;
284 aeNode = aeNode->succ() == nullptr ? nSG->firstAdj() : aeNode->succ()) {
285 edge eG = BaseEmbedder::pBCTree->original(eSG_to_eG[aeNode->theEdge()]);
286 if (nG == eG->source()) {
287 if (pAfter->valid()) {
288 *pAfter = BaseEmbedder::newOrder[nG].insertAfter(eG->adjSource(), *pAfter);
289 } else {
290 *pAfter = BaseEmbedder::newOrder[nG].pushBack(eG->adjSource());
291 }
292 } else {
293 if (pAfter->valid()) {
294 *pAfter = BaseEmbedder::newOrder[nG].insertAfter(eG->adjTarget(), *pAfter);
295 } else {
296 *pAfter = BaseEmbedder::newOrder[nG].pushBack(eG->adjTarget());
297 }
298 }
299
300 after_ae &= aeNode->succ() != nullptr;
301 }
302
303 if (*pAfter != after) {
304 delete pAfter;
305 }
306 }
307
308 if (DGcomputed) {
309 delete p_DG;
310 delete p_fPG_to_nDG;
311 delete p_adjacencyList;
312 delete p_faces;
313 delete p_distances;
314 }
315 }
316};
317
318}
319}
Declaration and implementation of ArrayBuffer class.
Declaration of class BCTree.
Declaration of CombinatorialEmbedding and face.
Computes an embedding of a biconnected graph with maximum external face.
Includes declaration of graph class.
Decralation of GraphElement and GraphList classes.
Declaration of doubly linked lists and iterators.
Declaration of class ShortestPathWithBFM which computes shortest paths via Bellman-Ford-Moore.
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 succ() const
Returns the successor in the adjacency list.
Definition Graph_d.h:219
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:161
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition Graph_d.h:176
node theNode() const
Returns the node whose adjacency list contains this element.
Definition Graph_d.h:167
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:64
void push(E e)
Puts a new element in the buffer.
@ CutVertex
a cut-vertex
Combinatorial embeddings of planar graphs with modification functionality.
face leftFace(adjEntry adj) const
Returns the face to the left of adj, i.e., the face containing the twin of adj.
Class for the representation of edges.
Definition Graph_d.h:364
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition Graph_d.h:408
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition Graph_d.h:411
node target() const
Returns the target node of the edge.
Definition Graph_d.h:402
node source() const
Returns the source node of the edge.
Definition Graph_d.h:399
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.
internal::FaceAdjContainer entries
Container maintaining the adjacency entries in the face.
adjEntry firstAdj() const
Returns the first adjacency element in the face.
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:866
void allEdges(CONTAINER &edgeContainer) const
Returns a container with all edges of the graph.
Definition Graph_d.h:1043
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition Graph_d.h:929
node newNode(int index=-1)
Creates a new node and returns it.
Definition Graph_d.h:1061
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
Definition Graph_d.h:1080
Doubly linked lists (maintaining the length of the list).
Definition List.h:1451
int size() const
Returns the number of elements in the list.
Definition List.h:1488
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1547
Encapsulates a pointer to a list element.
Definition List.h:113
bool valid() const
Returns true iff the iterator points to an element.
Definition List.h:153
ListIteratorBase< E, isConst, isReverse > succ() const
Returns successor iterator.
Definition List.h:174
const_iterator cyclicPred(const_iterator it) const
Returns a const iterator to the cyclic predecessor of it.
Definition List.h:501
const_iterator get(int pos) const
Returns a const iterator pointing to the element at position pos.
Definition List.h:341
ListConstIterator< E > search(const E &e) const
Scans the list for the specified element and returns an iterator to the first occurrence in the list,...
Definition List.h:1280
Class for the representation of nodes.
Definition Graph_d.h:241
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition Graph_d.h:272
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Computes single-source shortest-paths with Bellman-Ford-Moore's algorithm.
virtual bool call(const Graph &G, const node s, const EdgeArray< int > &length, NodeArray< int > &d, NodeArray< edge > &pi) override
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)
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
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.