Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

LayersBlockEmbedder.h
Go to the documentation of this file.
1 
33 #pragma once
34 
39 
40 namespace ogdf {
41 namespace embedder {
42 
44 template<class BaseEmbedder, class T>
45 class LayersBlockEmbedder : public BaseEmbedder {
46 protected:
47  void internalEmbedBlock(Graph& SG, NodeArray<T>& nodeLengthSG, EdgeArray<T>& edgeLengthSG,
48  NodeArray<node>& nSG_to_nG, EdgeArray<edge>& eSG_to_eG, node nodeInBlockSG, node cT,
49  ListIterator<adjEntry>& after) {
50  adjEntry m_adjExternal = nullptr;
51  // 1. Compute embedding of block
52  EmbedderMaxFaceBiconnectedGraphsLayers<T>::embed(SG, m_adjExternal, nodeLengthSG,
53  edgeLengthSG, nodeInBlockSG);
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;
78  ArrayBuffer<node>* p_fPG_to_nDG = nullptr;
79  NodeArray<List<adjEntry>>* p_adjacencyList = nullptr;
80  List<List<adjEntry>>* p_faces = nullptr;
81  NodeArray<int>* p_distances = nullptr;
82 
83  for (node nSG : SG.nodes) {
84  node nH = nSG_to_nG[nSG];
85  node nG = BaseEmbedder::pBCTree->original(nH);
86  adjEntry ae = nSG->firstAdj();
87 
88  ListIterator<adjEntry>* pAfter;
89  if (BaseEmbedder::pBCTree->bcproper(nG) == cT) {
90  pAfter = &after;
91  } else {
92  pAfter = new ListIterator<adjEntry>();
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) {
106  parent_bT_of_cT2 = e_cT2_to_bT2->target();
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();
133  p_fPG_to_nDG = new ArrayBuffer<node>();
134  p_adjacencyList = new NodeArray<List<adjEntry>>();
135  p_faces = new List<List<adjEntry>>;
136  p_distances = new NodeArray<int>;
137  DGcomputed = true;
138 
139  //compute dual graph of skeleton graph:
140  p_adjacencyList->init(SG);
141  for (node nBG : SG.nodes) {
142  for (adjEntry ae_nBG : nBG->adjEntries) {
143  (*p_adjacencyList)[nBG].pushBack(ae_nBG);
144  }
145  }
146 
147  NodeArray<List<adjEntry>> adjEntryTreated(SG);
148  for (node nBG : SG.nodes) {
149  for (adjEntry adj : nBG->adjEntries) {
150  if (!adjEntryTreated[nBG].search(adj).valid()) {
151  List<adjEntry> newFace;
152  adjEntry adj2 = adj;
153 
154  do {
155  newFace.pushBack(adj2);
156  adjEntryTreated[adj2->theNode()].pushBack(adj2);
157  List<adjEntry>& ladj =
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 
171  NodeArray<List<node>> adjFaces(*p_DG);
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
200  && !adjFaces[(*p_fPG_to_nDG)[f1_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()) {
212  extFaceID = f1_id;
213  }
214  }
215 
216  i++;
217  }
218 
219  // compute shortest path from every face to the external face:
220  List<edge> DG_edges;
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 
229  ShortestPathWithBFM shortestPath;
230  node efDG = (*p_fPG_to_nDG)[extFaceID];
231  EdgeArray<int> el(*p_DG, 1);
232  p_distances->init(*p_DG);
233  NodeArray<edge> pi(*p_DG);
234  shortestPath.call(*p_DG, efDG, el, *p_distances, pi);
235  }
236 
237  // choose face with minimal shortest path:
238  List<adjEntry> optFace;
239  int optFaceDist = -1;
240 
241  for (int fID = 0; fID < p_faces->size(); ++fID) {
242  List<adjEntry> theFace = *(p_faces->get(fID));
243  adjEntry ae_nSG;
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) {
258  optFace = theFace;
259  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 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:46
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::AdjElement::theNode
node theNode() const
Returns the node whose adjacency list contains this element.
Definition: Graph_d.h:159
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:276
ogdf::FaceElement::entries
internal::FaceAdjContainer entries
Container maintaining the adjacency entries in the face.
Definition: CombinatorialEmbedding.h:133
ogdf::ListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: List.h:143
ogdf::Graph::allEdges
void allEdges(CONTAINER &edgeContainer) const
Returns a container with all edges of the graph.
Definition: Graph_d.h:1038
ogdf::AdjElement::twin
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
Definition: Graph_d.h:165
ogdf::BCTree::GNodeType::CutVertex
@ CutVertex
a cut-vertex
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:135
ogdf::FaceElement::firstAdj
adjEntry firstAdj() const
Returns the first adjacency element in the face.
Definition: CombinatorialEmbedding.h:139
ogdf::ListIteratorBase::succ
ListIteratorBase< E, isConst, isReverse > succ() const
Returns successor iterator.
Definition: List.h:164
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:153
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:924
ogdf::AdjElement::succ
adjEntry succ() const
Returns the successor in the adjacency list.
Definition: Graph_d.h:211
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:264
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:282
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:209
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:391
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: List.h:42
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
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:47
ogdf::ShortestPathWithBFM
Computes single-source shortest-paths with Bellman-Ford-Moore's algorithm.
Definition: ShortestPathWithBFM.h:43
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:400
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
ogdf::Math::pi
constexpr double pi
The constant .
Definition: Math.h:59
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:45
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:168
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:403
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:1056
ogdf::CombinatorialEmbedding
Combinatorial embeddings of planar graphs with modification functionality.
Definition: CombinatorialEmbedding.h:397
ogdf::NodeElement::firstAdj
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Definition: Graph_d.h:279
ogdf::EdgeElement::opposite
node opposite(node v) const
Returns the adjacent node different from v.
Definition: Graph_d.h:406
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
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:849
ogdf::List::size
int size() const
Returns the number of elements in the list.
Definition: List.h:1478
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:46
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:394
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:1075
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::FaceElement
Faces in a combinatorial embedding.
Definition: CombinatorialEmbedding.h:109