Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

LayersBlockEmbedder.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <ogdf/basic/ArrayBuffer.h>
37 #include <ogdf/basic/Graph.h>
38 #include <ogdf/basic/GraphList.h>
39 #include <ogdf/basic/List.h>
40 #include <ogdf/basic/basic.h>
44 
45 namespace ogdf {
46 namespace embedder {
47 
49 template<class BaseEmbedder, class T>
50 class LayersBlockEmbedder : public BaseEmbedder {
51 protected:
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,
54  ListIterator<adjEntry>& after) {
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 
93  ListIterator<adjEntry>* pAfter;
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 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:53
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
Graph.h
Includes declaration of graph class.
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::AdjElement::theNode
node theNode() const
Returns the node whose adjacency list contains this element.
Definition: Graph_d.h:166
ogdf::ConstCombinatorialEmbedding::leftFace
face leftFace(adjEntry adj) const
Returns the face to the left of adj, i.e., the face containing the twin of adj.
Definition: CombinatorialEmbedding.h:285
ogdf::FaceElement::entries
internal::FaceAdjContainer entries
Container maintaining the adjacency entries in the face.
Definition: CombinatorialEmbedding.h:142
ogdf::ListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: List.h:153
ogdf::Graph::allEdges
void allEdges(CONTAINER &edgeContainer) const
Returns a container with all edges of the graph.
Definition: Graph_d.h:1046
ogdf::AdjElement::twin
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
Definition: Graph_d.h:172
ogdf::BCTree::GNodeType::CutVertex
@ CutVertex
a cut-vertex
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::FaceElement::firstAdj
adjEntry firstAdj() const
Returns the first adjacency element in the face.
Definition: CombinatorialEmbedding.h:148
ogdf::ListIteratorBase::succ
ListIteratorBase< E, isConst, isReverse > succ() const
Returns successor iterator.
Definition: List.h:174
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:160
BCTree.h
Declaration of class BCTree.
ogdf::Direction::after
@ after
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:932
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::AdjElement::succ
adjEntry succ() const
Returns the successor in the adjacency list.
Definition: Graph_d.h:218
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:271
ogdf::EmbedderMaxFaceBiconnectedGraphsLayers::embed
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.
Definition: EmbedderMaxFaceBiconnectedGraphsLayers.h:292
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:217
ShortestPathWithBFM.h
Declaration of class ShortestPathWithBFM which computes shortest paths via Bellman-Ford-Moore.
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: DfsMakeBiconnected.h:40
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::embedder::LayersBlockEmbedder::internalEmbedBlock
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)
Definition: LayersBlockEmbedder.h:52
ogdf::ShortestPathWithBFM
Computes single-source shortest-paths with Bellman-Ford-Moore's algorithm.
Definition: ShortestPathWithBFM.h:45
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:407
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
ogdf::Math::pi
constexpr double pi
The constant .
Definition: Math.h:63
EmbedderMaxFaceBiconnectedGraphsLayers.h
Computes an embedding of a biconnected graph with maximum external face.
ogdf::embedder::LayersBlockEmbedder
Common functionality for layer-based embedding algorithms.
Definition: LayersBlockEmbedder.h:50
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:175
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:410
basic.h
Basic declarations, included by all source files.
CombinatorialEmbedding.h
Declaration of CombinatorialEmbedding and face.
ogdf::Graph::newNode
node newNode(int index=-1)
Creates a new node and returns it.
Definition: Graph_d.h:1064
ogdf::CombinatorialEmbedding
Combinatorial embeddings of planar graphs with modification functionality.
Definition: CombinatorialEmbedding.h:406
ogdf::NodeElement::firstAdj
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Definition: Graph_d.h:286
ogdf::EdgeElement::opposite
node opposite(node v) const
Returns the adjacent node different from v.
Definition: Graph_d.h:413
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
List.h
Declaration of doubly linked lists and iterators.
ogdf::RegisteredArray< GraphRegistry< Key >, Value, WithDefault, Graph >::init
void init(const Graph *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Definition: RegisteredArray.h:858
ogdf::List::size
int size() const
Returns the number of elements in the list.
Definition: List.h:1488
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:51
ogdf::ShortestPathWithBFM::call
virtual bool call(const Graph &G, const node s, const EdgeArray< int > &length, NodeArray< int > &d, NodeArray< edge > &pi) override
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::Graph::newEdge
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
Definition: Graph_d.h:1083
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1547
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716
ogdf::FaceElement
Faces in a combinatorial embedding.
Definition: CombinatorialEmbedding.h:118