00001
00002
00003
00004
00005
00006
00007
00008
00050 #ifdef _MSC_VER
00051 #pragma once
00052 #endif
00053
00054 #ifndef OGDF_EMBEDDER_MAX_FACE_BICONNECTED_GRAPHS_Layers_H
00055 #define OGDF_EMBEDDER_MAX_FACE_BICONNECTED_GRAPHS_Layers_H
00056
00057 #include <ogdf/decomposition/StaticSPQRTree.h>
00058 #include <ogdf/basic/CombinatorialEmbedding.h>
00059 #include <ogdf/planarity/PlanarModule.h>
00060 #include <ogdf/graphalg/ShortestPathWithBFM.h>
00061
00062
00063 namespace ogdf {
00064
00065 template<class T>
00066 class EmbedderMaxFaceBiconnectedGraphsLayers
00067 {
00068 public:
00070 EmbedderMaxFaceBiconnectedGraphsLayers() { }
00071
00082 static void embed(
00083 Graph& G,
00084 adjEntry& adjExternal,
00085 const NodeArray<T>& nodeLength,
00086 const EdgeArray<T>& edgeLength,
00087 const node& n = 0);
00088
00098 static void compute(
00099 const Graph& G,
00100 const NodeArray<T>& nodeLength,
00101 const EdgeArray<T>& edgeLength,
00102 StaticSPQRTree& spqrTree,
00103 NodeArray< EdgeArray<T> >& edgeLengthSkel);
00104
00113 static T computeSize(
00114 const Graph& G,
00115 const node& n,
00116 const NodeArray<T>& nodeLength,
00117 const EdgeArray<T>& edgeLength);
00118
00130 static T computeSize(
00131 const Graph& G,
00132 const node& n,
00133 const NodeArray<T>& nodeLength,
00134 const EdgeArray<T>& edgeLength,
00135 StaticSPQRTree& spqrTree);
00136
00150 static T computeSize(
00151 const Graph& G,
00152 const node& n,
00153 const NodeArray<T>& nodeLength,
00154 const EdgeArray<T>& edgeLength,
00155 StaticSPQRTree& spqrTree,
00156 const NodeArray< EdgeArray<T> >& edgeLengthSkel);
00157
00165 static T computeSize(
00166 const Graph& G,
00167 const NodeArray<T>& nodeLength,
00168 const EdgeArray<T>& edgeLength);
00169
00183 static T computeSize(
00184 const Graph& G,
00185 const NodeArray<T>& nodeLength,
00186 const EdgeArray<T>& edgeLength,
00187 StaticSPQRTree& spqrTree,
00188 NodeArray< EdgeArray<T> >& edgeLengthSkel);
00189
00190 private:
00201 static void bottomUpTraversal(
00202 StaticSPQRTree& spqrTree,
00203 const node& mu,
00204 const NodeArray<T>& nodeLength,
00205 NodeArray< EdgeArray<T> >& edgeLength);
00206
00217 static void topDownTraversal(
00218 StaticSPQRTree& spqrTree,
00219 const node& mu,
00220 const NodeArray<T>& nodeLength,
00221 NodeArray< EdgeArray<T> >& edgeLength);
00222
00234 static T largestFaceContainingNode(
00235 const StaticSPQRTree& spqrTree,
00236 const node& mu,
00237 const node& n,
00238 const NodeArray<T>& nodeLength,
00239 const NodeArray< EdgeArray<T> >& edgeLength);
00240
00250 static T largestFaceInSkeleton(
00251 const StaticSPQRTree& spqrTree,
00252 const node& mu,
00253 const NodeArray<T>& nodeLength,
00254 const NodeArray< EdgeArray<T> >& edgeLength);
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 static void bottomUpThickness(
00269 const StaticSPQRTree& spqrTree,
00270 const node& mu,
00271 NodeArray<T>& thickness,
00272 const NodeArray<T>& nodeLength,
00273 const NodeArray< EdgeArray<T> >& edgeLength);
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 static void expandEdge(
00307 const StaticSPQRTree& spqrTree,
00308 NodeArray<bool>& treeNodeTreated,
00309 const node& mu,
00310 const node& leftNode,
00311 const NodeArray<T>& nodeLength,
00312 const NodeArray< EdgeArray<T> >& edgeLength,
00313 const NodeArray<T>& thickness,
00314 NodeArray< List<adjEntry> >& newOrder,
00315 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00316 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00317 const T& delta_u,
00318 const T& delta_d,
00319 adjEntry& adjExternal,
00320 const node& n = 0);
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 static void expandEdgeSNode(
00351 const StaticSPQRTree& spqrTree,
00352 NodeArray<bool>& treeNodeTreated,
00353 const node& mu,
00354 const node& leftNode,
00355 const NodeArray<T>& nodeLength,
00356 const NodeArray< EdgeArray<T> >& edgeLength,
00357 const NodeArray<T>& thickness,
00358 NodeArray< List<adjEntry> >& newOrder,
00359 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00360 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00361 const T& delta_u,
00362 const T& delta_d,
00363 adjEntry& adjExternal);
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 static void expandEdgePNode(
00394 const StaticSPQRTree& spqrTree,
00395 NodeArray<bool>& treeNodeTreated,
00396 const node& mu,
00397 const node& leftNode,
00398 const NodeArray<T>& nodeLength,
00399 const NodeArray< EdgeArray<T> >& edgeLength,
00400 const NodeArray<T>& thickness,
00401 NodeArray< List<adjEntry> >& newOrder,
00402 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00403 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00404 const T& delta_u,
00405 const T& delta_d,
00406 adjEntry& adjExternal);
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 static void expandEdgeRNode(
00440 const StaticSPQRTree& spqrTree,
00441 NodeArray<bool>& treeNodeTreated,
00442 const node& mu,
00443 const node& leftNode,
00444 const NodeArray<T>& nodeLength,
00445 const NodeArray< EdgeArray<T> >& edgeLength,
00446 const NodeArray<T>& thickness,
00447 NodeArray< List<adjEntry> >& newOrder,
00448 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00449 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00450 const T& delta_u,
00451 const T& delta_d,
00452 adjEntry& adjExternal,
00453 const node& n = 0);
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 static void adjEntryForNode(
00486 adjEntry& ae,
00487 ListIterator<adjEntry>& before,
00488 const StaticSPQRTree& spqrTree,
00489 NodeArray<bool>& treeNodeTreated,
00490 const node& mu,
00491 const node& leftNode,
00492 const NodeArray<T>& nodeLength,
00493 const NodeArray< EdgeArray<T> >& edgeLength,
00494 const NodeArray<T>& thickness,
00495 NodeArray< List<adjEntry> >& newOrder,
00496 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00497 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00498 const T& delta_u,
00499 const T& delta_d,
00500 adjEntry& adjExternal);
00501
00502
00503
00504
00505
00506
00507
00508
00509 static bool sssp(
00510 const Graph& G,
00511 const node& s,
00512 const EdgeArray<T>& length,
00513 NodeArray<T>& d);
00514 };
00515
00516
00517 template<class T>
00518 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::embed(
00519 Graph& G,
00520 adjEntry& adjExternal,
00521 const NodeArray<T>& nodeLength,
00522 const EdgeArray<T>& edgeLength,
00523 const node& n )
00524 {
00525
00526 if (G.empty())
00527 return;
00528 if (G.numberOfNodes() == 1)
00529 return;
00530 if (G.numberOfEdges() == 1)
00531 {
00532 edge e = G.chooseEdge();
00533 node n1 = e->source();
00534 node n2 = e->target();
00535 NodeArray< List<adjEntry> > newOrder(G);
00536 newOrder[n1].pushBack(e->adjSource());
00537 newOrder[n2].pushBack(e->adjTarget());
00538 G.sort(n1, newOrder[n1]);
00539 G.sort(n2, newOrder[n2]);
00540 adjExternal = e->adjSource();
00541 return;
00542 }
00543
00544
00545
00546
00547 StaticSPQRTree spqrTree(G);
00548 NodeArray< EdgeArray<T> > edgeLengthSkel;
00549 compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
00550
00551
00552
00553
00554 T biggestFace = -1;
00555 node bigFaceMu;
00556 if (n == 0)
00557 {
00558 node mu;
00559 forall_nodes(mu, spqrTree.tree())
00560 {
00561
00562 T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
00563 if (sizeMu > biggestFace)
00564 {
00565 biggestFace = sizeMu;
00566 bigFaceMu = mu;
00567 }
00568 }
00569 }
00570 else
00571 {
00572 edge nAdjEdge;
00573 node* mus = new node[n->degree()];
00574 int i = 0;
00575 forall_adj_edges(nAdjEdge, n)
00576 {
00577 mus[i] = spqrTree.skeletonOfReal(nAdjEdge).treeNode();
00578 bool alreadySeenMu = false;
00579 for (int j = 0; j < i && !alreadySeenMu; j++)
00580 {
00581 if (mus[i] == mus[j])
00582 alreadySeenMu = true;
00583 }
00584 if (alreadySeenMu)
00585 {
00586 i++;
00587 continue;
00588 }
00589 else
00590 {
00591
00592
00593 T sizeInMu = largestFaceContainingNode(spqrTree, mus[i], n,
00594 nodeLength, edgeLengthSkel);
00595 if (sizeInMu > biggestFace)
00596 {
00597 biggestFace = sizeInMu;
00598 bigFaceMu = mus[i];
00599 }
00600
00601 i++;
00602 }
00603 }
00604 delete mus;
00605 }
00606
00607 bigFaceMu = spqrTree.rootTreeAt(bigFaceMu);
00608
00609 NodeArray<T> thickness(spqrTree.tree());
00610 bottomUpThickness(spqrTree, bigFaceMu, thickness, nodeLength, edgeLengthSkel);
00611
00612 NodeArray< List<adjEntry> > newOrder(G);
00613 NodeArray<bool> treeNodeTreated(spqrTree.tree(), false);
00614 ListIterator<adjEntry> it;
00615 adjExternal = 0;
00616 NodeArray< ListIterator<adjEntry> > adjBeforeNodeArraySource(spqrTree.tree());
00617 NodeArray< ListIterator<adjEntry> > adjBeforeNodeArrayTarget(spqrTree.tree());
00618 expandEdge(spqrTree, treeNodeTreated, bigFaceMu, 0, nodeLength,
00619 edgeLengthSkel, thickness, newOrder, adjBeforeNodeArraySource,
00620 adjBeforeNodeArrayTarget, 0, 0, adjExternal, n);
00621
00622 node v;
00623 forall_nodes(v, G)
00624 G.sort(v, newOrder[v]);
00625 }
00626
00627 template<class T>
00628 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::adjEntryForNode(
00629 adjEntry& ae,
00630 ListIterator<adjEntry>& before,
00631 const StaticSPQRTree& spqrTree,
00632 NodeArray<bool>& treeNodeTreated,
00633 const node& mu,
00634 const node& leftNode,
00635 const NodeArray<T>& nodeLength,
00636 const NodeArray< EdgeArray<T> >& edgeLength,
00637 const NodeArray<T>& thickness,
00638 NodeArray< List<adjEntry> >& newOrder,
00639 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00640 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00641 const T& delta_u,
00642 const T& delta_d,
00643 adjEntry& adjExternal)
00644 {
00645 Skeleton& S = spqrTree.skeleton(mu);
00646 edge referenceEdge = S.referenceEdge();
00647 if (S.isVirtual(ae->theEdge()))
00648 {
00649 edge twinE = S.twinEdge(ae->theEdge());
00650 node twinNT = S.twinTreeNode(ae->theEdge());
00651
00652
00653 if (!treeNodeTreated[twinNT])
00654 {
00655 node m_leftNode;
00656 if (ae->theEdge()->source() == leftNode)
00657 m_leftNode = twinE->source();
00658 else
00659 m_leftNode = twinE->target();
00660
00661 if (ae->theEdge()->source() == ae->theNode())
00662 adjBeforeNodeArraySource[twinNT] = before;
00663 else
00664 adjBeforeNodeArrayTarget[twinNT] = before;
00665
00666
00667 expandEdge(spqrTree, treeNodeTreated, twinNT, m_leftNode,
00668 nodeLength, edgeLength, thickness, newOrder,
00669 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
00670 delta_u, delta_d, adjExternal);
00671 }
00672
00673 if (ae->theEdge() == referenceEdge)
00674 {
00675 if (ae->theNode() == ae->theEdge()->source())
00676 {
00677 ListIterator<adjEntry> tmpBefore = adjBeforeNodeArraySource[mu];
00678 adjBeforeNodeArraySource[mu] = before;
00679 before = tmpBefore;
00680 }
00681 else
00682 {
00683 ListIterator<adjEntry> tmpBefore = adjBeforeNodeArrayTarget[mu];
00684 adjBeforeNodeArrayTarget[mu] = before;
00685 before = tmpBefore;
00686 }
00687 }
00688 else
00689 {
00690 if (ae->theNode() == ae->theEdge()->source())
00691 before = adjBeforeNodeArraySource[twinNT];
00692 else
00693 before = adjBeforeNodeArrayTarget[twinNT];
00694 }
00695 }
00696 else
00697 {
00698 node origNode = S.original(ae->theNode());
00699 edge origEdge = S.realEdge(ae->theEdge());
00700
00701 if (origNode == origEdge->source())
00702 {
00703 if (!before.valid())
00704 before = newOrder[origNode].pushBack(origEdge->adjSource());
00705 else
00706 before = newOrder[origNode].insertBefore(origEdge->adjSource(), before);
00707 }
00708 else
00709 {
00710 if (!before.valid())
00711 before = newOrder[origNode].pushBack(origEdge->adjTarget());
00712 else
00713 before = newOrder[origNode].insertBefore(origEdge->adjTarget(), before);
00714 }
00715 }
00716 }
00717
00718 template<class T>
00719 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::expandEdge(
00720 const StaticSPQRTree& spqrTree,
00721 NodeArray<bool>& treeNodeTreated,
00722 const node& mu,
00723 const node& leftNode,
00724 const NodeArray<T>& nodeLength,
00725 const NodeArray< EdgeArray<T> >& edgeLength,
00726 const NodeArray<T>& thickness,
00727 NodeArray< List<adjEntry> >& newOrder,
00728 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00729 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00730 const T& delta_u,
00731 const T& delta_d,
00732 adjEntry& adjExternal,
00733 const node& n )
00734 {
00735 treeNodeTreated[mu] = true;
00736
00737 switch(spqrTree.typeOf(mu))
00738 {
00739 case SPQRTree::SNode:
00740 expandEdgeSNode(spqrTree, treeNodeTreated, mu, leftNode,
00741 nodeLength, edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
00742 adjBeforeNodeArrayTarget, delta_u, delta_d, adjExternal);
00743 break;
00744 case SPQRTree::PNode:
00745 expandEdgePNode(spqrTree, treeNodeTreated, mu, leftNode,
00746 nodeLength, edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
00747 adjBeforeNodeArrayTarget, delta_u, delta_d, adjExternal);
00748 break;
00749 case SPQRTree::RNode:
00750 expandEdgeRNode(spqrTree, treeNodeTreated, mu, leftNode,
00751 nodeLength, edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
00752 adjBeforeNodeArrayTarget, delta_u, delta_d, adjExternal, n);
00753 break;
00754 OGDF_NODEFAULT
00755 }
00756 }
00757
00758 template<class T>
00759 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::expandEdgeSNode(
00760 const StaticSPQRTree& spqrTree,
00761 NodeArray<bool>& treeNodeTreated,
00762 const node& mu,
00763 const node& leftNode,
00764 const NodeArray<T>& nodeLength,
00765 const NodeArray< EdgeArray<T> >& edgeLength,
00766 const NodeArray<T>& thickness,
00767 NodeArray< List<adjEntry> >& newOrder,
00768 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00769 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00770 const T& delta_u,
00771 const T& delta_d,
00772 adjEntry& adjExternal)
00773 {
00774 Skeleton& S = spqrTree.skeleton(mu);
00775 edge referenceEdge = S.referenceEdge();
00776 adjEntry startAdjEntry;
00777 if (leftNode == 0)
00778 {
00779 edge e;
00780 forall_edges(e, S.getGraph())
00781 {
00782 if (!S.isVirtual(e))
00783 {
00784 startAdjEntry = e->adjSource();
00785 break;
00786 }
00787 }
00788 }
00789 else if (leftNode->firstAdj()->theEdge() == referenceEdge)
00790 startAdjEntry = leftNode->lastAdj();
00791 else
00792 startAdjEntry = leftNode->firstAdj();
00793
00794 adjEntry ae = startAdjEntry;
00795 if (adjExternal == 0)
00796 {
00797 edge orgEdge = S.realEdge(ae->theEdge());
00798 if (orgEdge->source() == S.original(ae->theNode()))
00799 adjExternal = orgEdge->adjSource()->twin();
00800 else
00801 adjExternal = orgEdge->adjTarget()->twin();
00802 }
00803
00804 ListIterator<adjEntry> before;
00805 if (!(referenceEdge == 0) && leftNode == referenceEdge->source())
00806 before = adjBeforeNodeArraySource[mu];
00807 else if (!(referenceEdge == 0))
00808 before = adjBeforeNodeArrayTarget[mu];
00809 ListIterator<adjEntry> beforeSource;
00810
00811 bool firstStep = true;
00812 while (firstStep || ae != startAdjEntry)
00813 {
00814
00815 node m_leftNode = ae->theNode();
00816
00817 if (ae->theEdge() == referenceEdge)
00818 {
00819 if (ae->theNode() == referenceEdge->source())
00820 adjBeforeNodeArraySource[mu] = before;
00821 else
00822 adjBeforeNodeArrayTarget[mu] = before;
00823 }
00824 else
00825 {
00826 if (S.isVirtual(ae->theEdge()) && !(referenceEdge == 0))
00827 {
00828 node twinTN = S.twinTreeNode(ae->theEdge());
00829 if (ae->theEdge()->source() == ae->theNode())
00830 {
00831 if (ae->theEdge()->target() == referenceEdge->source())
00832 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
00833 else if (ae->theEdge()->target() == referenceEdge->target())
00834 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
00835 }
00836 else
00837 {
00838 if (ae->theEdge()->source() == referenceEdge->source())
00839 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
00840 else if (ae->theEdge()->source() == referenceEdge->target())
00841 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
00842 }
00843 }
00844
00845 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
00846 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
00847 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
00848 delta_u, delta_d, adjExternal);
00849 }
00850
00851 if (firstStep)
00852 {
00853 beforeSource = before;
00854 firstStep = false;
00855 }
00856
00857 ae = ae->twin();
00858 if (referenceEdge == 0)
00859 before = 0;
00860 else if (ae->theNode() == referenceEdge->source())
00861 before = adjBeforeNodeArraySource[mu];
00862 else if (ae->theNode() == referenceEdge->target())
00863 before = adjBeforeNodeArrayTarget[mu];
00864 else
00865 before = 0;
00866 if (ae->theEdge() == referenceEdge)
00867 {
00868 if (ae->theNode() == referenceEdge->source())
00869 adjBeforeNodeArraySource[mu] = beforeSource;
00870 else
00871 adjBeforeNodeArrayTarget[mu] = beforeSource;
00872 }
00873 else
00874 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
00875 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
00876 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
00877 delta_u, delta_d, adjExternal);
00878
00879
00880 if (ae->theNode()->firstAdj() == ae)
00881 ae = ae->theNode()->lastAdj();
00882 else
00883 ae = ae->theNode()->firstAdj();
00884 }
00885 }
00886
00887 template<class T>
00888 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::expandEdgePNode(
00889 const StaticSPQRTree& spqrTree,
00890 NodeArray<bool>& treeNodeTreated,
00891 const node& mu,
00892 const node& leftNode,
00893 const NodeArray<T>& nodeLength,
00894 const NodeArray< EdgeArray<T> >& edgeLength,
00895 const NodeArray<T>& thickness,
00896 NodeArray< List<adjEntry> >& newOrder,
00897 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
00898 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
00899 const T& delta_u,
00900 const T& delta_d,
00901 adjEntry& adjExternal)
00902 {
00903
00904 Skeleton& S = spqrTree.skeleton(mu);
00905 edge referenceEdge = S.referenceEdge();
00906 edge altReferenceEdge = 0;
00907
00908 node m_leftNode = leftNode;
00909 if (m_leftNode == 0)
00910 {
00911 List<node> nodeList;
00912 S.getGraph().allNodes(nodeList);
00913 m_leftNode = *(nodeList.begin());
00914 }
00915 node m_rightNode = m_leftNode->firstAdj()->twinNode();
00916
00917 edge e;
00918 if (referenceEdge == 0)
00919 {
00920 forall_edges(e, S.getGraph())
00921 {
00922 if (!S.isVirtual(e))
00923 {
00924 altReferenceEdge = e;
00925 edge orgEdge = S.realEdge(e);
00926 if (orgEdge->source() == S.original(m_leftNode))
00927 adjExternal = orgEdge->adjSource();
00928 else
00929 adjExternal = orgEdge->adjTarget();
00930 break;
00931 }
00932 }
00933 }
00934
00935
00936 List<edge> graphEdges;
00937 forall_edges(e, S.getGraph())
00938 {
00939 if (e == referenceEdge || e == altReferenceEdge)
00940 continue;
00941
00942 if (!graphEdges.begin().valid())
00943 graphEdges.pushBack(e);
00944 else
00945 {
00946 for (ListIterator<edge> it = graphEdges.begin(); it.valid(); it++)
00947 {
00948 if (edgeLength[mu][e] > edgeLength[mu][*it])
00949 {
00950 graphEdges.insertBefore(e, it);
00951 break;
00952 }
00953 ListIterator<edge> next = it;
00954 next++;
00955 if (!next.valid())
00956 {
00957 graphEdges.pushBack(e);
00958 break;
00959 }
00960 }
00961 }
00962 }
00963
00964 List<edge> rightEdgeOrder;
00965 ListIterator<adjEntry> beforeAltRefEdge;
00966 ListIterator<adjEntry> beforeLeft;
00967
00968
00969 for (int i = 0; i < 2; i++)
00970 {
00971 ListIterator<adjEntry> before;
00972 node n;
00973 if (i == 0)
00974 n = m_leftNode;
00975 else
00976 {
00977 n = m_rightNode;
00978 before = beforeAltRefEdge;
00979 }
00980
00981 if (!(referenceEdge == 0))
00982 {
00983 if (n == referenceEdge->source())
00984 before = adjBeforeNodeArraySource[mu];
00985 else
00986 before = adjBeforeNodeArrayTarget[mu];
00987 }
00988
00989 adjEntry ae;
00990
00991
00992 if (i == 0)
00993 {
00994 ListIterator<edge> lastPos;
00995 ListIterator<adjEntry> beforeRight;
00996 if (!(referenceEdge == 0))
00997 {
00998 if (referenceEdge->source() == m_rightNode)
00999 beforeRight = adjBeforeNodeArraySource[mu];
01000 else
01001 beforeRight = adjBeforeNodeArrayTarget[mu];
01002 }
01003 bool insertBeforeLast = false;
01004 bool oneEdgeInE_a = false;
01005 T sum_E_a = 0;
01006 T sum_E_b = 0;
01007
01008 for (int looper = 0; looper < graphEdges.size(); looper++)
01009 {
01010 edge e = *(graphEdges.get(looper));
01011
01012 if (!lastPos.valid())
01013 lastPos = rightEdgeOrder.pushBack(e);
01014 else if (insertBeforeLast)
01015 lastPos = rightEdgeOrder.insertBefore(e, lastPos);
01016 else
01017 lastPos = rightEdgeOrder.insertAfter(e, lastPos);
01018
01019
01020 if (delta_u + sum_E_a < delta_d + sum_E_b)
01021 {
01022 ListIterator<adjEntry> beforeU = before;
01023
01024 if (e->source() == n)
01025 ae = e->adjSource();
01026 else
01027 ae = e->adjTarget();
01028
01029 if (S.isVirtual(e))
01030 {
01031 node nu = S.twinTreeNode(e);
01032
01033 T delta_u_nu = delta_u + sum_E_a;
01034 T delta_d_nu = delta_d + sum_E_b;
01035
01036
01037 NodeArray< List<adjEntry> > tmp_newOrder(spqrTree.originalGraph());
01038 ListIterator<adjEntry> tmp_before;
01039
01040 adjEntryForNode(ae, tmp_before, spqrTree, treeNodeTreated, mu,
01041 m_leftNode, nodeLength, edgeLength, thickness,
01042 tmp_newOrder, adjBeforeNodeArraySource,
01043 adjBeforeNodeArrayTarget, delta_d_nu, delta_u_nu, adjExternal);
01044
01045
01046 node leftOrg = S.original(m_leftNode);
01047 node rightOrg = S.original(m_rightNode);
01048 node nOG;
01049 forall_nodes(nOG, spqrTree.originalGraph())
01050 {
01051 List<adjEntry> nOG_tmp_adjList = tmp_newOrder[nOG];
01052 if (nOG_tmp_adjList.size() == 0)
01053 continue;
01054
01055 ListIterator<adjEntry>* m_before;
01056 if (nOG == leftOrg)
01057 m_before = &beforeU;
01058 else if (nOG == rightOrg && !(referenceEdge == 0))
01059 m_before = &beforeRight;
01060 else
01061 m_before = OGDF_NEW ListIterator<adjEntry>();
01062
01063 for (ListIterator<adjEntry> ae_it = nOG_tmp_adjList.begin(); ae_it.valid(); ae_it++)
01064 {
01065 adjEntry adjaEnt = *ae_it;
01066 if (!m_before->valid())
01067 *m_before = newOrder[nOG].pushBack(adjaEnt);
01068 else
01069 *m_before = newOrder[nOG].insertBefore(adjaEnt, *m_before);
01070
01071 if (nOG == leftOrg || nOG == rightOrg)
01072 {
01073 if (S.original(e->source()) == nOG)
01074 adjBeforeNodeArraySource[nu] = *m_before;
01075 else
01076 adjBeforeNodeArrayTarget[nu] = *m_before;
01077 }
01078 }
01079
01080 if (nOG != leftOrg && (nOG != rightOrg || referenceEdge == 0))
01081 delete m_before;
01082 }
01083
01084 sum_E_a += thickness[nu];
01085 }
01086 else
01087 {
01088 adjEntryForNode(ae, beforeU, spqrTree, treeNodeTreated, mu,
01089 m_leftNode, nodeLength, edgeLength, thickness,
01090 newOrder, adjBeforeNodeArraySource,
01091 adjBeforeNodeArrayTarget, 0, 0, adjExternal);
01092
01093 sum_E_a += 1;
01094 }
01095
01096 insertBeforeLast = false;
01097 if (!oneEdgeInE_a)
01098 {
01099 beforeLeft = beforeU;
01100 oneEdgeInE_a = true;
01101 }
01102 }
01103 else
01104 {
01105 if (S.isVirtual(e))
01106 {
01107 node nu = S.twinTreeNode(e);
01108 if (!(referenceEdge == 0))
01109 {
01110 if (e->source() == n)
01111 adjBeforeNodeArrayTarget[nu] = beforeRight;
01112 else
01113 adjBeforeNodeArraySource[nu] = beforeRight;
01114 }
01115 }
01116
01117 T delta_u_nu = delta_u + sum_E_a;
01118 T delta_d_nu = delta_d + sum_E_b;
01119
01120 if (e->source() == n)
01121 ae = e->adjSource();
01122 else
01123 ae = e->adjTarget();
01124
01125 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
01126 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
01127 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01128 delta_u_nu, delta_d_nu, adjExternal);
01129
01130 if (S.isVirtual(e))
01131 sum_E_b += thickness[S.twinTreeNode(e)];
01132 else
01133 sum_E_b += 1;
01134
01135 insertBeforeLast = true;
01136 if (!oneEdgeInE_a)
01137 beforeLeft = before;
01138 }
01139 }
01140 }
01141 else
01142 {
01143 for (ListIterator<edge> it = rightEdgeOrder.begin(); it.valid(); it++)
01144 {
01145 if ((*it)->source() == n)
01146 ae = (*it)->adjSource();
01147 else
01148 ae = (*it)->adjTarget();
01149
01150 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
01151 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
01152 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01153 0, 0, adjExternal);
01154 }
01155 }
01156
01157
01158 if (!(referenceEdge == 0))
01159 {
01160 if (i == 0)
01161 {
01162 if (n == referenceEdge->source())
01163 adjBeforeNodeArraySource[mu] = beforeLeft;
01164 else
01165 adjBeforeNodeArrayTarget[mu] = beforeLeft;
01166 }
01167 else
01168 {
01169 if (n == referenceEdge->source())
01170 adjBeforeNodeArraySource[mu] = before;
01171 else
01172 adjBeforeNodeArrayTarget[mu] = before;
01173 }
01174 }
01175 else
01176 {
01177 if (altReferenceEdge->source() == n)
01178 ae = altReferenceEdge->adjSource();
01179 else
01180 ae = altReferenceEdge->adjTarget();
01181
01182 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
01183 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
01184 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01185 0, 0, adjExternal);
01186 }
01187 }
01188 }
01189
01190 template<class T>
01191 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::expandEdgeRNode(
01192 const StaticSPQRTree& spqrTree,
01193 NodeArray<bool>& treeNodeTreated,
01194 const node& mu,
01195 const node& leftNode,
01196 const NodeArray<T>& nodeLength,
01197 const NodeArray< EdgeArray<T> >& edgeLength,
01198 const NodeArray<T>& thickness,
01199 NodeArray< List<adjEntry> >& newOrder,
01200 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArraySource,
01201 NodeArray< ListIterator<adjEntry> >& adjBeforeNodeArrayTarget,
01202 const T& delta_u,
01203 const T& delta_d,
01204 adjEntry& adjExternal,
01205 const node& n )
01206 {
01207 Skeleton& S = spqrTree.skeleton(mu);
01208 edge referenceEdge = S.referenceEdge();
01209
01210
01211 face maxFaceContEdge;
01212 List<node> maxFaceNodes;
01213 PlanarModule pm;
01214 pm.planarEmbed(S.getGraph());
01215 CombinatorialEmbedding combinatorialEmbedding(S.getGraph());
01216 T bigFaceSize = -1;
01217 adjEntry m_adjExternal = 0;
01218 face f;
01219 forall_faces(f, combinatorialEmbedding)
01220 {
01221 bool containsVirtualEdgeOrN = false;
01222 adjEntry this_m_adjExternal = 0;
01223 T sizeOfFace = 0;
01224 List<node> faceNodes;
01225 adjEntry ae;
01226 forall_face_adj(ae, f)
01227 {
01228 faceNodes.pushBack(ae->theNode());
01229 if ( (n == 0 && (ae->theEdge() == referenceEdge || referenceEdge == 0))
01230 || S.original(ae->theNode()) == n)
01231 {
01232 containsVirtualEdgeOrN = true;
01233 if (!(referenceEdge == 0))
01234 this_m_adjExternal = ae;
01235 }
01236
01237 if (referenceEdge == 0 && !S.isVirtual(ae->theEdge()))
01238 this_m_adjExternal = ae;
01239
01240 sizeOfFace += edgeLength[mu][ae->theEdge()]
01241 + nodeLength[S.original(ae->theNode())];
01242 }
01243
01244 if (containsVirtualEdgeOrN && !(this_m_adjExternal == 0) && sizeOfFace > bigFaceSize)
01245 {
01246 maxFaceNodes = faceNodes;
01247 bigFaceSize = sizeOfFace;
01248 maxFaceContEdge = f;
01249 m_adjExternal = this_m_adjExternal;
01250 }
01251 }
01252
01253 if (adjExternal == 0)
01254 {
01255 edge orgEdge = S.realEdge(m_adjExternal->theEdge());
01256 if (orgEdge->source() == S.original(m_adjExternal->theNode()))
01257 adjExternal = orgEdge->adjSource();
01258 else
01259 adjExternal = orgEdge->adjTarget();
01260 }
01261
01262 adjEntry adjMaxFace = m_adjExternal;
01263
01264
01265
01266 if (!(referenceEdge == 0))
01267 {
01268
01269 adjEntry succ_virtualEdge_leftNode;
01270 if (leftNode == referenceEdge->source())
01271 succ_virtualEdge_leftNode = referenceEdge->adjSource()->succ();
01272 else
01273 succ_virtualEdge_leftNode = referenceEdge->adjTarget()->succ();
01274 if (!succ_virtualEdge_leftNode)
01275 succ_virtualEdge_leftNode = leftNode->firstAdj();
01276
01277 bool succVELNAEInExtFace = false;
01278 adjEntry aeExtFace;
01279 forall_face_adj(aeExtFace, maxFaceContEdge)
01280 {
01281 if (aeExtFace->theEdge() == succ_virtualEdge_leftNode->theEdge())
01282 {
01283 succVELNAEInExtFace = true;
01284 break;
01285 }
01286 }
01287
01288 if (!succVELNAEInExtFace)
01289 {
01290 node v;
01291 forall_nodes(v, S.getGraph())
01292 {
01293 List<adjEntry> newAdjOrder;
01294 for (adjEntry ae = v->firstAdj(); ae; ae = ae->succ())
01295 newAdjOrder.pushFront(ae);
01296 S.getGraph().sort(v, newAdjOrder);
01297 }
01298 adjMaxFace = adjMaxFace->twin();
01299 }
01300 }
01301
01302 NodeArray<bool> nodeTreated(S.getGraph(), false);
01303 adjEntry start_ae;
01304 if (!(referenceEdge == 0))
01305 {
01306 start_ae = adjMaxFace;
01307 do
01308 {
01309 if (start_ae->theEdge() == referenceEdge)
01310 {
01311 start_ae = start_ae->faceCycleSucc();
01312 break;
01313 }
01314 start_ae = start_ae->faceCycleSucc();
01315 } while(start_ae != adjMaxFace);
01316 }
01317 else
01318 start_ae = adjMaxFace;
01319
01320
01321
01322 EdgeArray< List<adjEntry> > buffer(S.getGraph());
01323
01324 bool firstStep = true;
01325 bool after_start_ae = true;
01326 for (adjEntry ae = start_ae;
01327 firstStep || ae != start_ae;
01328 after_start_ae = (!after_start_ae || !ae->succ()) ? false : true,
01329 ae = after_start_ae ? ae->faceCycleSucc()
01330 : (!ae->faceCycleSucc() ? adjMaxFace
01331 : ae->faceCycleSucc()))
01332 {
01333 firstStep = false;
01334
01335 nodeTreated[ae->theNode()] = true;
01336
01337
01338 ListIterator<adjEntry> before;
01339 edge vE = (ae->theEdge() == referenceEdge) ? referenceEdge : ae->theEdge();
01340 node nu = (ae->theEdge() == referenceEdge) ? mu : S.twinTreeNode(ae->theEdge());
01341 if (S.isVirtual(vE))
01342 {
01343 if (ae->theNode() == vE->source())
01344 before = adjBeforeNodeArraySource[nu];
01345 else
01346 before = adjBeforeNodeArrayTarget[nu];
01347 }
01348
01349 bool after_ae = true;
01350 adjEntry m_start_ae;
01351 if (!(referenceEdge == 0))
01352 {
01353 if (ae->theNode() == referenceEdge->source())
01354 m_start_ae = referenceEdge->adjSource();
01355 else if (ae->theNode() == referenceEdge->target())
01356 m_start_ae = referenceEdge->adjTarget();
01357 else
01358 m_start_ae = ae;
01359 }
01360 else
01361 m_start_ae = ae;
01362
01363 adjEntry m_stop_ae;
01364 bool hit_stop_twice = false;
01365 int numOfHits = 0;
01366 if ( !(referenceEdge == 0)
01367 && ( ae->theNode() == referenceEdge->source()
01368 || ae->theNode() == referenceEdge->target()))
01369 {
01370 if (m_start_ae->succ())
01371 m_stop_ae = m_start_ae->succ();
01372 else
01373 {
01374 m_stop_ae = m_start_ae->theNode()->firstAdj();
01375 hit_stop_twice = true;
01376 }
01377 }
01378 else
01379 m_stop_ae = m_start_ae;
01380
01381 for (adjEntry aeN = m_start_ae;
01382 after_ae || (hit_stop_twice && numOfHits != 2) || aeN != m_stop_ae;
01383 after_ae = (!after_ae || !aeN->succ()) ? false : true,
01384 aeN = after_ae ? aeN->succ()
01385 : (!aeN->succ() ? ae->theNode()->firstAdj() : aeN->succ()),
01386 numOfHits = (aeN == m_stop_ae) ? numOfHits + 1 : numOfHits)
01387 {
01388 node m_leftNode = 0;
01389 if (S.isVirtual(aeN->theEdge()) && aeN->theEdge() != referenceEdge)
01390 {
01391
01392
01393
01394
01395 adjEntry aeExtFace = 0;
01396 bool succInExtFace = false;
01397 bool aeNInExtFace = false;
01398 adjEntry aeNSucc = (aeN->succ()) ? aeN->succ() : ae->theNode()->firstAdj();
01399 aeExtFace = adjMaxFace;
01400 do
01401 {
01402 if (aeExtFace->theEdge() == aeNSucc->theEdge())
01403 {
01404 succInExtFace = true;
01405 if (aeNInExtFace)
01406 break;
01407 }
01408 if (aeExtFace->theEdge() == aeN->theEdge())
01409 {
01410 aeNInExtFace = true;
01411 if (succInExtFace)
01412 break;
01413 }
01414 aeExtFace = aeExtFace->faceCycleSucc();
01415 } while(aeExtFace != adjMaxFace);
01416 if (aeNInExtFace && succInExtFace)
01417 m_leftNode = aeN->twinNode();
01418 else
01419 m_leftNode = aeN->theNode();
01420
01421 node twinTN = S.twinTreeNode(aeN->theEdge());
01422 if (!(referenceEdge == 0))
01423 {
01424 if (aeN->theEdge()->source() == aeN->theNode())
01425 {
01426 if (aeN->theEdge()->target() == referenceEdge->source())
01427 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
01428 else if (aeN->theEdge()->target() == referenceEdge->target())
01429 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
01430 }
01431 else
01432 {
01433 if (aeN->theEdge()->source() == referenceEdge->source())
01434 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
01435 else if (aeN->theEdge()->source() == referenceEdge->target())
01436 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
01437 }
01438 }
01439 }
01440
01441 adjEntryForNode(aeN, before, spqrTree, treeNodeTreated, mu,
01442 m_leftNode, nodeLength, edgeLength, thickness, newOrder,
01443 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01444 0, 0, adjExternal);
01445
01446
01447
01448
01449 if (maxFaceNodes.search(aeN->twinNode()) == -1)
01450 {
01451 node orig_aeN_twin_theNode = S.original(aeN->twinNode());
01452 buffer[aeN->theEdge()] = newOrder[orig_aeN_twin_theNode];
01453 newOrder[orig_aeN_twin_theNode].clear();
01454 }
01455 }
01456 }
01457
01458
01459
01460
01461 bool DGcomputed = false;
01462 int f_ext_id = 0;
01463 int f_ref_id = 0;
01464 Graph* p_DG;
01465 List<node>* p_fPG_to_nDG;
01466 NodeArray<int>* p_nDG_to_fPG;
01467 NodeArray< List<adjEntry> >* p_adjacencyList;
01468 List< List<adjEntry> >* p_faces;
01469 NodeArray<T>* p_dist_f_ref;
01470 NodeArray<T>* p_dist_f_ext;
01471 AdjEntryArray<int>* p_ae_to_face;
01472
01473 node v;
01474 forall_nodes(v, S.getGraph())
01475 {
01476 if (nodeTreated[v])
01477 continue;
01478
01479 node v_original = S.original(v);
01480 nodeTreated[v] = true;
01481 ListIterator<adjEntry> before;
01482 for (adjEntry ae = v->firstAdj(); ae; ae = ae->succ())
01483 {
01484 if (buffer[ae->theEdge()].empty())
01485 {
01486 T delta_u_nu = 0;
01487 T delta_d_nu = 0;
01488 bool frauenlinks = false;
01489 if (S.isVirtual(ae->theEdge()))
01490 {
01491 if (!DGcomputed)
01492 {
01493 p_DG = new Graph();
01494 p_fPG_to_nDG = OGDF_NEW List<node>();
01495 p_nDG_to_fPG = OGDF_NEW NodeArray<int>();
01496 p_adjacencyList = OGDF_NEW NodeArray< List<adjEntry> >();
01497 p_faces = OGDF_NEW List< List<adjEntry> >();
01498 p_dist_f_ref = OGDF_NEW NodeArray<T>();
01499 p_dist_f_ext = OGDF_NEW NodeArray<T>();
01500 p_ae_to_face = OGDF_NEW AdjEntryArray<int>(S.getGraph());
01501 EdgeArray<T> edgeLengthDG(*p_DG);
01502 DGcomputed = true;
01503
01504
01505 p_adjacencyList->init(S.getGraph());
01506 node nBG;
01507 forall_nodes(nBG, S.getGraph())
01508 {
01509 adjEntry ae_nBG;
01510 forall_adj(ae_nBG, nBG)
01511 (*p_adjacencyList)[nBG].pushBack(ae_nBG);
01512 }
01513
01514 NodeArray< List<adjEntry> > adjEntryTreated(S.getGraph());
01515 forall_nodes(nBG, S.getGraph())
01516 {
01517 adjEntry adj;
01518 forall_adj(adj, nBG)
01519 {
01520 if (adjEntryTreated[nBG].search(adj) != -1)
01521 continue;
01522
01523 List<adjEntry> newFace;
01524 adjEntry adj2 = adj;
01525 do
01526 {
01527 newFace.pushBack(adj2);
01528 (*p_ae_to_face)[adj2] = p_faces->size();
01529 adjEntryTreated[adj2->theNode()].pushBack(adj2);
01530 node tn = adj2->twinNode();
01531 int idx = (*p_adjacencyList)[tn].search(adj2->twin());
01532 if (idx - 1 < 0)
01533 idx = (*p_adjacencyList)[tn].size() - 1;
01534 else
01535 idx -= 1;
01536 adj2 = *((*p_adjacencyList)[tn].get(idx));
01537 } while (adj2 != adj);
01538 p_faces->pushBack(newFace);
01539 }
01540 }
01541
01542 p_nDG_to_fPG->init(*p_DG);
01543
01544 for (ListIterator< List<adjEntry> > it = p_faces->begin(); it.valid(); it++)
01545 {
01546 node nn = p_DG->newNode();
01547 (*p_nDG_to_fPG)[nn] = p_fPG_to_nDG->search(*(p_fPG_to_nDG->pushBack(nn)));
01548 }
01549
01550 NodeArray< List<node> > adjFaces(*p_DG);
01551 int i = 0;
01552 for (ListIterator< List<adjEntry> > it = p_faces->begin(); it.valid(); it++)
01553 {
01554 int f1_id = i;
01555 for (ListIterator<adjEntry> it2 = (*it).begin(); it2.valid(); it2++)
01556 {
01557 int f2_id = 0;
01558 int j = 0;
01559 for (ListIterator< List<adjEntry> > it3 = p_faces->begin(); it3.valid(); it3++)
01560 {
01561 bool do_break = false;
01562 for (ListIterator<adjEntry> it4 = (*it3).begin(); it4.valid(); it4++)
01563 {
01564 if ((*it4) == (*it2)->twin())
01565 {
01566 f2_id = j;
01567 do_break = true;
01568 break;
01569 }
01570 }
01571 if (do_break)
01572 break;
01573 j++;
01574 }
01575
01576 if ( f1_id != f2_id
01577 && adjFaces[*(p_fPG_to_nDG->get(f1_id))].search(*(p_fPG_to_nDG->get(f2_id))) == -1
01578 && adjFaces[*(p_fPG_to_nDG->get(f2_id))].search(*(p_fPG_to_nDG->get(f1_id))) == -1)
01579 {
01580 adjFaces[*(p_fPG_to_nDG->get(f1_id))].pushBack(*(p_fPG_to_nDG->get(f2_id)));
01581 edge e1 = p_DG->newEdge(*(p_fPG_to_nDG->get(f1_id)), *(p_fPG_to_nDG->get(f2_id)));
01582 edge e2 = p_DG->newEdge(*(p_fPG_to_nDG->get(f2_id)), *(p_fPG_to_nDG->get(f1_id)));
01583
01584
01585 T e_length = -1;
01586 for (ListIterator<adjEntry> it_f1 = (*it).begin(); it_f1.valid(); it_f1++)
01587 {
01588 edge e = (*it_f1)->theEdge();
01589 for (ListIterator<adjEntry> it_f2 = (*(p_faces->get(f2_id))).begin();
01590 it_f2.valid();
01591 it_f2++)
01592 {
01593 if ((*it_f2)->theEdge() == e)
01594 {
01595 if (e_length == -1 || edgeLength[mu][e] < e_length)
01596 e_length = edgeLength[mu][e];
01597 }
01598 }
01599 }
01600 edgeLengthDG[e1] = e_length;
01601 edgeLengthDG[e2] = e_length;
01602 }
01603
01604 if (*it2 == adjMaxFace)
01605 f_ext_id = f1_id;
01606 if (!(referenceEdge == 0) && *it2 == adjMaxFace->twin())
01607 f_ref_id = f1_id;
01608 }
01609 i++;
01610 }
01611
01612
01613 node f_ext_DG = *(p_fPG_to_nDG->get(f_ext_id));
01614 p_dist_f_ext->init(*p_DG);
01615 sssp(*p_DG, f_ext_DG, edgeLengthDG, *p_dist_f_ext);
01616 if (!(referenceEdge == 0))
01617 {
01618 node f_ref_DG = *(p_fPG_to_nDG->get(f_ref_id));
01619 p_dist_f_ref->init(*p_DG);
01620 sssp(*p_DG, f_ref_DG, edgeLengthDG, *p_dist_f_ref);
01621 }
01622 }
01623
01624
01625 T min1, min2;
01626 T pi_f_0_f_ext = (*p_dist_f_ext)[*(p_fPG_to_nDG->get((*p_ae_to_face)[ae]))];
01627 T pi_f_1_f_ext = (*p_dist_f_ext)[*(p_fPG_to_nDG->get((*p_ae_to_face)[ae->twin()]))];
01628 if (!(referenceEdge == 0))
01629 {
01630 T pi_f_0_f_ref = (*p_dist_f_ref)[*(p_fPG_to_nDG->get((*p_ae_to_face)[ae]))];
01631 T pi_f_1_f_ref = (*p_dist_f_ref)[*(p_fPG_to_nDG->get((*p_ae_to_face)[ae->twin()]))];
01632
01633 if (delta_u + pi_f_0_f_ref < delta_d + pi_f_0_f_ext)
01634 min1 = delta_u + pi_f_0_f_ref;
01635 else
01636 min1 = delta_d + pi_f_0_f_ext;
01637
01638 if (delta_u + pi_f_1_f_ref < delta_d + pi_f_1_f_ext)
01639 min2 = delta_u + pi_f_1_f_ref;
01640 else
01641 min2 = delta_d + pi_f_1_f_ext;
01642
01643 if (min1 > min2)
01644 {
01645 delta_u_nu = delta_u;
01646 if (pi_f_0_f_ref < pi_f_0_f_ext)
01647 delta_u_nu += pi_f_0_f_ref;
01648 else
01649 delta_u_nu += pi_f_0_f_ext;
01650 delta_d_nu = delta_d;
01651 if (pi_f_1_f_ref < pi_f_1_f_ext)
01652 delta_d_nu += pi_f_1_f_ref;
01653 else
01654 delta_d_nu += pi_f_1_f_ext;
01655 }
01656 else
01657 {
01658 frauenlinks = true;
01659 delta_u_nu = delta_u;
01660 if (pi_f_1_f_ref < pi_f_1_f_ext)
01661 delta_u_nu += pi_f_1_f_ref;
01662 else
01663 delta_u_nu += pi_f_1_f_ext;
01664 delta_d_nu = delta_d;
01665 if (pi_f_0_f_ref < pi_f_0_f_ext)
01666 delta_d_nu += pi_f_0_f_ref;
01667 else
01668 delta_d_nu += pi_f_0_f_ext;
01669 }
01670 }
01671 else
01672 {
01673 min1 = delta_d + pi_f_0_f_ext;
01674 min2 = delta_d + pi_f_1_f_ext;
01675
01676 if (min1 > min2)
01677 {
01678 delta_u_nu = delta_u + pi_f_0_f_ext;
01679 delta_d_nu = delta_d + pi_f_1_f_ext;
01680 }
01681 else
01682 {
01683 frauenlinks = true;
01684 delta_u_nu = delta_u + pi_f_1_f_ext;
01685 delta_d_nu = delta_d + pi_f_0_f_ext;
01686 }
01687 }
01688 }
01689
01690 if (frauenlinks)
01691 {
01692 node nu = S.twinTreeNode(ae->theEdge());
01693
01694
01695 NodeArray< List<adjEntry> > tmp_newOrder(spqrTree.originalGraph());
01696 ListIterator<adjEntry> tmp_before;
01697
01698 adjEntryForNode(ae, tmp_before, spqrTree, treeNodeTreated, mu,
01699 v, nodeLength, edgeLength, thickness, tmp_newOrder,
01700 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01701 delta_u_nu, delta_d_nu, adjExternal);
01702
01703
01704
01705 node m_rightNode = ae->twinNode();
01706 node leftOrg = v_original;
01707 node rightOrg = S.original(m_rightNode);
01708 node nOG;
01709 forall_nodes(nOG, spqrTree.originalGraph())
01710 {
01711 List<adjEntry> nOG_tmp_adjList = tmp_newOrder[nOG];
01712 if (nOG_tmp_adjList.size() == 0)
01713 continue;
01714
01715 ListIterator<adjEntry>* m_before;
01716 if (nOG == leftOrg)
01717 m_before = &before;
01718 else
01719 m_before = OGDF_NEW ListIterator<adjEntry>();
01720
01721 for (ListIterator<adjEntry> ae_it = nOG_tmp_adjList.begin(); ae_it.valid(); ae_it++)
01722 {
01723 adjEntry adjaEnt = *ae_it;
01724 if (!m_before->valid())
01725 *m_before = newOrder[nOG].pushBack(adjaEnt);
01726 else
01727 *m_before = newOrder[nOG].insertBefore(adjaEnt, *m_before);
01728
01729 if (nOG == leftOrg || nOG == rightOrg)
01730 {
01731 if (S.original(ae->theEdge()->source()) == nOG)
01732 adjBeforeNodeArraySource[nu] = *m_before;
01733 else
01734 adjBeforeNodeArrayTarget[nu] = *m_before;
01735 }
01736 }
01737
01738 if (nOG != leftOrg)
01739 delete m_before;
01740 }
01741 }
01742 else
01743 adjEntryForNode(ae, before, spqrTree, treeNodeTreated, mu,
01744 v, nodeLength, edgeLength, thickness, newOrder,
01745 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
01746 delta_u_nu, delta_d_nu, adjExternal);
01747
01748 if (!nodeTreated[ae->twinNode()])
01749 {
01750 node orig_ae_twin_theNode = S.original(ae->twinNode());
01751 buffer[ae->theEdge()] = newOrder[orig_ae_twin_theNode];
01752 newOrder[orig_ae_twin_theNode].clear();
01753 }
01754 }
01755 else
01756 {
01757 buffer[ae->theEdge()].reverse();
01758 for (ListIterator<adjEntry> it = buffer[ae->theEdge()].begin(); it.valid(); it++)
01759 {
01760 if (!before.valid())
01761 before = newOrder[v_original].pushFront(*it);
01762 else
01763 before = newOrder[v_original].insertBefore(*it, before);
01764 }
01765 }
01766 }
01767 }
01768
01769 if (DGcomputed)
01770 {
01771 delete p_DG;
01772 delete p_fPG_to_nDG;
01773 delete p_nDG_to_fPG;
01774 delete p_adjacencyList;
01775 delete p_faces;
01776 delete p_dist_f_ext;
01777 delete p_dist_f_ref;
01778 delete p_ae_to_face;
01779 }
01780 }
01781
01782 template<class T>
01783 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::compute(
01784 const Graph& G,
01785 const NodeArray<T>& nodeLength,
01786 const EdgeArray<T>& edgeLength,
01787 StaticSPQRTree& spqrTree,
01788 NodeArray< EdgeArray<T> >& edgeLengthSkel)
01789 {
01790
01791 if (G.empty() || G.numberOfNodes() == 1 || G.numberOfEdges() == 1)
01792 return;
01793
01794
01795
01796 edgeLengthSkel.init(spqrTree.tree());
01797 node v;
01798 forall_nodes(v, spqrTree.tree())
01799 {
01800 edgeLengthSkel[v].init(spqrTree.skeleton(v).getGraph());
01801 edge e;
01802 forall_edges(e, spqrTree.skeleton(v).getGraph())
01803 {
01804 if (spqrTree.skeleton(v).isVirtual(e))
01805 edgeLengthSkel[v][e] = 0;
01806 else
01807 edgeLengthSkel[v][e] = edgeLength[spqrTree.skeleton(v).realEdge(e)];
01808 }
01809 }
01810
01811
01812 bottomUpTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
01813
01814 topDownTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
01815 }
01816
01817 template<class T>
01818 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::computeSize(
01819 const Graph& G,
01820 const NodeArray<T>& nodeLength,
01821 const EdgeArray<T>& edgeLength)
01822 {
01823
01824 if (G.empty())
01825 return 0;
01826 if (G.numberOfNodes() == 1)
01827 return nodeLength[G.chooseNode()];
01828 if (G.numberOfEdges() == 1)
01829 {
01830 edge e = G.chooseEdge();
01831 return edgeLength[e] + nodeLength[e->source()]+ nodeLength[e->target()];
01832 }
01833 StaticSPQRTree spqrTree(G);
01834 NodeArray< EdgeArray<T> > edgeLengthSkel;
01835 return computeSize(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
01836 }
01837
01838 template<class T>
01839 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::computeSize(
01840 const Graph& G,
01841 const NodeArray<T>& nodeLength,
01842 const EdgeArray<T>& edgeLength,
01843 StaticSPQRTree& spqrTree,
01844 NodeArray< EdgeArray<T> >& edgeLengthSkel)
01845 {
01846
01847 if (G.empty())
01848 return 0;
01849 if (G.numberOfNodes() == 1)
01850 return nodeLength[G.chooseNode()];
01851 if (G.numberOfEdges() == 1)
01852 {
01853 edge e = G.chooseEdge();
01854 return edgeLength[e] + nodeLength[e->source()]+ nodeLength[e->target()];
01855 }
01856
01857
01858
01859 edgeLengthSkel.init(spqrTree.tree());
01860 node v;
01861 forall_nodes(v, spqrTree.tree())
01862 {
01863 edgeLengthSkel[v].init(spqrTree.skeleton(v).getGraph());
01864 edge e;
01865 forall_edges(e, spqrTree.skeleton(v).getGraph())
01866 {
01867 if (spqrTree.skeleton(v).isVirtual(e))
01868 edgeLengthSkel[v][e] = 0;
01869 else
01870 edgeLengthSkel[v][e] = edgeLength[spqrTree.skeleton(v).realEdge(e)];
01871 }
01872 }
01873
01874
01875 bottomUpTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
01876
01877 topDownTraversal(spqrTree, spqrTree.rootNode(), nodeLength, edgeLengthSkel);
01878
01879 T biggestFace = -1;
01880 node mu;
01881 forall_nodes(mu, spqrTree.tree())
01882 {
01883
01884 T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
01885 if (sizeMu > biggestFace)
01886 biggestFace = sizeMu;
01887 }
01888
01889 return biggestFace;
01890 }
01891
01892 template<class T>
01893 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::computeSize(
01894 const Graph& G,
01895 const node& n,
01896 const NodeArray<T>& nodeLength,
01897 const EdgeArray<T>& edgeLength)
01898 {
01899
01900 if (G.empty())
01901 return 0;
01902 if (G.numberOfNodes() == 1)
01903 return nodeLength[n];
01904 if (G.numberOfEdges() == 1)
01905 {
01906 edge e = G.chooseEdge();
01907 return edgeLength[e] + nodeLength[e->source()] + nodeLength[e->target()];
01908 }
01909
01910 StaticSPQRTree spqrTree(G);
01911 NodeArray< EdgeArray<T> > edgeLengthSkel;
01912 compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
01913 return computeSize(G, n, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
01914 }
01915
01916 template<class T>
01917 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::computeSize(
01918 const Graph& G,
01919 const node& n,
01920 const NodeArray<T>& nodeLength,
01921 const EdgeArray<T>& edgeLength,
01922 StaticSPQRTree& spqrTree)
01923 {
01924 NodeArray< EdgeArray<T> > edgeLengthSkel;
01925 compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
01926 return computeSize(G, n, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
01927 }
01928
01929 template<class T>
01930 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::computeSize(
01931 const Graph& G,
01932 const node& n,
01933 const NodeArray<T>& nodeLength,
01934 const EdgeArray<T>& edgeLength,
01935 StaticSPQRTree& spqrTree,
01936 const NodeArray< EdgeArray<T> >& edgeLengthSkel)
01937 {
01938
01939 if (G.empty())
01940 return 0;
01941 if (G.numberOfNodes() == 1)
01942 return nodeLength[n];
01943 if (G.numberOfEdges() == 1)
01944 {
01945 edge e = G.chooseEdge();
01946 return edgeLength[e] + nodeLength[e->source()] + nodeLength[e->target()];
01947 }
01948
01949 edge nAdjEdges;
01950 node* mus = new node[n->degree()];
01951 int i = 0;
01952 T biggestFace = -1;
01953 forall_adj_edges(nAdjEdges, n)
01954 {
01955 mus[i] = spqrTree.skeletonOfReal(nAdjEdges).treeNode();
01956 bool alreadySeenMu = false;
01957 for (int j = 0; j < i && !alreadySeenMu; j++)
01958 {
01959 if (mus[i] == mus[j])
01960 alreadySeenMu = true;
01961 }
01962 if (alreadySeenMu)
01963 {
01964 i++;
01965 continue;
01966 }
01967 else
01968 {
01969
01970 T sizeInMu = largestFaceContainingNode(spqrTree, mus[i], n, nodeLength, edgeLengthSkel);
01971 if (sizeInMu > biggestFace)
01972 biggestFace = sizeInMu;
01973
01974 i++;
01975 }
01976 }
01977 delete mus;
01978
01979 return biggestFace;
01980 }
01981
01982 template<class T>
01983 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::bottomUpTraversal(
01984 StaticSPQRTree& spqrTree,
01985 const node& mu,
01986 const NodeArray<T>& nodeLength,
01987 NodeArray< EdgeArray<T> >& edgeLength)
01988 {
01989
01990 edge ed;
01991 forall_adj_edges(ed, mu)
01992 {
01993 if (ed->source() == mu)
01994 bottomUpTraversal(spqrTree, ed->target(), nodeLength, edgeLength);
01995 }
01996
01997 edge e;
01998 forall_edges(e, spqrTree.skeleton(mu).getGraph())
01999 {
02000
02001 if (!spqrTree.skeleton(mu).isVirtual(e) || e == spqrTree.skeleton(mu).referenceEdge())
02002 continue;
02003
02004
02005 node nu = spqrTree.skeleton(mu).twinTreeNode(e);
02006
02007 edge er = spqrTree.skeleton(nu).referenceEdge();
02008
02009 node refEdgeSource = spqrTree.skeleton(nu).referenceEdge()->source();
02010 node origRefEdgeSource = spqrTree.skeleton(nu).original(refEdgeSource);
02011 node refEdgeTarget = spqrTree.skeleton(nu).referenceEdge()->target();
02012 node origRefEdgeTarget = spqrTree.skeleton(nu).original(refEdgeTarget);
02013 T ell = nodeLength[origRefEdgeSource] + nodeLength[origRefEdgeTarget];
02014
02015 if (spqrTree.typeOf(nu) == SPQRTree::SNode)
02016 {
02017
02018 T sizeOfFace = 0;
02019 node nS;
02020 forall_nodes(nS, spqrTree.skeleton(nu).getGraph())
02021 sizeOfFace += nodeLength[spqrTree.skeleton(nu).original(nS)];
02022
02023 edge eS;
02024 forall_edges(eS, spqrTree.skeleton(nu).getGraph())
02025 sizeOfFace += edgeLength[nu][eS];
02026
02027 edgeLength[mu][e] = sizeOfFace - ell;
02028 }
02029 else if (spqrTree.typeOf(nu) == SPQRTree::PNode)
02030 {
02031
02032 edge longestEdge = 0;
02033 forall_edges(ed, spqrTree.skeleton(nu).getGraph())
02034 {
02035 if (!(ed == er) && ( longestEdge == 0
02036 || edgeLength[nu][ed] > edgeLength[nu][longestEdge]))
02037 {
02038 longestEdge = ed;
02039 }
02040 }
02041 edgeLength[mu][e] = edgeLength[nu][longestEdge];
02042 }
02043 else if (spqrTree.typeOf(nu) == SPQRTree::RNode)
02044 {
02045
02046
02047
02048 PlanarModule pm;
02049 pm.planarEmbed(spqrTree.skeleton(nu).getGraph());
02050 CombinatorialEmbedding combinatorialEmbedding(spqrTree.skeleton(nu).getGraph());
02051 T biggestFaceSize = -1;
02052 face f;
02053 forall_faces(f, combinatorialEmbedding)
02054 {
02055 T sizeOfFace = 0;
02056 bool containsEr = false;
02057 adjEntry ae;
02058 forall_face_adj(ae, f)
02059 {
02060 if (ae->theEdge() == er)
02061 containsEr = true;
02062 sizeOfFace += edgeLength[nu][ae->theEdge()]
02063 + nodeLength[spqrTree.skeleton(nu).original(ae->theNode())];
02064 }
02065
02066 if (containsEr && sizeOfFace > biggestFaceSize)
02067 biggestFaceSize = sizeOfFace;
02068 }
02069
02070 edgeLength[mu][e] = biggestFaceSize - ell;
02071 }
02072 else
02073 edgeLength[mu][e] = 1;
02074 }
02075 }
02076
02077 template<class T>
02078 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::topDownTraversal(
02079 StaticSPQRTree& spqrTree,
02080 const node& mu,
02081 const NodeArray<T>& nodeLength,
02082 NodeArray< EdgeArray<T> >& edgeLength)
02083 {
02084
02085 Skeleton& S = spqrTree.skeleton(mu);
02086
02087
02088 edge ed;
02089 forall_adj_edges(ed, mu)
02090 {
02091 if (ed->source() != mu)
02092 continue;
02093
02094 node nu = ed->target();
02095 edge referenceEdgeOfNu = spqrTree.skeleton(nu).referenceEdge();
02096 edge eSnu = spqrTree.skeleton(nu).twinEdge(referenceEdgeOfNu);
02097 if (spqrTree.typeOf(mu) == SPQRTree::SNode)
02098 {
02099
02100
02101
02102 T L = 0;
02103 edge ed2;
02104 forall_edges(ed2, S.getGraph())
02105 L += edgeLength[mu][ed2];
02106 node no;
02107 forall_nodes(no, S.getGraph())
02108 L += nodeLength[S.original(no)];
02109
02110 edgeLength[nu][referenceEdgeOfNu] = L - edgeLength[mu][eSnu]
02111 - nodeLength[S.original(eSnu->source())]
02112 - nodeLength[S.original(eSnu->target())];
02113 }
02114 else if (spqrTree.typeOf(mu) == SPQRTree::PNode)
02115 {
02116
02117
02118 edge ed2;
02119 edge longestEdge = 0;
02120 forall_edges(ed2, S.getGraph())
02121 {
02122 if (ed2 != eSnu && ( longestEdge == 0
02123 || edgeLength[mu][ed2] > edgeLength[mu][longestEdge]))
02124 {
02125 longestEdge = ed2;
02126 }
02127 }
02128 edgeLength[nu][referenceEdgeOfNu] = edgeLength[mu][longestEdge];
02129 }
02130 else if (spqrTree.typeOf(mu) == SPQRTree::RNode)
02131 {
02132
02133
02134
02135
02136
02137
02138 PlanarModule pm;
02139 pm.planarEmbed(S.getGraph());
02140 CombinatorialEmbedding combinatorialEmbedding(S.getGraph());
02141 T biggestFaceSize = -1;
02142 face f;
02143 forall_faces(f, combinatorialEmbedding)
02144 {
02145 T sizeOfFace = 0;
02146 bool containsESnu = false;
02147 adjEntry ae;
02148 forall_face_adj(ae, f)
02149 {
02150 if (ae->theEdge() == eSnu)
02151 containsESnu = true;
02152 sizeOfFace += edgeLength[mu][ae->theEdge()]
02153 + nodeLength[S.original(ae->theNode())];
02154 }
02155 if (containsESnu && sizeOfFace > biggestFaceSize)
02156 biggestFaceSize = sizeOfFace;
02157 }
02158 edgeLength[nu][referenceEdgeOfNu] = biggestFaceSize - edgeLength[mu][eSnu]
02159 - nodeLength[S.original(eSnu->source())]
02160 - nodeLength[S.original(eSnu->target())];
02161 }
02162 else
02163 edgeLength[nu][referenceEdgeOfNu] = 0;
02164
02165
02166 topDownTraversal(spqrTree, ed->target(), nodeLength, edgeLength);
02167 }
02168 }
02169
02170 template<class T>
02171 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::largestFaceContainingNode(
02172 const StaticSPQRTree& spqrTree,
02173 const node& mu,
02174 const node& n,
02175 const NodeArray<T>& nodeLength,
02176 const NodeArray< EdgeArray<T> >& edgeLength)
02177 {
02178 bool containsARealEdge = false;
02179 if (spqrTree.typeOf(mu) == SPQRTree::RNode)
02180 {
02181
02182 PlanarModule pm;
02183 pm.planarEmbed(spqrTree.skeleton(mu).getGraph());
02184 CombinatorialEmbedding combinatorialEmbedding(spqrTree.skeleton(mu).getGraph());
02185 T biggestFaceSize = -1;
02186 face f;
02187 forall_faces(f, combinatorialEmbedding)
02188 {
02189 T sizeOfFace = 0;
02190 bool containingN = false;
02191 bool m_containsARealEdge = false;
02192 adjEntry ae;
02193 forall_face_adj(ae, f)
02194 {
02195 if (spqrTree.skeleton(mu).original(ae->theNode()) == n)
02196 containingN = true;
02197 if (!spqrTree.skeleton(mu).isVirtual(ae->theEdge()))
02198 m_containsARealEdge = true;
02199 sizeOfFace += edgeLength[mu][ae->theEdge()];
02200 sizeOfFace += nodeLength[spqrTree.skeleton(mu).original(ae->theNode())];
02201 }
02202 if (containingN && sizeOfFace > biggestFaceSize)
02203 {
02204 biggestFaceSize = sizeOfFace;
02205 containsARealEdge = m_containsARealEdge;
02206 }
02207 }
02208
02209 if (!containsARealEdge)
02210 return -1;
02211 return biggestFaceSize;
02212 }
02213 else if (spqrTree.typeOf(mu) == SPQRTree::PNode)
02214 {
02215
02216 edge edgeWalker;
02217 edge longestEdges[2] = {0, 0};
02218 forall_edges(edgeWalker, spqrTree.skeleton(mu).getGraph())
02219 {
02220 if ( longestEdges[1] == 0
02221 || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[1]])
02222 {
02223 if ( longestEdges[0] == 0
02224 || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[0]])
02225 {
02226 longestEdges[1] = longestEdges[0];
02227 longestEdges[0] = edgeWalker;
02228 }
02229 else
02230 longestEdges[1] = edgeWalker;
02231 }
02232 }
02233
02234 if ( !spqrTree.skeleton(mu).isVirtual(longestEdges[0])
02235 || !spqrTree.skeleton(mu).isVirtual(longestEdges[1]))
02236 {
02237 containsARealEdge = true;
02238 }
02239
02240 if (!containsARealEdge)
02241 return -1;
02242
02243 return edgeLength[mu][longestEdges[0]] + edgeLength[mu][longestEdges[1]];
02244 }
02245 else if (spqrTree.typeOf(mu) == SPQRTree::SNode)
02246 {
02247
02248 T sizeOfFace = 0;
02249 node nS;
02250 forall_nodes(nS, spqrTree.skeleton(mu).getGraph())
02251 sizeOfFace += nodeLength[spqrTree.skeleton(mu).original(nS)];
02252
02253 edge eS;
02254 forall_edges(eS, spqrTree.skeleton(mu).getGraph())
02255 {
02256 if (!spqrTree.skeleton(mu).isVirtual(eS))
02257 containsARealEdge = true;
02258 sizeOfFace += edgeLength[mu][eS];
02259 }
02260
02261 if (!containsARealEdge)
02262 return -1;
02263
02264 return sizeOfFace;
02265 }
02266
02267
02268 return 42;
02269 }
02270
02271 template<class T>
02272 T EmbedderMaxFaceBiconnectedGraphsLayers<T>::largestFaceInSkeleton
02273 (const StaticSPQRTree& spqrTree,
02274 const node& mu,
02275 const NodeArray<T>& nodeLength,
02276 const NodeArray< EdgeArray<T> >& edgeLength)
02277 {
02278 bool containsARealEdge = false;
02279 if (spqrTree.typeOf(mu) == SPQRTree::RNode)
02280 {
02281
02282 PlanarModule pm;
02283 pm.planarEmbed(spqrTree.skeleton(mu).getGraph());
02284 CombinatorialEmbedding combinatorialEmbedding(spqrTree.skeleton(mu).getGraph());
02285 T biggestFaceSize = -1;
02286 face f;
02287 forall_faces(f, combinatorialEmbedding)
02288 {
02289 bool m_containsARealEdge = false;
02290 T sizeOfFace = 0;
02291 adjEntry ae;
02292 forall_face_adj(ae, f)
02293 {
02294
02295 if (!spqrTree.skeleton(mu).isVirtual(ae->theEdge()))
02296 m_containsARealEdge = true;
02297 sizeOfFace += edgeLength[mu][ae->theEdge()]
02298 + nodeLength[spqrTree.skeleton(mu).original(ae->theNode())];
02299 }
02300
02301 if (sizeOfFace > biggestFaceSize)
02302 {
02303 biggestFaceSize = sizeOfFace;
02304 containsARealEdge = m_containsARealEdge;
02305 }
02306 }
02307
02308 if (!containsARealEdge)
02309 return -1;
02310
02311 return biggestFaceSize;
02312 }
02313 else if (spqrTree.typeOf(mu) == SPQRTree::PNode)
02314 {
02315
02316 edge edgeWalker;
02317 edge longestEdges[2] = {0, 0};
02318 forall_edges(edgeWalker, spqrTree.skeleton(mu).getGraph())
02319 {
02320 if ( longestEdges[1] == 0
02321 || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[1]])
02322 {
02323 if ( longestEdges[0] == 0
02324 || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[0]])
02325 {
02326 longestEdges[1] = longestEdges[0];
02327 longestEdges[0] = edgeWalker;
02328 }
02329 else
02330 longestEdges[1] = edgeWalker;
02331 }
02332 }
02333
02334 if ( !spqrTree.skeleton(mu).isVirtual(longestEdges[0])
02335 || !spqrTree.skeleton(mu).isVirtual(longestEdges[1]))
02336 {
02337 containsARealEdge = true;
02338 }
02339
02340 if (!containsARealEdge)
02341 return -1;
02342
02343 return edgeLength[mu][longestEdges[0]] + edgeLength[mu][longestEdges[1]];
02344 }
02345 else if (spqrTree.typeOf(mu) == SPQRTree::SNode)
02346 {
02347
02348 T sizeOfFace = 0;
02349 node nS;
02350 forall_nodes(nS, spqrTree.skeleton(mu).getGraph())
02351 sizeOfFace += nodeLength[spqrTree.skeleton(mu).original(nS)];
02352
02353 edge eS;
02354 forall_edges(eS, spqrTree.skeleton(mu).getGraph())
02355 {
02356 if (!spqrTree.skeleton(mu).isVirtual(eS))
02357 containsARealEdge = true;
02358 sizeOfFace += edgeLength[mu][eS];
02359 }
02360
02361 if (!containsARealEdge)
02362 return -1;
02363
02364 return sizeOfFace;
02365 }
02366
02367
02368 return 42;
02369 }
02370
02371 template<class T>
02372 void EmbedderMaxFaceBiconnectedGraphsLayers<T>::bottomUpThickness(
02373 const StaticSPQRTree& spqrTree,
02374 const node& mu,
02375 NodeArray<T>& thickness,
02376 const NodeArray<T>& nodeLength,
02377 const NodeArray< EdgeArray<T> >& edgeLength)
02378 {
02379
02380 edge e_mu_to_nu;
02381 forall_adj_edges(e_mu_to_nu, mu)
02382 {
02383 if (e_mu_to_nu->source() != mu)
02384 continue;
02385 else
02386 {
02387 node nu = e_mu_to_nu->target();
02388 bottomUpThickness(spqrTree, nu, thickness, nodeLength, edgeLength);
02389 }
02390 }
02391
02392 Skeleton& S = spqrTree.skeleton(mu);
02393 edge referenceEdge = S.referenceEdge();
02394
02395 if (referenceEdge == 0)
02396 {
02397 thickness[mu] = 0;
02398 return;
02399 }
02400
02401
02402 EdgeArray<T> dLength(S.getGraph());
02403 edge eSG;
02404 forall_edges(eSG, S.getGraph())
02405 {
02406 if (eSG == referenceEdge)
02407 continue;
02408
02409 if (S.isVirtual(eSG))
02410 {
02411 node twinTN = S.twinTreeNode(eSG);
02412 dLength[eSG] = thickness[twinTN];
02413 }
02414 else
02415 dLength[eSG] = edgeLength[mu][eSG];
02416 }
02417
02418
02419 switch (spqrTree.typeOf(mu))
02420 {
02421 case SPQRTree::SNode:
02422 {
02423
02424 T min_dLength = -1;
02425 forall_edges(eSG, S.getGraph())
02426 {
02427 if (eSG == referenceEdge)
02428 continue;
02429 if (min_dLength == -1 || dLength[eSG] < min_dLength)
02430 min_dLength = dLength[eSG];
02431 }
02432 thickness[mu] = min_dLength;
02433 } break;
02434 case SPQRTree::PNode:
02435 {
02436
02437 T sumof_dLength = 0;
02438 forall_edges(eSG, S.getGraph())
02439 {
02440 if (eSG == referenceEdge)
02441 continue;
02442 sumof_dLength += dLength[eSG];
02443 }
02444 thickness[mu] = sumof_dLength;
02445 } break;
02446 case SPQRTree::RNode:
02447 {
02448
02449
02450
02451
02452
02453
02454
02455
02456 CombinatorialEmbedding CE(S.getGraph());
02457 adjEntry ae_f_ext = referenceEdge->adjSource();
02458 adjEntry ae_f_ref = referenceEdge->adjTarget();
02459 T faceSize_f_ext = 0;
02460 adjEntry ae_f_ext_walker = ae_f_ext;
02461 do
02462 {
02463 faceSize_f_ext += nodeLength[S.original(ae_f_ext_walker->theNode())]
02464 + edgeLength[mu][ae_f_ext_walker->theEdge()];
02465 ae_f_ext_walker = ae_f_ext_walker->faceCycleSucc();
02466 } while (ae_f_ext_walker != ae_f_ext);
02467 T faceSize_f_ref = 0;
02468 adjEntry ae_f_ref_walker = ae_f_ref;
02469 do
02470 {
02471 faceSize_f_ref += nodeLength[S.original(ae_f_ref_walker->theNode())]
02472 + edgeLength[mu][ae_f_ref_walker->theEdge()];
02473 ae_f_ref_walker = ae_f_ref_walker->faceCycleSucc();
02474 } while (ae_f_ref_walker != ae_f_ref);
02475 if (faceSize_f_ext < faceSize_f_ref)
02476 {
02477 adjEntry ae_tmp = ae_f_ext;
02478 ae_f_ext = ae_f_ref;
02479 ae_f_ref = ae_tmp;
02480 }
02481
02482
02483 Graph DG;
02484 List<node> fPG_to_nDG;
02485 NodeArray<int> nDG_to_fPG(DG);
02486 NodeArray< List<adjEntry> > adjacencyList(S.getGraph());
02487 List< List<adjEntry> > faces;
02488 NodeArray<int> distances;
02489 EdgeArray<T> edgeLengthDG(DG);
02490 int f_ref_id = -1;
02491 int f_ext_id = -1;
02492
02493 node nBG;
02494 forall_nodes(nBG, S.getGraph())
02495 {
02496 adjEntry ae_nBG;
02497 forall_adj(ae_nBG, nBG)
02498 adjacencyList[nBG].pushBack(ae_nBG);
02499 }
02500
02501 NodeArray< List<adjEntry> > adjEntryTreated(S.getGraph());
02502 forall_nodes(nBG, S.getGraph())
02503 {
02504 adjEntry adj;
02505 forall_adj(adj, nBG)
02506 {
02507 if (adjEntryTreated[nBG].search(adj) != -1)
02508 continue;
02509
02510 List<adjEntry> newFace;
02511 adjEntry adj2 = adj;
02512 do
02513 {
02514 newFace.pushBack(adj2);
02515 adjEntryTreated[adj2->theNode()].pushBack(adj2);
02516 node tn = adj2->twinNode();
02517 int idx = adjacencyList[tn].search(adj2->twin());
02518 if (idx - 1 < 0)
02519 idx = adjacencyList[tn].size() - 1;
02520 else
02521 idx -= 1;
02522 adj2 = *(adjacencyList[tn].get(idx));
02523 } while (adj2 != adj);
02524 faces.pushBack(newFace);
02525 }
02526 }
02527
02528 for (ListIterator< List<adjEntry> > it = faces.begin(); it.valid(); it++)
02529 {
02530 node nn = DG.newNode();
02531 nDG_to_fPG[nn] = fPG_to_nDG.search(*(fPG_to_nDG.pushBack(nn)));
02532 }
02533
02534 NodeArray< List<node> > adjFaces(DG);
02535 int i = 0;
02536 for (ListIterator< List<adjEntry> > it = faces.begin(); it.valid(); it++)
02537 {
02538 int f1_id = i;
02539 for (ListIterator<adjEntry> it2 = (*it).begin(); it2.valid(); it2++)
02540 {
02541 int f2_id = 0;
02542 int j = 0;
02543 for (ListIterator< List<adjEntry> > it3 = faces.begin(); it3.valid(); it3++)
02544 {
02545 bool do_break = false;
02546 for (ListIterator<adjEntry> it4 = (*it3).begin(); it4.valid(); it4++)
02547 {
02548 if ((*it4) == (*it2)->twin())
02549 {
02550 f2_id = j;
02551 do_break = true;
02552 break;
02553 }
02554 }
02555 if (do_break)
02556 break;
02557 j++;
02558 }
02559
02560 if ( f1_id != f2_id
02561 && adjFaces[*(fPG_to_nDG.get(f1_id))].search(*(fPG_to_nDG.get(f2_id))) == -1
02562 && adjFaces[*(fPG_to_nDG.get(f2_id))].search(*(fPG_to_nDG.get(f1_id))) == -1)
02563 {
02564 adjFaces[*(fPG_to_nDG.get(f1_id))].pushBack(*(fPG_to_nDG.get(f2_id)));
02565 adjFaces[*(fPG_to_nDG.get(f2_id))].pushBack(*(fPG_to_nDG.get(f1_id)));
02566 edge e1 = DG.newEdge(*(fPG_to_nDG.get(f1_id)), *(fPG_to_nDG.get(f2_id)));
02567 edge e2 = DG.newEdge(*(fPG_to_nDG.get(f2_id)), *(fPG_to_nDG.get(f1_id)));
02568
02569
02570 T e_length = -1;
02571 for (ListIterator<adjEntry> it_f1 = (*it).begin(); it_f1.valid(); it_f1++)
02572 {
02573 edge e = (*it_f1)->theEdge();
02574 for (ListIterator<adjEntry> it_f2 = (*(faces.get(f2_id))).begin();
02575 it_f2.valid();
02576 it_f2++)
02577 {
02578 if ((*it_f2)->theEdge() == e)
02579 {
02580 if (e_length == -1 || edgeLength[mu][e] < e_length)
02581 e_length = edgeLength[mu][e];
02582 }
02583 }
02584 }
02585 edgeLengthDG[e1] = e_length;
02586 edgeLengthDG[e2] = e_length;
02587 }
02588
02589 if (*it2 == ae_f_ext)
02590 f_ext_id = f1_id;
02591 if (*it2 == ae_f_ref)
02592 f_ref_id = f1_id;
02593 }
02594 i++;
02595 }
02596
02597
02598 node nDG_f_ref = *(fPG_to_nDG.get(f_ref_id));
02599 List<node>& f_ref_adj_faces = adjFaces[nDG_f_ref];
02600
02601
02602 DG.delNode(*(fPG_to_nDG.get(f_ref_id)));
02603
02604
02605 NodeArray<T> dist(DG);
02606 node nDG_f_ext = *(fPG_to_nDG.get(f_ext_id));
02607 sssp(DG, nDG_f_ext, edgeLengthDG, dist);
02608 T minDist = -1;
02609 for (ListIterator<node> it_adj_faces = f_ref_adj_faces.begin();
02610 it_adj_faces.valid();
02611 it_adj_faces++)
02612 {
02613 node fDG = *it_adj_faces;
02614 if (fDG != nDG_f_ext)
02615 {
02616 T d = dist[fDG];
02617 if (minDist == -1 || d < minDist)
02618 minDist = d;
02619 }
02620 }
02621 thickness[mu] = minDist + 1;
02622 } break;
02623 OGDF_NODEFAULT
02624 }
02625 }
02626
02627 template<class T>
02628 bool EmbedderMaxFaceBiconnectedGraphsLayers<T>::sssp(
02629 const Graph& G,
02630 const node& s,
02631 const EdgeArray<T>& length,
02632 NodeArray<T>& d)
02633 {
02634 const T infinity = 20000000;
02635
02636
02637 d.init(G);
02638 node v;
02639 edge e;
02640 forall_nodes (v, G)
02641 d[v] = infinity;
02642
02643 d[s] = 0;
02644 for (int i = 1; i < G.numberOfNodes(); ++i)
02645 {
02646 forall_edges (e, G)
02647 {
02648
02649 if (d[e->target()] > d[e->source()] + length[e])
02650 d[e->target()] = d[e->source()] + length[e];
02651 }
02652 }
02653
02654
02655 forall_edges (e, G)
02656 {
02657 if (d[e->target()] > d[e->source()] + length[e])
02658 return false;
02659 }
02660
02661 return true;
02662 }
02663
02664
02665 }
02666
02667 #endif