PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/OGDF/ogdf/internal/planarity/EmbedderMaxFaceBiconnectedGraphs.h

https://gitlab.com/mba811/TortoiseGit
C Header | 1906 lines | 1370 code | 163 blank | 373 comment | 349 complexity | b7dffd66d22bc589cc5a21a78bef6395 MD5 | raw file
Possible License(s): LGPL-3.0, MPL-2.0-no-copyleft-exception, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * $Revision: 2599 $
  3. *
  4. * last checkin:
  5. * $Author: chimani $
  6. * $Date: 2012-07-15 22:39:24 +0200 (So, 15. Jul 2012) $
  7. ***************************************************************/
  8. /** \file
  9. * \brief Computes an embedding of a biconnected graph with maximum
  10. * external face.
  11. *
  12. * \author Thorsten Kerkhof
  13. *
  14. * \par License:
  15. * This file is part of the Open Graph Drawing Framework (OGDF).
  16. *
  17. * \par
  18. * Copyright (C)<br>
  19. * See README.txt in the root directory of the OGDF installation for details.
  20. *
  21. * \par
  22. * This program is free software; you can redistribute it and/or
  23. * modify it under the terms of the GNU General Public License
  24. * Version 2 or 3 as published by the Free Software Foundation;
  25. * see the file LICENSE.txt included in the packaging of this file
  26. * for details.
  27. *
  28. * \par
  29. * This program is distributed in the hope that it will be useful,
  30. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  32. * GNU General Public License for more details.
  33. *
  34. * \par
  35. * You should have received a copy of the GNU General Public
  36. * License along with this program; if not, write to the Free
  37. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  38. * Boston, MA 02110-1301, USA.
  39. *
  40. * \see http://www.gnu.org/copyleft/gpl.html
  41. ***************************************************************/
  42. #ifdef _MSC_VER
  43. #pragma once
  44. #endif
  45. #ifndef OGDF_EMBEDDER_MAX_FACE_BICONNECTED_GRAPHS_H
  46. #define OGDF_EMBEDDER_MAX_FACE_BICONNECTED_GRAPHS_H
  47. #include <ogdf/decomposition/StaticSPQRTree.h>
  48. #include <ogdf/basic/CombinatorialEmbedding.h>
  49. #include <ogdf/basic/extended_graph_alg.h>
  50. namespace ogdf {
  51. //! Computes an embedding of a biconnected graph with maximum external face.
  52. /**
  53. * See the paper "Graph Embedding with Minimum Depth and
  54. * Maximum External Face" by C. Gutwenger and P. Mutzel (2004) for
  55. * details.
  56. */
  57. template<class T>
  58. class EmbedderMaxFaceBiconnectedGraphs
  59. {
  60. public:
  61. //! Creates an embedder.
  62. EmbedderMaxFaceBiconnectedGraphs() { }
  63. /**
  64. * \brief Embeds \a G by computing and extending a maximum face in \a G
  65. * containing \a n.
  66. * \param G is the original graph.
  67. * \param adjExternal is assigned an adjacency entry of the external face.
  68. * \param nodeLength stores for each vertex in \a G its length.
  69. * \param edgeLength stores for each edge in \a G its length.
  70. * \param n is a vertex of the original graph. If n is given, a maximum face
  71. * containing n is computed, otherwise any maximum face.
  72. */
  73. static void embed(
  74. Graph& G,
  75. adjEntry& adjExternal,
  76. const NodeArray<T>& nodeLength,
  77. const EdgeArray<T>& edgeLength,
  78. const node& n = 0);
  79. /**
  80. * \brief Computes the component lengths of all virtual edges in spqrTree.
  81. * \param G is the original graph.
  82. * \param nodeLength is saving for each vertex in \a G its length.
  83. * \param edgeLength is saving for each edge in \a G its length.
  84. * \param spqrTree is the SPQR-tree of \a G.
  85. * \param edgeLengthSkel is saving for each skeleton graph of the SPQR-tree
  86. * all edge lengths.
  87. */
  88. static void compute(
  89. const Graph& G,
  90. const NodeArray<T>& nodeLength,
  91. const EdgeArray<T>& edgeLength,
  92. StaticSPQRTree& spqrTree,
  93. NodeArray< EdgeArray<T> >& edgeLengthSkel);
  94. /**
  95. * \brief Returns the size of a maximum external face in \a G containing the node \a n.
  96. * \param G is the original graph.
  97. * \param n is a node of the original graph.
  98. * \param nodeLength is saving for each vertex in \a G its length.
  99. * \param edgeLength is saving for each edge in \a G its length.
  100. * \return The size of a maximum external face in \a G containing the node \a n.
  101. */
  102. static T computeSize(
  103. const Graph& G,
  104. const node& n,
  105. const NodeArray<T>& nodeLength,
  106. const EdgeArray<T>& edgeLength);
  107. /**
  108. * \brief Returns the size of a maximum external face in \a G containing
  109. * the node \a n.
  110. *
  111. * \param G is the original graph.
  112. * \param n is a node of the original graph.
  113. * \param nodeLength is saving for each vertex in \a G its length.
  114. * \param edgeLength is saving for each edge in \a G its length.
  115. * \param spqrTree is the SPQR-tree of G.
  116. * \return The size of a maximum external face in \a G containing the node \a n.
  117. */
  118. static T computeSize(
  119. const Graph& G,
  120. const node& n,
  121. const NodeArray<T>& nodeLength,
  122. const EdgeArray<T>& edgeLength,
  123. StaticSPQRTree& spqrTree);
  124. /**
  125. * \brief Returns the size of a maximum external face in \a G containing
  126. * the node \a n.
  127. *
  128. * \param G is the original graph.
  129. * \param n is a node of the original graph.
  130. * \param nodeLength is saving for each vertex in \a G its length.
  131. * \param edgeLength is saving for each edge in \a G its length.
  132. * \param spqrTree is the SPQR-tree of G.
  133. * \param edgeLengthSkel is saving for each skeleton graph the length
  134. * of each edge.
  135. * \return The size of a maximum external face in \a G containing the node \a n.
  136. */
  137. static T computeSize(
  138. const Graph& G,
  139. const node& n,
  140. const NodeArray<T>& nodeLength,
  141. const EdgeArray<T>& edgeLength,
  142. StaticSPQRTree& spqrTree,
  143. const NodeArray< EdgeArray<T> >& edgeLengthSkel);
  144. /**
  145. * \brief Returns the size of a maximum external face in \a G.
  146. * \param G is the original graph.
  147. * \param nodeLength is saving for each vertex in \a G its length.
  148. * \param edgeLength is saving for each edge in \a G its length.
  149. * \return The size of a maximum external face in \a G.
  150. */
  151. static T computeSize(
  152. const Graph& G,
  153. const NodeArray<T>& nodeLength,
  154. const EdgeArray<T>& edgeLength);
  155. /**
  156. * \brief Returns the size of a maximum external face in \a G.
  157. * The SPQR-tree is given. The computed component lengths are
  158. * computed and returned.
  159. *
  160. * \param G is the original graph.
  161. * \param nodeLength is saving for each vertex in \a G its length.
  162. * \param edgeLength is saving for each edge in \a G its length.
  163. * \param spqrTree is the SPQR-tree of G.
  164. * \param edgeLengthSkel is saving for each skeleton graph the length
  165. * of each edge.
  166. * \return The size of a maximum external face in \a G.
  167. */
  168. static T computeSize(
  169. const Graph& G,
  170. const NodeArray<T>& nodeLength,
  171. const EdgeArray<T>& edgeLength,
  172. StaticSPQRTree& spqrTree,
  173. NodeArray< EdgeArray<T> >& edgeLengthSkel);
  174. private:
  175. /**
  176. * \brief Bottom up traversal of SPQR-tree computing the component length of
  177. * all non-reference edges.
  178. * \param spqrTree is the SPQR-tree of \a G.
  179. * \param mu is the SPQR-tree node treated in this function call.
  180. * \param nodeLength is saving for each node of the original graph \a G its
  181. * length.
  182. * \param edgeLength is saving for each skeleton graph the length of each
  183. * edge.
  184. */
  185. static void bottomUpTraversal(
  186. StaticSPQRTree& spqrTree,
  187. const node& mu,
  188. const NodeArray<T>& nodeLength,
  189. NodeArray< EdgeArray<T> >& edgeLength);
  190. /**
  191. * \brief Top down traversal of SPQR-tree computing the component length of
  192. * all reference edges.
  193. * \param spqrTree is the SPQR-tree of \a G.
  194. * \param mu is the SPQR-tree node treated in this function call.
  195. * \param nodeLength is saving for each node of the original graph \a G its
  196. * length.
  197. * \param edgeLength is saving for each skeleton graph the length of each
  198. * edge.
  199. */
  200. static void topDownTraversal(
  201. StaticSPQRTree& spqrTree,
  202. const node& mu,
  203. const NodeArray<T>& nodeLength,
  204. NodeArray< EdgeArray<T> >& edgeLength);
  205. /**
  206. * \brief Computes the size of a maximum face in the skeleton graph of \a mu
  207. * containing \a n.
  208. * \param spqrTree is the SPQR-tree of \a G.
  209. * \param mu is the SPQR-tree node treated in this function call.
  210. * \param n is a node of the original graph \a G.
  211. * \param nodeLength is saving for each node of the original graph \a G its
  212. * length.
  213. * \param edgeLength is saving for each skeleton graph the length of each
  214. * edge.
  215. */
  216. static T largestFaceContainingNode(
  217. const StaticSPQRTree& spqrTree,
  218. const node& mu,
  219. const node& n,
  220. const NodeArray<T>& nodeLength,
  221. const NodeArray< EdgeArray<T> >& edgeLength);
  222. /**
  223. * \brief Computes the size of a maximum face in the skeleton graph of \a mu.
  224. * \param spqrTree is the SPQR-tree of \a G.
  225. * \param mu is the SPQR-tree node treated in this function call.
  226. * \param nodeLength is saving for each node of the original graph \a G its
  227. * length.
  228. * \param edgeLength is saving for each skeleton graph the length of each
  229. * edge.
  230. */
  231. static T largestFaceInSkeleton(
  232. const StaticSPQRTree& spqrTree,
  233. const node& mu,
  234. const NodeArray<T>& nodeLength,
  235. const NodeArray< EdgeArray<T> >& edgeLength);
  236. /* \brief ExpandEdge embeds all edges in the skeleton graph \a S into an
  237. * existing embedding and calls recursively itself for all virtual edges
  238. * in S.
  239. *
  240. * \param spqrTree The SPQR-tree of the treated graph.
  241. * \param treeNodeTreated is an array saving for each SPQR-tree node \a mu
  242. * whether it was already treated by any call of ExpandEdge or not. Every
  243. * \a mu should only be treated once.
  244. * \param mu is a node in the SPQR-tree.
  245. * \param leftNode is the node adjacent to referenceEdge, which should be "left"
  246. * in the embedding
  247. * \param nodeLength is an array saving the lengths of the nodes of \a G.
  248. * \param edgeLength is saving the edge lengths of all edges in each skeleton
  249. * graph of all tree nodes.
  250. * \param newOrder is saving for each node \a n in \a G the new adjacency
  251. * list. This is an output parameter.
  252. * \param adjBeforeNodeArraySource is saving for the source of the reference edge
  253. * of the skeleton of mu the adjacency entry, before which new entries have
  254. * to be inserted.
  255. * \param adjBeforeNodeArrayTarget is saving for the target of the reference edge
  256. * of the skeleton of mu the adjacency entry, before which new entries have
  257. * to be inserted.
  258. * \param adjExternal is an adjacency entry in the external face.
  259. * \param n is only set, if ExpandEdge is called for the first time, because
  260. * then there is no virtual edge which has to be expanded, but the max face
  261. * has to contain a certain node \a n.
  262. */
  263. static void expandEdge(
  264. const StaticSPQRTree& spqrTree,
  265. NodeArray<bool>& treeNodeTreated,
  266. const node& mu,
  267. const node& leftNode,
  268. const NodeArray<T>& nodeLength,
  269. const NodeArray< EdgeArray<T> >& edgeLength,
  270. NodeArray< List<adjEntry> >& newOrder,
  271. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  272. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  273. adjEntry& adjExternal,
  274. const node& n = 0);
  275. /* \brief Embeds all edges in the skeleton graph \a S of an S-node of the
  276. * SPQR-tree into an existing embedding and calls recursively itself for
  277. * all virtual edges in S.
  278. *
  279. * \param spqrTree The SPQR-tree of the treated graph.
  280. * \param treeNodeTreated is an array saving for each SPQR-tree node \a mu
  281. * whether it was already treated by any call of ExpandEdge or not. Every
  282. * \a mu should only be treated once.
  283. * \param mu is a node in the SPQR-tree.
  284. * \param leftNode is the node adjacent to referenceEdge, which should be "left"
  285. * in the embedding
  286. * \param nodeLength is an array saving the lengths of the nodes of \a G.
  287. * \param edgeLength is saving the edge lengths of all edges in each skeleton
  288. * graph of all tree nodes.
  289. * \param newOrder is saving for each node \a n in \a G the new adjacency
  290. * list. This is an output parameter.
  291. * \param adjBeforeNodeArraySource is saving for the source of the reference edge
  292. * of the skeleton of mu the adjacency entry, before which new entries have
  293. * to be inserted.
  294. * \param adjBeforeNodeArrayTarget is saving for the target of the reference edge
  295. * of the skeleton of mu the adjacency entry, before which new entries have
  296. * to be inserted.
  297. * \param adjExternal is an adjacency entry in the external face.
  298. */
  299. static void expandEdgeSNode(
  300. const StaticSPQRTree& spqrTree,
  301. NodeArray<bool>& treeNodeTreated,
  302. const node& mu,
  303. const node& leftNode,
  304. const NodeArray<T>& nodeLength,
  305. const NodeArray< EdgeArray<T> >& edgeLength,
  306. NodeArray< List<adjEntry> >& newOrder,
  307. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  308. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  309. adjEntry& adjExternal);
  310. /* \brief Embeds all edges in the skeleton graph \a S of an P-node of the
  311. * SPQR-tree into an existing embedding and calls recursively itself for
  312. * all virtual edges in S.
  313. *
  314. * \param spqrTree The SPQR-tree of the treated graph.
  315. * \param treeNodeTreated is an array saving for each SPQR-tree node \a mu
  316. * whether it was already treated by any call of ExpandEdge or not. Every
  317. * \a mu should only be treated once.
  318. * \param mu is a node in the SPQR-tree.
  319. * \param leftNode is the node adjacent to referenceEdge, which should be "left"
  320. * in the embedding
  321. * \param nodeLength is an array saving the lengths of the nodes of \a G.
  322. * \param edgeLength is saving the edge lengths of all edges in each skeleton
  323. * graph of all tree nodes.
  324. * \param newOrder is saving for each node \a n in \a G the new adjacency
  325. * list. This is an output parameter.
  326. * \param adjBeforeNodeArraySource is saving for the source of the reference edge
  327. * of the skeleton of mu the adjacency entry, before which new entries have
  328. * to be inserted.
  329. * \param adjBeforeNodeArrayTarget is saving for the target of the reference edge
  330. * of the skeleton of mu the adjacency entry, before which new entries have
  331. * to be inserted.
  332. * \param adjExternal is an adjacency entry in the external face.
  333. */
  334. static void expandEdgePNode(
  335. const StaticSPQRTree& spqrTree,
  336. NodeArray<bool>& treeNodeTreated,
  337. const node& mu,
  338. const node& leftNode,
  339. const NodeArray<T>& nodeLength,
  340. const NodeArray< EdgeArray<T> >& edgeLength,
  341. NodeArray< List<adjEntry> >& newOrder,
  342. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  343. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  344. adjEntry& adjExternal);
  345. /* \brief Embeds all edges in the skeleton graph \a S of an R-node of the
  346. * SPQR-tree into an existing embedding and calls recursively itself for
  347. * all virtual edges in S.
  348. *
  349. * \param spqrTree The SPQR-tree of the treated graph.
  350. * \param treeNodeTreated is an array saving for each SPQR-tree node \a mu
  351. * whether it was already treated by any call of ExpandEdge or not. Every
  352. * \a mu should only be treated once.
  353. * \param mu is a node in the SPQR-tree.
  354. * \param leftNode is the node adjacent to referenceEdge, which should be "left"
  355. * in the embedding
  356. * \param nodeLength is an array saving the lengths of the nodes of \a G.
  357. * \param edgeLength is saving the edge lengths of all edges in each skeleton
  358. * graph of all tree nodes.
  359. * \param newOrder is saving for each node \a n in \a G the new adjacency
  360. * list. This is an output parameter.
  361. * \param adjBeforeNodeArraySource is saving for the source of the reference edge
  362. * of the skeleton of mu the adjacency entry, before which new entries have
  363. * to be inserted.
  364. * \param adjBeforeNodeArrayTarget is saving for the target of the reference edge
  365. * of the skeleton of mu the adjacency entry, before which new entries have
  366. * to be inserted.
  367. * \param adjExternal is an adjacency entry in the external face.
  368. * \param n is only set, if ExpandEdge is called for the first time, because
  369. * then there is no virtual edge which has to be expanded, but the max face
  370. * has to contain a certain node \a n.
  371. */
  372. static void expandEdgeRNode(
  373. const StaticSPQRTree& spqrTree,
  374. NodeArray<bool>& treeNodeTreated,
  375. const node& mu,
  376. const node& leftNode,
  377. const NodeArray<T>& nodeLength,
  378. const NodeArray< EdgeArray<T> >& edgeLength,
  379. NodeArray< List<adjEntry> >& newOrder,
  380. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  381. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  382. adjEntry& adjExternal,
  383. const node& n);
  384. /* \brief Writes a given adjacency entry into the newOrder. If the edge
  385. * belonging to ae is a virtual edge, it is expanded.
  386. *
  387. * \param ae is the adjacency entry which has to be expanded.
  388. * \param before is the adjacency entry of the node in \a G, before
  389. * which ae has to be inserted.
  390. * \param spqrTree The SPQR-tree of the treated graph.
  391. * \param treeNodeTreated is an array saving for each SPQR-tree node \a mu
  392. * whether it was already treated by any call of ExpandEdge or not. Every
  393. * \a mu should only be treated once.
  394. * \param mu is a node in the SPQR-tree.
  395. * \param leftNode is the node adjacent to referenceEdge, which should be "left"
  396. * in the embedding
  397. * \param nodeLength is an array saving the lengths of the nodes of \a G.
  398. * \param edgeLength is saving the edge lengths of all edges in each skeleton
  399. * graph of all tree nodes.
  400. * \param newOrder is saving for each node \a n in \a G the new adjacency
  401. * list. This is an output parameter.
  402. * \param adjBeforeNodeArraySource is saving for the source of the reference edge
  403. * of the skeleton of mu the adjacency entry, before which new entries have
  404. * to be inserted.
  405. * \param adjBeforeNodeArrayTarget is saving for the target of the reference edge
  406. * of the skeleton of mu the adjacency entry, before which new entries have
  407. * to be inserted.
  408. * \param adjExternal is an adjacency entry in the external face.
  409. */
  410. static void adjEntryForNode(
  411. adjEntry& ae,
  412. ListIterator<adjEntry>& before,
  413. const StaticSPQRTree& spqrTree,
  414. NodeArray<bool>& treeNodeTreated,
  415. const node& mu,
  416. const node& leftNode,
  417. const NodeArray<T>& nodeLength,
  418. const NodeArray< EdgeArray<T> >& edgeLength,
  419. NodeArray< List<adjEntry> >& newOrder,
  420. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  421. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  422. adjEntry& adjExternal);
  423. };
  424. template<class T>
  425. void EmbedderMaxFaceBiconnectedGraphs<T>::embed(
  426. Graph& G,
  427. adjEntry& adjExternal,
  428. const NodeArray<T>& nodeLength,
  429. const EdgeArray<T>& edgeLength,
  430. const node& n /* = 0*/)
  431. {
  432. //Base cases (SPQR-Tree implementation would crash with these inputs):
  433. OGDF_ASSERT(G.numberOfNodes() >= 2)
  434. if (G.numberOfEdges() <= 2)
  435. {
  436. edge e = G.firstEdge();
  437. adjExternal = e->adjSource();
  438. return;
  439. }
  440. //****************************************************************************
  441. //First step: calculate maximum face and edge lengths for virtual edges
  442. //****************************************************************************
  443. StaticSPQRTree spqrTree(G);
  444. NodeArray< EdgeArray<T> > edgeLengthSkel;
  445. compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  446. //****************************************************************************
  447. //Second step: Embed G
  448. //****************************************************************************
  449. T biggestFace = -1;
  450. node bigFaceMu;
  451. if (n == 0)
  452. {
  453. node mu;
  454. forall_nodes(mu, spqrTree.tree())
  455. {
  456. //Expand all faces in skeleton(mu) and get size of the largest of them:
  457. T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
  458. if (sizeMu > biggestFace)
  459. {
  460. biggestFace = sizeMu;
  461. bigFaceMu = mu;
  462. }
  463. }
  464. }
  465. else
  466. {
  467. edge nAdjEdge;
  468. node* mus = new node[n->degree()];
  469. int i = 0;
  470. forall_adj_edges(nAdjEdge, n)
  471. {
  472. mus[i] = spqrTree.skeletonOfReal(nAdjEdge).treeNode();
  473. bool alreadySeenMu = false;
  474. for (int j = 0; j < i && !alreadySeenMu; j++)
  475. {
  476. if (mus[i] == mus[j])
  477. alreadySeenMu = true;
  478. }
  479. if (alreadySeenMu)
  480. {
  481. i++;
  482. continue;
  483. }
  484. else
  485. {
  486. //Expand all faces in skeleton(mu) containing n and get size of
  487. //the largest of them:
  488. T sizeInMu = largestFaceContainingNode(spqrTree, mus[i], n,
  489. nodeLength, edgeLengthSkel);
  490. if (sizeInMu > biggestFace)
  491. {
  492. biggestFace = sizeInMu;
  493. bigFaceMu = mus[i];
  494. }
  495. i++;
  496. }
  497. }
  498. delete mus;
  499. }
  500. bigFaceMu = spqrTree.rootTreeAt(bigFaceMu);
  501. NodeArray< List<adjEntry> > newOrder(G);
  502. NodeArray<bool> treeNodeTreated(spqrTree.tree(), false);
  503. ListIterator<adjEntry> it;
  504. adjExternal = 0;
  505. NodeArray< ListIterator<adjEntry> > adjBeforeNodeArraySource(spqrTree.tree());
  506. NodeArray< ListIterator<adjEntry> > adjBeforeNodeArrayTarget(spqrTree.tree());
  507. expandEdge(spqrTree, treeNodeTreated, bigFaceMu, 0, nodeLength,
  508. edgeLengthSkel, newOrder, adjBeforeNodeArraySource,
  509. adjBeforeNodeArrayTarget, adjExternal, n);
  510. node v;
  511. forall_nodes(v, G)
  512. G.sort(v, newOrder[v]);
  513. }
  514. template<class T>
  515. void EmbedderMaxFaceBiconnectedGraphs<T>::adjEntryForNode(
  516. adjEntry& ae,
  517. ListIterator<adjEntry>& before,
  518. const StaticSPQRTree& spqrTree,
  519. NodeArray<bool>& treeNodeTreated,
  520. const node& mu,
  521. const node& leftNode,
  522. const NodeArray<T>& nodeLength,
  523. const NodeArray< EdgeArray<T> >& edgeLength,
  524. NodeArray< List<adjEntry> >& newOrder,
  525. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  526. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  527. adjEntry& adjExternal)
  528. {
  529. Skeleton& S = spqrTree.skeleton(mu);
  530. edge referenceEdge = S.referenceEdge();
  531. if (S.isVirtual(ae->theEdge()))
  532. {
  533. edge twinE = S.twinEdge(ae->theEdge());
  534. node twinNT = S.twinTreeNode(ae->theEdge());
  535. //Skeleton& twinS = spqrTree.skeleton(twinNT);
  536. if (!treeNodeTreated[twinNT])
  537. {
  538. node m_leftNode;
  539. if (ae->theEdge()->source() == leftNode)
  540. m_leftNode = twinE->source();
  541. else
  542. m_leftNode = twinE->target();
  543. if (ae->theEdge()->source() == ae->theNode())
  544. adjBeforeNodeArraySource[twinNT] = before;
  545. else
  546. adjBeforeNodeArrayTarget[twinNT] = before;
  547. //recursion call:
  548. expandEdge(spqrTree, treeNodeTreated, twinNT, m_leftNode,
  549. nodeLength, edgeLength, newOrder,
  550. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  551. adjExternal);
  552. } //if (!treeNodeTreated[twinNT])
  553. if (ae->theEdge() == referenceEdge)
  554. {
  555. if (ae->theNode() == ae->theEdge()->source())
  556. {
  557. ListIterator<adjEntry> tmpBefore = adjBeforeNodeArraySource[mu];
  558. adjBeforeNodeArraySource[mu] = before;
  559. before = tmpBefore;
  560. }
  561. else
  562. {
  563. ListIterator<adjEntry> tmpBefore = adjBeforeNodeArrayTarget[mu];
  564. adjBeforeNodeArrayTarget[mu] = before;
  565. before = tmpBefore;
  566. }
  567. }
  568. else //!(ae->theEdge() == referenceEdge)
  569. {
  570. if (ae->theNode() == ae->theEdge()->source())
  571. before = adjBeforeNodeArraySource[twinNT];
  572. else
  573. before = adjBeforeNodeArrayTarget[twinNT];
  574. }
  575. }
  576. else //!(S.isVirtual(ae->theEdge()))
  577. {
  578. node origNode = S.original(ae->theNode());
  579. edge origEdge = S.realEdge(ae->theEdge());
  580. if (origNode == origEdge->source())
  581. {
  582. if (!before.valid())
  583. before = newOrder[origNode].pushBack(origEdge->adjSource());
  584. else
  585. before = newOrder[origNode].insertBefore(origEdge->adjSource(), before);
  586. }
  587. else
  588. {
  589. if (!before.valid())
  590. before = newOrder[origNode].pushBack(origEdge->adjTarget());
  591. else
  592. before = newOrder[origNode].insertBefore(origEdge->adjTarget(), before);
  593. }
  594. } //else //!(S.isVirtual(ae->theEdge()))
  595. }
  596. template<class T>
  597. void EmbedderMaxFaceBiconnectedGraphs<T>::expandEdge(
  598. const StaticSPQRTree& spqrTree,
  599. NodeArray<bool>& treeNodeTreated,
  600. const node& mu,
  601. const node& leftNode,
  602. const NodeArray<T>& nodeLength,
  603. const NodeArray< EdgeArray<T> >& edgeLength,
  604. NodeArray< List<adjEntry> >& newOrder,
  605. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  606. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  607. adjEntry& adjExternal,
  608. const node& n /*= 0*/)
  609. {
  610. treeNodeTreated[mu] = true;
  611. switch(spqrTree.typeOf(mu))
  612. {
  613. case SPQRTree::SNode:
  614. expandEdgeSNode(spqrTree, treeNodeTreated, mu, leftNode,
  615. nodeLength, edgeLength, newOrder, adjBeforeNodeArraySource,
  616. adjBeforeNodeArrayTarget, adjExternal);
  617. break;
  618. case SPQRTree::PNode:
  619. expandEdgePNode(spqrTree, treeNodeTreated, mu, leftNode,
  620. nodeLength, edgeLength, newOrder, adjBeforeNodeArraySource,
  621. adjBeforeNodeArrayTarget, adjExternal);
  622. break;
  623. case SPQRTree::RNode:
  624. expandEdgeRNode(spqrTree, treeNodeTreated, mu, leftNode,
  625. nodeLength, edgeLength, newOrder, adjBeforeNodeArraySource,
  626. adjBeforeNodeArrayTarget, adjExternal, n);
  627. break;
  628. OGDF_NODEFAULT
  629. }
  630. }
  631. template<class T>
  632. void EmbedderMaxFaceBiconnectedGraphs<T>::expandEdgeSNode(
  633. const StaticSPQRTree& spqrTree,
  634. NodeArray<bool>& treeNodeTreated,
  635. const node& mu,
  636. const node& leftNode,
  637. const NodeArray<T>& nodeLength,
  638. const NodeArray< EdgeArray<T> >& edgeLength,
  639. NodeArray< List<adjEntry> >& newOrder,
  640. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  641. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  642. adjEntry& adjExternal)
  643. {
  644. Skeleton& S = spqrTree.skeleton(mu);
  645. edge referenceEdge = S.referenceEdge();
  646. adjEntry startAdjEntry;
  647. if (leftNode == 0)
  648. {
  649. edge e;
  650. forall_edges(e, S.getGraph())
  651. {
  652. if (!S.isVirtual(e))
  653. {
  654. startAdjEntry = e->adjSource();
  655. break;
  656. }
  657. }
  658. }
  659. else if (leftNode->firstAdj()->theEdge() == referenceEdge)
  660. startAdjEntry = leftNode->lastAdj();
  661. else
  662. startAdjEntry = leftNode->firstAdj();
  663. adjEntry ae = startAdjEntry;
  664. if (adjExternal == 0)
  665. {
  666. edge orgEdge = S.realEdge(ae->theEdge());
  667. if (orgEdge->source() == S.original(ae->theNode()))
  668. adjExternal = orgEdge->adjSource()->twin();
  669. else
  670. adjExternal = orgEdge->adjTarget()->twin();
  671. }
  672. ListIterator<adjEntry> before;
  673. if (!(referenceEdge == 0) && leftNode == referenceEdge->source())
  674. before = adjBeforeNodeArraySource[mu];
  675. else if (!(referenceEdge == 0))
  676. before = adjBeforeNodeArrayTarget[mu];
  677. ListIterator<adjEntry> beforeSource;
  678. bool firstStep = true;
  679. while (firstStep || ae != startAdjEntry)
  680. {
  681. //first treat ae with ae->theNode() is left node, then treat its twin:
  682. node m_leftNode = ae->theNode();
  683. if (ae->theEdge() == referenceEdge)
  684. {
  685. if (ae->theNode() == referenceEdge->source())
  686. adjBeforeNodeArraySource[mu] = before;
  687. else
  688. adjBeforeNodeArrayTarget[mu] = before;
  689. }
  690. else
  691. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  692. m_leftNode, nodeLength, edgeLength, newOrder,
  693. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  694. adjExternal);
  695. if (firstStep)
  696. {
  697. beforeSource = before;
  698. firstStep = false;
  699. }
  700. ae = ae->twin();
  701. before = 0;
  702. if (ae->theEdge() == referenceEdge)
  703. {
  704. if (ae->theNode() == referenceEdge->source())
  705. adjBeforeNodeArraySource[mu] = beforeSource;
  706. else
  707. adjBeforeNodeArrayTarget[mu] = beforeSource;
  708. }
  709. else
  710. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  711. m_leftNode, nodeLength, edgeLength, newOrder,
  712. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  713. adjExternal);
  714. //set new adjacency entry pair (ae and its twin):
  715. if (ae->theNode()->firstAdj() == ae)
  716. ae = ae->theNode()->lastAdj();
  717. else
  718. ae = ae->theNode()->firstAdj();
  719. }
  720. }
  721. template<class T>
  722. void EmbedderMaxFaceBiconnectedGraphs<T>::expandEdgePNode(
  723. const StaticSPQRTree& spqrTree,
  724. NodeArray<bool>& treeNodeTreated,
  725. const node& mu,
  726. const node& leftNode,
  727. const NodeArray<T>& nodeLength,
  728. const NodeArray< EdgeArray<T> >& edgeLength,
  729. NodeArray< List<adjEntry> >& newOrder,
  730. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  731. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  732. adjEntry& adjExternal)
  733. {
  734. //Choose face defined by virtual edge and the longest edge different from it.
  735. Skeleton& S = spqrTree.skeleton(mu);
  736. edge referenceEdge = S.referenceEdge();
  737. edge altReferenceEdge = 0;
  738. node m_leftNode = leftNode;
  739. if (m_leftNode == 0)
  740. {
  741. List<node> nodeList;
  742. S.getGraph().allNodes(nodeList);
  743. m_leftNode = *(nodeList.begin());
  744. }
  745. node m_rightNode = m_leftNode->firstAdj()->twinNode();
  746. edge e;
  747. if (referenceEdge == 0)
  748. {
  749. forall_edges(e, S.getGraph())
  750. {
  751. if (!S.isVirtual(e))
  752. {
  753. altReferenceEdge = e;
  754. edge orgEdge = S.realEdge(e);
  755. if (orgEdge->source() == S.original(m_leftNode))
  756. adjExternal = orgEdge->adjSource();
  757. else
  758. adjExternal = orgEdge->adjTarget();
  759. break;
  760. }
  761. }
  762. }
  763. edge longestEdge = 0;
  764. forall_edges(e, S.getGraph())
  765. {
  766. if (e == referenceEdge || e == altReferenceEdge)
  767. continue;
  768. if (longestEdge == 0 || edgeLength[mu][e] > edgeLength[mu][longestEdge])
  769. longestEdge = e;
  770. }
  771. List<edge> rightEdgeOrder;
  772. ListIterator<adjEntry> beforeAltRefEdge;
  773. //begin with left node and longest edge:
  774. for (int i = 0; i < 2; i++)
  775. {
  776. ListIterator<adjEntry> before;
  777. node n;
  778. if (i == 0)
  779. n = m_leftNode;
  780. else
  781. {
  782. n = m_rightNode;
  783. before = beforeAltRefEdge;
  784. }
  785. if (!(referenceEdge == 0))
  786. {
  787. if (n == referenceEdge->source())
  788. before = adjBeforeNodeArraySource[mu];
  789. else
  790. before = adjBeforeNodeArrayTarget[mu];
  791. }
  792. List<edge> edgeList;
  793. S.getGraph().allEdges(edgeList);
  794. adjEntry ae;
  795. //if left node, longest edge at first:
  796. if (i == 0)
  797. {
  798. if (longestEdge->source() == n)
  799. ae = longestEdge->adjSource();
  800. else
  801. ae = longestEdge->adjTarget();
  802. if (!(referenceEdge == 0) && S.isVirtual(longestEdge))
  803. {
  804. node nu = S.twinTreeNode(longestEdge);
  805. if (longestEdge->source() == n)
  806. {
  807. if (referenceEdge->source() == n)
  808. adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArrayTarget[mu];
  809. else
  810. adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArraySource[mu];
  811. }
  812. else
  813. {
  814. if (referenceEdge->source() == n)
  815. adjBeforeNodeArraySource[nu] = adjBeforeNodeArrayTarget[mu];
  816. else
  817. adjBeforeNodeArraySource[nu] = adjBeforeNodeArraySource[mu];
  818. }
  819. }
  820. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  821. m_leftNode, nodeLength, edgeLength, newOrder,
  822. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  823. adjExternal);
  824. }
  825. //all edges except reference edge and longest edge:
  826. if (i == 0)
  827. {
  828. //all virtual edges
  829. for (ListIterator<edge> it = edgeList.begin(); it.valid(); it++)
  830. {
  831. if (*it == referenceEdge || *it == longestEdge || *it == altReferenceEdge || !S.isVirtual(*it))
  832. continue;
  833. node nu = S.twinTreeNode(*it);
  834. if (!(referenceEdge == 0) && (*it)->source() == n)
  835. {
  836. if (referenceEdge->source() == n)
  837. adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArrayTarget[mu];
  838. else
  839. adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArraySource[mu];
  840. }
  841. else if (!(referenceEdge == 0))
  842. {
  843. if (referenceEdge->source() == n)
  844. adjBeforeNodeArraySource[nu] = adjBeforeNodeArrayTarget[mu];
  845. else
  846. adjBeforeNodeArraySource[nu] = adjBeforeNodeArraySource[mu];
  847. }
  848. rightEdgeOrder.pushFront(*it);
  849. if ((*it)->source() == n)
  850. ae = (*it)->adjSource();
  851. else
  852. ae = (*it)->adjTarget();
  853. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  854. m_leftNode, nodeLength, edgeLength, newOrder,
  855. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  856. adjExternal);
  857. }
  858. //all real edges
  859. for (ListIterator<edge> it = edgeList.begin(); it.valid(); it++)
  860. {
  861. if (*it == referenceEdge || *it == longestEdge || *it == altReferenceEdge || S.isVirtual(*it))
  862. continue;
  863. rightEdgeOrder.pushFront(*it);
  864. if ((*it)->source() == n)
  865. ae = (*it)->adjSource();
  866. else
  867. ae = (*it)->adjTarget();
  868. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  869. m_leftNode, nodeLength, edgeLength, newOrder,
  870. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  871. adjExternal);
  872. }
  873. }
  874. else
  875. {
  876. for (ListIterator<edge> it = rightEdgeOrder.begin(); it.valid(); it++)
  877. {
  878. if ((*it)->source() == n)
  879. ae = (*it)->adjSource();
  880. else
  881. ae = (*it)->adjTarget();
  882. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  883. m_leftNode, nodeLength, edgeLength, newOrder,
  884. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  885. adjExternal);
  886. }
  887. }
  888. //if not left node, longest edge:
  889. if (i == 1)
  890. {
  891. if (longestEdge->source() == n)
  892. ae = longestEdge->adjSource();
  893. else
  894. ae = longestEdge->adjTarget();
  895. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  896. m_leftNode, nodeLength, edgeLength, newOrder,
  897. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  898. adjExternal);
  899. }
  900. //(alternative) reference edge at last:
  901. if (!(referenceEdge == 0))
  902. {
  903. if (n == referenceEdge->source())
  904. adjBeforeNodeArraySource[mu] = before;
  905. else
  906. adjBeforeNodeArrayTarget[mu] = before;
  907. }
  908. else
  909. {
  910. node newLeftNode;
  911. if (i == 0)
  912. newLeftNode = m_leftNode->firstAdj()->twinNode();
  913. else
  914. newLeftNode = m_leftNode;
  915. if (altReferenceEdge->source() == n)
  916. ae = altReferenceEdge->adjSource();
  917. else
  918. ae = altReferenceEdge->adjTarget();
  919. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  920. newLeftNode, nodeLength, edgeLength, newOrder,
  921. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  922. adjExternal);
  923. if (i == 0 && S.isVirtual(altReferenceEdge))
  924. {
  925. node nu = S.twinTreeNode(altReferenceEdge);
  926. if (altReferenceEdge->source() == n)
  927. beforeAltRefEdge = adjBeforeNodeArrayTarget[nu];
  928. else
  929. beforeAltRefEdge = adjBeforeNodeArraySource[nu];
  930. }
  931. }
  932. }
  933. }
  934. template<class T>
  935. void EmbedderMaxFaceBiconnectedGraphs<T>::expandEdgeRNode(
  936. const StaticSPQRTree& spqrTree,
  937. NodeArray<bool>& treeNodeTreated,
  938. const node& mu,
  939. const node& leftNode,
  940. const NodeArray<T>& nodeLength,
  941. const NodeArray< EdgeArray<T> >& edgeLength,
  942. NodeArray< List<adjEntry> >& newOrder,
  943. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
  944. NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
  945. adjEntry& adjExternal,
  946. const node& n /* = 0 */)
  947. {
  948. Skeleton& S = spqrTree.skeleton(mu);
  949. edge referenceEdge = S.referenceEdge();
  950. //compute biggest face containing the reference edge:
  951. face maxFaceContEdge;
  952. List<node> maxFaceNodes;
  953. planarEmbed(S.getGraph());
  954. CombinatorialEmbedding combinatorialEmbedding(S.getGraph());
  955. T bigFaceSize = -1;
  956. adjEntry m_adjExternal = 0;
  957. face f;
  958. forall_faces(f, combinatorialEmbedding)
  959. {
  960. bool containsVirtualEdgeOrN = false;
  961. adjEntry this_m_adjExternal = 0;
  962. T sizeOfFace = 0;
  963. List<node> faceNodes;
  964. adjEntry ae;
  965. forall_face_adj(ae, f)
  966. {
  967. faceNodes.pushBack(ae->theNode());
  968. if ( (n == 0 && (ae->theEdge() == referenceEdge || referenceEdge == 0))
  969. || S.original(ae->theNode()) == n)
  970. {
  971. containsVirtualEdgeOrN = true;
  972. if (!(referenceEdge == 0))
  973. this_m_adjExternal = ae;
  974. }
  975. if (referenceEdge == 0 && !S.isVirtual(ae->theEdge()))
  976. this_m_adjExternal = ae;
  977. sizeOfFace += edgeLength[mu][ae->theEdge()]
  978. + nodeLength[S.original(ae->theNode())];
  979. }
  980. if (containsVirtualEdgeOrN && !(this_m_adjExternal == 0) && sizeOfFace > bigFaceSize)
  981. {
  982. maxFaceNodes = faceNodes;
  983. bigFaceSize = sizeOfFace;
  984. maxFaceContEdge = f;
  985. m_adjExternal = this_m_adjExternal;
  986. }
  987. }
  988. if (adjExternal == 0)
  989. {
  990. edge orgEdge = S.realEdge(m_adjExternal->theEdge());
  991. if (orgEdge->source() == S.original(m_adjExternal->theNode()))
  992. adjExternal = orgEdge->adjSource();
  993. else
  994. adjExternal = orgEdge->adjTarget();
  995. }
  996. adjEntry adjMaxFace = maxFaceContEdge->firstAdj();
  997. //if embedding is mirror symmetrical embedding of desired embedding,
  998. //invert adjacency list of all nodes:
  999. if (!(referenceEdge == 0))
  1000. {
  1001. //successor of adjEntry of virtual edge in adjacency list of leftNode:
  1002. adjEntry succ_virtualEdge_leftNode;
  1003. if (leftNode == referenceEdge->source())
  1004. succ_virtualEdge_leftNode = referenceEdge->adjSource()->succ();
  1005. else
  1006. succ_virtualEdge_leftNode = referenceEdge->adjTarget()->succ();
  1007. if (!succ_virtualEdge_leftNode)
  1008. succ_virtualEdge_leftNode = leftNode->firstAdj();
  1009. bool succVELNAEInExtFace = false;
  1010. adjEntry aeExtFace;
  1011. forall_face_adj(aeExtFace, maxFaceContEdge)
  1012. {
  1013. if (aeExtFace->theEdge() == succ_virtualEdge_leftNode->theEdge())
  1014. {
  1015. succVELNAEInExtFace = true;
  1016. break;
  1017. }
  1018. }
  1019. if (!succVELNAEInExtFace)
  1020. {
  1021. node v;
  1022. forall_nodes(v, S.getGraph())
  1023. {
  1024. List<adjEntry> newAdjOrder;
  1025. for (adjEntry ae = v->firstAdj(); ae; ae = ae->succ())
  1026. newAdjOrder.pushFront(ae);
  1027. S.getGraph().sort(v, newAdjOrder);
  1028. }
  1029. adjMaxFace = adjMaxFace->twin();
  1030. }
  1031. }
  1032. NodeArray<bool> nodeTreated(S.getGraph(), false);
  1033. adjEntry start_ae;
  1034. if (!(referenceEdge == 0))
  1035. {
  1036. start_ae = adjMaxFace;
  1037. do
  1038. {
  1039. if (start_ae->theEdge() == referenceEdge)
  1040. {
  1041. start_ae = start_ae->faceCycleSucc();
  1042. break;
  1043. }
  1044. start_ae = start_ae->faceCycleSucc();
  1045. } while(start_ae != adjMaxFace);
  1046. }
  1047. else
  1048. start_ae = adjMaxFace;
  1049. //For every edge a buffer saving adjacency entries written in embedding step
  1050. //for nodes on the maximum face, needed in step for other nodes.
  1051. EdgeArray< List<adjEntry> > buffer(S.getGraph());
  1052. bool firstStep = true;
  1053. bool after_start_ae = true;
  1054. for (adjEntry ae = start_ae;
  1055. firstStep || ae != start_ae;
  1056. after_start_ae = (!after_start_ae || !ae->succ()) ? false : true,
  1057. ae = after_start_ae ? ae->faceCycleSucc()
  1058. : (!ae->faceCycleSucc() ? adjMaxFace : ae->faceCycleSucc()))
  1059. {
  1060. firstStep = false;
  1061. //node nodeG = S.original(ae->theNode());
  1062. nodeTreated[ae->theNode()] = true;
  1063. //copy adjacency list of nodes into newOrder:
  1064. ListIterator<adjEntry> before;
  1065. edge vE = (ae->theEdge() == referenceEdge) ? referenceEdge : ae->theEdge();
  1066. node nu = (ae->theEdge() == referenceEdge) ? mu : S.twinTreeNode(ae->theEdge());
  1067. if (S.isVirtual(vE))
  1068. {
  1069. if (ae->theNode() == vE->source())
  1070. before = adjBeforeNodeArraySource[nu];
  1071. else
  1072. before = adjBeforeNodeArrayTarget[nu];
  1073. }
  1074. bool after_ae = true;
  1075. adjEntry m_start_ae;
  1076. if (ae->theEdge() == referenceEdge)
  1077. {
  1078. if (ae->succ())
  1079. m_start_ae = ae->succ();
  1080. else
  1081. m_start_ae = ae->theNode()->firstAdj();
  1082. }
  1083. else
  1084. m_start_ae = ae;
  1085. for (adjEntry aeN = m_start_ae;
  1086. after_ae || aeN != m_start_ae;
  1087. after_ae = (!after_ae || !aeN->succ()) ? false : true,
  1088. aeN = after_ae ? aeN->succ() : (!aeN->succ() ? ae->theNode()->firstAdj() : aeN->succ())
  1089. )
  1090. {
  1091. node m_leftNode = 0;
  1092. if (S.isVirtual(aeN->theEdge()) && aeN->theEdge() != referenceEdge)
  1093. {
  1094. //Compute left node of aeN->theNode(). First get adjacency entry in ext. face
  1095. //(if edge is in ext. face) and compare face cycle successor with successor
  1096. //in node adjacency list. If it is the same, it is the right node, otherwise
  1097. //the left.
  1098. adjEntry aeExtFace = 0;
  1099. bool succInExtFace = false;
  1100. bool aeNInExtFace = false;
  1101. adjEntry aeNSucc = (aeN->succ()) ? aeN->succ() : ae->theNode()->firstAdj();
  1102. aeExtFace = adjMaxFace;
  1103. do
  1104. {
  1105. if (aeExtFace->theEdge() == aeNSucc->theEdge())
  1106. {
  1107. succInExtFace = true;
  1108. if (aeNInExtFace)
  1109. break;
  1110. }
  1111. if (aeExtFace->theEdge() == aeN->theEdge())
  1112. {
  1113. aeNInExtFace = true;
  1114. if (succInExtFace)
  1115. break;
  1116. }
  1117. aeExtFace = aeExtFace->faceCycleSucc();
  1118. } while(aeExtFace != adjMaxFace);
  1119. if (aeNInExtFace && succInExtFace)
  1120. m_leftNode = aeN->twinNode();
  1121. else
  1122. m_leftNode = aeN->theNode();
  1123. node twinTN = S.twinTreeNode(aeN->theEdge());
  1124. if (!(referenceEdge == 0))
  1125. {
  1126. if (aeN->theEdge()->source() == aeN->theNode())
  1127. {
  1128. if (aeN->theEdge()->target() == referenceEdge->source())
  1129. adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
  1130. else if (aeN->theEdge()->target() == referenceEdge->target())
  1131. adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
  1132. }
  1133. else
  1134. {
  1135. if (aeN->theEdge()->source() == referenceEdge->source())
  1136. adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
  1137. else if (aeN->theEdge()->source() == referenceEdge->target())
  1138. adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
  1139. }
  1140. }
  1141. }
  1142. adjEntryForNode(aeN, before, spqrTree, treeNodeTreated, mu,
  1143. m_leftNode, nodeLength, edgeLength, newOrder,
  1144. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  1145. adjExternal);
  1146. //if the other node adjacent to the current treated edge is not in the
  1147. //max face, put written edges into an buffer and clear the adjacency
  1148. //list of that node.
  1149. if (maxFaceNodes.search(aeN->twinNode()) == -1)
  1150. {
  1151. node orig_aeN_twin_theNode = S.original(aeN->twinNode());
  1152. buffer[aeN->theEdge()] = newOrder[orig_aeN_twin_theNode];
  1153. newOrder[orig_aeN_twin_theNode].clear();
  1154. }
  1155. } //for (adjEntry aeN = m_start_ae; [...]
  1156. } //for (adjEntry ae = start_ae; [...]
  1157. //Simple copy of not treated node's adjacency lists (internal nodes). Setting
  1158. //of left node not necessary, because all nodes are not in external face.
  1159. node v;
  1160. forall_nodes(v, S.getGraph())
  1161. {
  1162. if (nodeTreated[v])
  1163. continue;
  1164. node v_original = S.original(v);
  1165. nodeTreated[v] = true;
  1166. ListIterator<adjEntry> before;
  1167. for (adjEntry ae = v->firstAdj(); ae; ae = ae->succ())
  1168. {
  1169. if (buffer[ae->theEdge()].empty())
  1170. {
  1171. adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
  1172. ae->theNode(), nodeLength, edgeLength, newOrder,
  1173. adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
  1174. adjExternal);
  1175. if (!nodeTreated[ae->twinNode()])
  1176. {
  1177. node orig_ae_twin_theNode = S.original(ae->twinNode());
  1178. buffer[ae->theEdge()] = newOrder[orig_ae_twin_theNode];
  1179. newOrder[orig_ae_twin_theNode].clear();
  1180. }
  1181. }
  1182. else
  1183. {
  1184. buffer[ae->theEdge()].reverse();
  1185. for (ListIterator<adjEntry> it = buffer[ae->theEdge()].begin(); it.valid(); it++)
  1186. {
  1187. if (!before.valid())
  1188. before = newOrder[v_original].pushFront(*it);
  1189. else
  1190. before = newOrder[v_original].insertBefore(*it, before);
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196. template<class T>
  1197. void EmbedderMaxFaceBiconnectedGraphs<T>::compute(
  1198. const Graph& G,
  1199. const NodeArray<T>& nodeLength,
  1200. const EdgeArray<T>& edgeLength,
  1201. StaticSPQRTree& spqrTree,
  1202. NodeArray< EdgeArray<T> >& edgeLengthSkel)
  1203. {
  1204. //base cases (SPQR-tree implementation would crash for such graphs):
  1205. if (G.numberOfNodes() <= 1 || G.numberOfEdges() <= 2)
  1206. return;
  1207. //set length for all real edges in skeletons to length of the original edge
  1208. //and initialize edge lengths for virtual edges with 0:
  1209. edgeLengthSkel.init(spqrTree.tree());
  1210. node v;
  1211. forall_nodes(v, spqrTree.tree())
  1212. {
  1213. edgeLengthSkel[v].init(spqrTree.skeleton(v).getGraph());
  1214. edge e;
  1215. forall_edges(e, spqrTree.skeleton(v).getGraph())
  1216. {
  1217. if (spqrTree.skeleton(v).isVirtual(e))
  1218. edgeLengthSkel[v][e] = 0;
  1219. else
  1220. edgeLengthSkel[v][e] = edgeLength[spqrTree.skeleton(v).realEdge(e)];
  1221. }
  1222. }
  1223. //set component-length for all non-reference edges:
  1224. bottomUpTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
  1225. //set component length for all reference edges:
  1226. topDownTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
  1227. }
  1228. template<class T>
  1229. T EmbedderMaxFaceBiconnectedGraphs<T>::computeSize(
  1230. const Graph& G,
  1231. const NodeArray<T>& nodeLength,
  1232. const EdgeArray<T>& edgeLength)
  1233. {
  1234. //base cases (SPQR-tree implementation would crash for such graphs):
  1235. OGDF_ASSERT(G.numberOfNodes() >= 2)
  1236. if (G.numberOfEdges() == 1)
  1237. {
  1238. edge e = G.firstEdge();
  1239. return edgeLength[e] + nodeLength[e->source()]+ nodeLength[e->target()];
  1240. }
  1241. if (G.numberOfEdges() == 2)
  1242. {
  1243. edge e1 = G.firstEdge();
  1244. edge e2 = e1->succ();
  1245. return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->source()] + nodeLength[e1->target()];
  1246. }
  1247. StaticSPQRTree spqrTree(G);
  1248. NodeArray< EdgeArray<T> > edgeLengthSkel;
  1249. return computeSize(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  1250. }
  1251. template<class T>
  1252. T EmbedderMaxFaceBiconnectedGraphs<T>::computeSize(
  1253. const Graph& G,
  1254. const NodeArray<T>& nodeLength,
  1255. const EdgeArray<T>& edgeLength,
  1256. StaticSPQRTree& spqrTree,
  1257. NodeArray< EdgeArray<T> >& edgeLengthSkel)
  1258. {
  1259. //base cases (SPQR-tree implementation would crash for such graphs):
  1260. OGDF_ASSERT(G.numberOfNodes() >= 2)
  1261. if (G.numberOfEdges() == 1)
  1262. {
  1263. edge e = G.firstEdge();
  1264. return edgeLength[e] + nodeLength[e->source()]+ nodeLength[e->target()];
  1265. }
  1266. if (G.numberOfEdges() == 2)
  1267. {
  1268. edge e1 = G.firstEdge();
  1269. edge e2 = e1->succ();
  1270. return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->source()] + nodeLength[e1->target()];
  1271. }
  1272. //set length for all real edges in skeletons to length of the original edge
  1273. //and initialize edge lengths for virtual edges with 0:
  1274. edgeLengthSkel.init(spqrTree.tree());
  1275. node v;
  1276. forall_nodes(v, spqrTree.tree())
  1277. {
  1278. edgeLengthSkel[v].init(spqrTree.skeleton(v).getGraph());
  1279. edge e;
  1280. forall_edges(e, spqrTree.skeleton(v).getGraph())
  1281. {
  1282. if (spqrTree.skeleton(v).isVirtual(e))
  1283. edgeLengthSkel[v][e] = 0;
  1284. else
  1285. edgeLengthSkel[v][e] = edgeLength[spqrTree.skeleton(v).realEdge(e)];
  1286. }
  1287. }
  1288. //set component-length for all non-reference edges:
  1289. bottomUpTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
  1290. //set component length for all reference edges:
  1291. topDownTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
  1292. T biggestFace = -1;
  1293. node mu;
  1294. forall_nodes(mu, spqrTree.tree())
  1295. {
  1296. //Expand all faces in skeleton(mu) and get size of the largest of them:
  1297. T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
  1298. if (sizeMu > biggestFace)
  1299. biggestFace = sizeMu;
  1300. }
  1301. return biggestFace;
  1302. }
  1303. template<class T>
  1304. T EmbedderMaxFaceBiconnectedGraphs<T>::computeSize(
  1305. const Graph& G,
  1306. const node& n,
  1307. const NodeArray<T>& nodeLength,
  1308. const EdgeArray<T>& edgeLength)
  1309. {
  1310. //base cases (SPQR-tree implementation would crash for such graphs):
  1311. OGDF_ASSERT(G.numberOfNodes() >= 2)
  1312. if (G.numberOfEdges() == 1)
  1313. {
  1314. edge e = G.firstEdge();
  1315. return edgeLength[e] + nodeLength[e->source()] + nodeLength[e->target()];
  1316. }
  1317. if (G.numberOfEdges() == 2)
  1318. {
  1319. edge e1 = G.firstEdge();
  1320. edge e2 = e1->succ();
  1321. return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->source()] + nodeLength[e1->target()];
  1322. }
  1323. StaticSPQRTree spqrTree(G);
  1324. NodeArray< EdgeArray<T> > edgeLengthSkel;
  1325. compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  1326. return computeSize(G, n, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  1327. }
  1328. template<class T>
  1329. T EmbedderMaxFaceBiconnectedGraphs<T>::computeSize(
  1330. const Graph& G,
  1331. const node& n,
  1332. const NodeArray<T>& nodeLength,
  1333. const EdgeArray<T>& edgeLength,
  1334. StaticSPQRTree& spqrTree)
  1335. {
  1336. NodeArray< EdgeArray<T> > edgeLengthSkel;
  1337. compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  1338. return computeSize(G, n, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
  1339. }
  1340. template<class T>
  1341. T EmbedderMaxFaceBiconnectedGraphs<T>::computeSize(
  1342. const Graph& G,
  1343. const node& n,
  1344. const NodeArray<T>& nodeLength,
  1345. const EdgeArray<T>& edgeLength,
  1346. StaticSPQRTree& spqrTree,
  1347. const NodeArray< EdgeArray<T> >& edgeLengthSkel)
  1348. {
  1349. //base cases (SPQR-tree implementation would crash for such graphs):
  1350. OGDF_ASSERT(G.numberOfNodes() >= 2)
  1351. if (G.numberOfEdges() == 1)
  1352. {
  1353. edge e = G.firstEdge();
  1354. return edgeLength[e] + nodeLength[e->source()] + nodeLength[e->target()];
  1355. }
  1356. else if (G.numberOfEdges() == 2)
  1357. {
  1358. edge e1 = G.firstEdge();
  1359. edge e2 = e1->succ();
  1360. return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->source()] + nodeLength[e1->target()];
  1361. }
  1362. edge nAdjEdges;
  1363. node* mus = new node[n->degree()];
  1364. int i = 0;
  1365. T biggestFace = -1;
  1366. forall_adj_edges(nAdjEdges, n)
  1367. {
  1368. mus[i] = spqrTree.skeletonOfReal(nAdjEdges).treeNode();
  1369. bool alreadySeenMu = false;
  1370. for (int j = 0; j < i && !alreadySeenMu; j++)
  1371. {
  1372. if (mus[i] == mus[j])
  1373. alreadySeenMu = true;
  1374. }
  1375. if (alreadySeenMu)
  1376. {
  1377. i++;
  1378. continue;
  1379. }
  1380. else
  1381. {
  1382. //Expand all faces in skeleton(mu) containing n and get size of the largest of them:
  1383. T sizeInMu = largestFaceContainingNode(spqrTree, mus[i], n, nodeLength, edgeLengthSkel);
  1384. if (sizeInMu > biggestFace)
  1385. biggestFace = sizeInMu;
  1386. i++;
  1387. }
  1388. }
  1389. delete mus;
  1390. return biggestFace;
  1391. }
  1392. template<class T>
  1393. void EmbedderMaxFaceBiconnectedGraphs<T>::bottomUpTraversal(
  1394. StaticSPQRTree& spqrTree,
  1395. const node& mu,
  1396. const NodeArray<T>& nodeLength,
  1397. NodeArray< EdgeArray<T> >& edgeLength)
  1398. {
  1399. //Recursion:
  1400. edge ed;
  1401. forall_adj_edges(ed, mu)
  1402. {
  1403. if (ed->source() == mu)
  1404. bottomUpTraversal(spqrTree, ed->target(), nodeLength, edgeLength);
  1405. }
  1406. edge e;
  1407. forall_edges(e, spqrTree.skeleton(mu).getGraph())
  1408. {
  1409. //do not treat real edges here and do not treat reference edges:
  1410. if (!spqrTree.skeleton(mu).isVirtual(e) || e == spqrTree.skeleton(mu).referenceEdge())
  1411. continue;
  1412. //pertinent node of e in the SPQR-tree:
  1413. node nu = spqrTree.skeleton(mu).twinTreeNode(e);
  1414. //reference edge of nu (virtual edge in nu associated with mu):
  1415. edge er = spqrTree.skeleton(nu).referenceEdge();
  1416. //sum of the lengths of the two poles of mu:
  1417. node refEdgeSource = spqrTree.skeleton(nu).referenceEdge()->source();
  1418. node origRefEdgeSource = spqrTree.skeleton(nu).original(refEdgeSource);
  1419. node refEdgeTarget = spqrTree.skeleton(nu).referenceEdge()->target();
  1420. node origRefEdgeTarget = spqrTree.skeleton(nu).original(refEdgeTarget);
  1421. T ell = nodeLength[origRefEdgeSource] + nodeLength[origRefEdgeTarget];
  1422. if (spqrTree.typeOf(nu) == SPQRTree::SNode)
  1423. {
  1424. //size of a face in skeleton(nu) minus ell
  1425. T sizeOfFace = 0;
  1426. node nS;
  1427. forall_nodes(nS, spqrTree.skeleton(nu).getGraph())
  1428. sizeOfFace += nodeLength[spqrTree.skeleton(nu).original(nS)];
  1429. edge eS;
  1430. forall_edges(eS, spqrTree.skeleton(nu).getGraph())
  1431. sizeOfFace += edgeLength[nu][eS];
  1432. edgeLength[mu][e] = sizeOfFace - ell;
  1433. }
  1434. else if (spqrTree.typeOf(nu) == SPQRTree::PNode)
  1435. {
  1436. //length of the longest edge different from er in skeleton(nu)
  1437. edge longestEdge = 0;
  1438. forall_edges(ed, spqrTree.skeleton(nu).getGraph())
  1439. {
  1440. if (!(ed == er) && ( longestEdge == 0
  1441. || edgeLength[nu][ed] > edgeLength[nu][longestEdge]))
  1442. {
  1443. longestEdge = ed;
  1444. }
  1445. }
  1446. edgeLength[mu][e] = edgeLength[nu][longestEdge];
  1447. }
  1448. else if (spqrTree.typeOf(nu) == SPQRTree::RNode)
  1449. {
  1450. //size of the largest face containing er in skeleton(nu) minus ell
  1451. //Calculate an embedding of the graph (it exists only two which are
  1452. //mirror-symmetrical):
  1453. planarEmbed(spqrTree.skeleton(nu).getGraph());
  1454. CombinatorialEmbedding combinatorialEmbedding(spqrTree.skeleton(nu).getGraph());
  1455. T biggestFaceSize = -1;
  1456. face f;
  1457. forall_faces(f, combinatorial

Large files files are truncated, but you can click here to view the full file