_planar.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:17k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _planar.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/stack.h>
  12. #include <LEDA/graph.h>
  13. #include <LEDA/graph_alg.h>
  14. static void dfs_in_make_biconnected_graph(graph & G, node v, 
  15.   list<edge>& new_edges, int &dfs_count,
  16.   node_array < bool > &reached,
  17.   node_array < int >&dfsnum, node_array < int >&lowpt,
  18.   node_array < node > &parent);
  19. const int left = 1;
  20. const int right = 2;
  21. static void dfs_in_reorder(list < edge > &Del, node v, int &dfs_count,
  22.   node_array < bool > &reached,
  23.   node_array < int >&dfsnum,
  24.   node_array < int >&lowpt1, node_array < int >&lowpt2,
  25.   node_array < node > &parent);
  26. class block
  27. {
  28.   private:
  29.   list < int >Latt, Ratt; /* list of attachments */
  30.    list < edge > Lseg, Rseg; /* list of segments represented by their *
  31.  * defining edges */
  32.    public:
  33.    block(edge e, list < int >&A) {
  34.     Lseg.append(e);
  35.     Latt.conc(A);
  36. /* the other two lists are empty */
  37.   } ~block() {
  38.   }
  39.   void flip() {
  40.     list < int >ha;
  41.      list < edge > he;
  42. /* we first interchange |Latt| and |Ratt| and then |Lseg| and |Rseg| */
  43.      ha.conc(Ratt);
  44.      Ratt.conc(Latt);
  45.      Latt.conc(ha);
  46.      he.conc(Rseg);
  47.      Rseg.conc(Lseg);
  48.      Lseg.conc(he);
  49.   } int head_of_Latt() {
  50.     return Latt.head();
  51.   }
  52.   bool empty_Latt() {
  53.     return Latt.empty();
  54.   }
  55.   int head_of_Ratt() {
  56.     return Ratt.head();
  57.   }
  58.   bool empty_Ratt() {
  59.     return Ratt.empty();
  60.   }
  61.   bool left_interlace(stack < block * >&S) {
  62. /* check for interlacing with the left side of the topmost block of
  63.  * |S| */
  64.     if (Latt.empty())
  65.       error_handler(1, "Latt is never empty");
  66.     if (!S.empty() && !((S.top())->empty_Latt()) &&
  67.       Latt.tail() < (S.top())->head_of_Latt())
  68.       return true;
  69.     else
  70.       return false;
  71.   }
  72.   bool right_interlace(stack < block * >&S) {
  73. /* check for interlacing with the right side of the topmost block of
  74.  * |S| */
  75.     if (Latt.empty())
  76.       error_handler(1, "Latt is never empty");
  77.     if (!S.empty() && !((S.top())->empty_Ratt()) &&
  78.       Latt.tail() < (S.top())->head_of_Ratt())
  79.       return true;
  80.     else
  81.       return false;
  82.   }
  83.   void combine(block * Bprime) {
  84. /* add block Bprime to the rear of |this| block */
  85.     Latt.conc(Bprime->Latt);
  86.     Ratt.conc(Bprime->Ratt);
  87.     Lseg.conc(Bprime->Lseg);
  88.     Rseg.conc(Bprime->Rseg);
  89.     delete(Bprime);
  90.   } bool clean(int dfsnum_w, edge_array < int >&alpha) {
  91. /* remove all attachments to |w|; there may be several */
  92.     while (!Latt.empty() && Latt.head() == dfsnum_w)
  93.       Latt.pop();
  94.     while (!Ratt.empty() && Ratt.head() == dfsnum_w)
  95.       Ratt.pop();
  96.     if (!Latt.empty() || !Ratt.empty())
  97.       return false;
  98. /*|Latt| and |Ratt| are empty; we record the placement of the subsegments
  99.  * in |alpha|. */
  100.     edge e;
  101.      forall(e, Lseg) alpha[e] = left;
  102.      forall(e, Rseg) alpha[e] = right;
  103.      return true;
  104.   }
  105.   void add_to_Att(list < int >&Att, int dfsnum_w0, edge_array < int >&alpha) {
  106. /* add the block to the rear of |Att|. Flip if necessary */
  107.     if (!Ratt.empty() && head_of_Ratt() > dfsnum_w0)
  108.       flip();
  109.     Att.conc(Latt);
  110.     Att.conc(Ratt);
  111. /* This needs some explanation. Note that |Ratt| is either empty
  112.  * or ${w0}$. Also if |Ratt| is non-empty then all subsequent sets are contained
  113.  * in ${w0}$. So we indeed compute an ordered set of attachments. */
  114.     edge e;
  115.      forall(e, Lseg) alpha[e] = left;
  116.      forall(e, Rseg) alpha[e] = right;
  117.   }
  118. };
  119. list<edge> make_biconnected_graph(graph & G)
  120. {
  121.   node v;
  122.   node_array < bool > reached(G, false);
  123.   list<edge> new_edges;
  124.   node u = G.first_node();
  125.   forall_nodes(v, G) {
  126.     if (!reached[v]) { /* explore the connected component with root
  127.  * * |v| */
  128.       DFS(G, v, reached);
  129.       if (u != v) { /* link |v|'s component to the first *
  130.  * component */
  131. new_edges.append(G.new_edge(u,v));
  132. new_edges.append(G.new_edge(v,u));
  133.       } /* end if */
  134.     } /* end not reached */
  135.   } /* end forall */
  136. /* |G| is now connected. We next make it biconnected. */
  137.   forall_nodes(v, G) reached[v] = false;
  138.   node_array < int >dfsnum(G);
  139.   node_array < node > parent(G, nil);
  140.   int dfs_count = 0;
  141.   node_array < int >lowpt(G);
  142.   dfs_in_make_biconnected_graph(G, G.first_node(), new_edges,dfs_count, reached, dfsnum, lowpt, parent);
  143.   return new_edges;
  144. } /* end |make_biconnected_graph| */
  145. static void dfs_in_make_biconnected_graph(graph & G, node v, 
  146.   list<edge>& new_edges, int &dfs_count,
  147.   node_array < bool > &reached,
  148.   node_array < int >&dfsnum, node_array < int >&lowpt,
  149.   node_array < node > &parent)
  150. {
  151.   node w;
  152.   edge e;
  153.   dfsnum[v] = dfs_count++;
  154.   lowpt[v] = dfsnum[v];
  155.   reached[v] = true;
  156.   if (!G.first_adj_edge(v))
  157.     return; /* no children */
  158.   node u = target(G.first_adj_edge(v)); /* first child */
  159.   forall_adj_edges(e, v) {
  160.     w = target(e);
  161.     if (!reached[w]) { /* e is a tree edge */
  162.       parent[w] = v;
  163.       dfs_in_make_biconnected_graph(G, w, new_edges, dfs_count, reached, dfsnum, lowpt, parent);
  164.       if (lowpt[w] == dfsnum[v]) { /* |v| is an articulation point. We * 
  165.  * now add an edge. If |w| is the *
  166.  * first child and |v| has a parent * 
  167.  * then we connect |w| and *
  168.  * |parent[v]|, if |w| is a first *
  169.  * child and |v| has no parent then * 
  170.  * we do nothing. If |w| is not the * 
  171.  * first child then we connect |w| to 
  172.  * 
  173.  * * the first child. The net effect
  174.  * of  * all of this is to link all * 
  175.  * children of an articulation point
  176.  * * to the first child and the first
  177.  * * child to the parent (if it
  178.  * exists)  */
  179. if (w == u && parent[v]) {
  180.   new_edges.append(G.new_edge(w, parent[v]));
  181.   new_edges.append(G.new_edge(parent[v], w));
  182. }
  183. if (w != u) {
  184.   new_edges.append(G.new_edge(u,w));
  185.   new_edges.append(G.new_edge(w,u));
  186. }
  187.       } /* end if lowpt = dfsnum */
  188.       lowpt[v] = Min(lowpt[v], lowpt[w]);
  189.     } /* end tree edge */
  190.     else
  191.       lowpt[v] = Min(lowpt[v], dfsnum[w]); /* non tree edge */
  192.   } /* end forall */
  193. } /* end dfs */
  194. static void reorder(graph & G, node_array < int >&dfsnum,
  195.   node_array < node > &parent)
  196. {
  197.   node v;
  198.   node_array < bool > reached(G, false);
  199.   int dfs_count = 0;
  200.   list < edge > Del;
  201.   node_array < int >lowpt1(G), lowpt2(G);
  202.   dfs_in_reorder(Del, G.first_node(), dfs_count, reached, dfsnum, lowpt1, lowpt2, parent);
  203. /* remove forward and reversals of tree edges */
  204.   edge e;
  205.   forall(e, Del) G.del_edge(e);
  206. /* we now reorder adjacency lists as described in cite[page 101]{Me:book} */
  207.   node w;
  208.   edge_array<int> cost(G);
  209.   forall_edges(e, G) {
  210.     v = source(e);
  211.     w = target(e);
  212.     cost[e] = ((dfsnum[w] < dfsnum[v]) ?
  213.       2 * dfsnum[w] :
  214.       ((lowpt2[w] >= dfsnum[v]) ?
  215. 2 * lowpt1[w] : 2 * lowpt1[w] + 1));
  216.   }
  217.   G.sort_edges(cost);
  218. }
  219. static void dfs_in_reorder(list < edge > &Del, node v, int &dfs_count,
  220.   node_array < bool > &reached,
  221.   node_array < int >&dfsnum,
  222.   node_array < int >&lowpt1, node_array < int >&lowpt2,
  223.   node_array < node > &parent)
  224. {
  225.   node w;
  226.   edge e;
  227.   dfsnum[v] = dfs_count++;
  228.   lowpt1[v] = lowpt2[v] = dfsnum[v];
  229.   reached[v] = true;
  230.   forall_adj_edges(e, v) {
  231.     w = target(e);
  232.     if (!reached[w]) { /* e is a tree edge */
  233.       parent[w] = v;
  234.       dfs_in_reorder(Del, w, dfs_count, reached, dfsnum, lowpt1, lowpt2,
  235. parent);
  236.       lowpt1[v] = Min(lowpt1[v], lowpt1[w]);
  237.     } /* end tree edge */
  238.     else {
  239.       lowpt1[v] = Min(lowpt1[v], dfsnum[w]); /* no effect for forward *
  240.  * edges */
  241.       if ((dfsnum[w] >= dfsnum[v]) || w == parent[v])
  242. /* forward edge or reversal of tree edge */
  243. Del.append(e);
  244.     } /* end non-tree edge */
  245.   } /* end forall */
  246. /* we know |lowpt1[v]| at this point and now make a second pass over all
  247.  * adjacent edges of |v| to compute |lowpt2| */
  248.   {
  249.     forall_adj_edges(e, v) {
  250.       w = target(e);
  251.       if (parent[w] == v) { /* tree edge */
  252. if (lowpt1[w] != lowpt1[v])
  253.   lowpt2[v] = Min(lowpt2[v], lowpt1[w]);
  254. lowpt2[v] = Min(lowpt2[v], lowpt2[w]);
  255.       } /* end tree edge */
  256.       else
  257.       /* all other edges */ if (lowpt1[v] != dfsnum[w])
  258. lowpt2[v] = Min(lowpt2[v], dfsnum[w]);
  259.     } /* end forall */
  260.   }
  261. } /* end dfs */
  262. static bool strongly_planar(edge e0, graph & G, list < int >&Att,
  263.   edge_array < int >&alpha,
  264.   node_array < int >&dfsnum,
  265.   node_array < node > &parent)
  266. {
  267.   node x = source(e0);
  268.   node y = target(e0);
  269.   edge e = G.first_adj_edge(y);
  270.   node wk = y;
  271.   while (dfsnum[target(e)] > dfsnum[wk]) { /* e is a tree edge */
  272.     wk = target(e);
  273.     e = G.first_adj_edge(wk);
  274.   }
  275.   node w0 = target(e);
  276.   node w = wk;
  277.   stack < block * >S;
  278.   while (w != x) {
  279.     int count = 0;
  280.     forall_adj_edges(e, w) {
  281.       count++;
  282.       if (count != 1) { /* no action for first edge */
  283. list < int >A;
  284. if (dfsnum[w] < dfsnum[target(e)]) { /* tree edge */
  285.   if (!strongly_planar(e, G, A, alpha, dfsnum, parent)) {
  286.     while (!S.empty())
  287.       delete(S.pop());
  288.     return false;
  289.   }
  290. }
  291. else
  292.   A.append(dfsnum[target(e)]); /* a back edge */
  293. block *B = new block(e, A);
  294. while (true) {
  295.   if (B->left_interlace(S))
  296.     (S.top())->flip();
  297.   if (B->left_interlace(S)) {
  298.     delete(B);
  299.     while (!S.empty())
  300.       delete(S.pop());
  301.     return false;
  302.   };
  303.   if (B->right_interlace(S))
  304.     B->combine(S.pop());
  305.   else
  306.     break;
  307. } /* end while */
  308. S.push(B);
  309.       } /* end if */
  310.     } /* end forall */
  311.     while (!S.empty() && (S.top())->clean(dfsnum[parent[w]], alpha))
  312.       delete(S.pop());
  313.     w = parent[w];
  314.   } /* end while */
  315.   Att.clear();
  316.   while (!S.empty()) {
  317.     block *B = S.pop();
  318.     if (!(B->empty_Latt()) && !(B->empty_Ratt()) &&
  319.       (B->head_of_Latt() > dfsnum[w0]) && (B->head_of_Ratt() > dfsnum[w0])) {
  320.       delete(B);
  321.       while (!S.empty())
  322. delete(S.pop());
  323.       return false;
  324.     }
  325.     B->add_to_Att(Att, dfsnum[w0], alpha);
  326.     delete(B);
  327.   } /* end while */
  328. /* Let's not forget (as the book does) that $w0$ is an attachment of $S(e0)$
  329.  * except if $w0 = x$. */
  330.   if (w0 != x)
  331.     Att.append(dfsnum[w0]);
  332.   return true;
  333. }
  334. static void embedding(edge e0, int t, GRAPH < node, edge > &G,
  335.   edge_array < int >&alpha,
  336.   node_array < int >&dfsnum,
  337.   list < edge > &T, list < edge > &A, int &cur_nr,
  338.   edge_array < int >&sort_num, node_array < edge > &tree_edge_into,
  339.   node_array < node > &parent, edge_array < edge > &reversal)
  340. {
  341.   node x = source(e0);
  342.   node y = target(e0);
  343.   tree_edge_into[y] = e0;
  344.   edge e = G.first_adj_edge(y);
  345.   node wk = y;
  346.   while (dfsnum[target(e)] > dfsnum[wk]) { /* e is a tree edge */
  347.     wk = target(e);
  348.     tree_edge_into[wk] = e;
  349.     e = G.first_adj_edge(wk);
  350.   }
  351.   node w0 = target(e);
  352.   edge back_edge_into_w0 = e;
  353.   node w = wk;
  354.   list < edge > Al, Ar;
  355.   list < edge > Tprime, Aprime;
  356.   T.clear();
  357.   T.append(G[e]); /* |e = (wk,w0)| at this point, line (2) */
  358.   while (w != x) {
  359.     int count = 0;
  360.     forall_adj_edges(e, w) {
  361.       count++;
  362.       if (count != 1) { /* no action for first edge */
  363. if (dfsnum[w] < dfsnum[target(e)]) { /* tree edge */
  364.   int tprime = ((t == alpha[e]) ? left : right);
  365.   embedding(e, tprime, G, alpha, dfsnum, Tprime, Aprime, cur_nr, sort_num, tree_edge_into, parent, reversal);
  366. }
  367. else { /* back edge */
  368.   Tprime.append(G[e]); /* $e$ */
  369.   Aprime.append(reversal[G[e]]); /* reversal of $e$ */
  370. }
  371. if (t == alpha[e]) {
  372.   Tprime.conc(T);
  373.   T.conc(Tprime); /* $T = Tprime conc T$ */
  374.   Al.conc(Aprime); /* $Al = Al conc Aprime$ */
  375. }
  376. else {
  377.   T.conc(Tprime); /* $ T = T conc Tprime $ */
  378.   Aprime.conc(Ar);
  379.   Ar.conc(Aprime); /* $ Ar = Aprime conc Ar$ */
  380. }
  381.       } /* end if */
  382.     } /* end forall */
  383.     T.append(reversal[G[tree_edge_into[w]]]); /* $(w_{j-1},w_j)$ */
  384.     forall(e, T) sort_num[e] = cur_nr++;
  385. /* |w|'s adjacency list is now computed; we clear |T| and prepare for the
  386.  * next iteration by moving all darts incident to |parent[w]| from |Al| and
  387.  * |Ar| to |T|. These darts are at the rear end of |Al| and at the front end
  388.  * of |Ar| */
  389.     T.clear();
  390.     while (!Al.empty() && source(Al.tail()) == G[parent[w]])
  391. /* |parent[w]| is in |G|, |Al.tail| in |H| */
  392.     {
  393.       T.push(Al.Pop()); /* Pop removes from the rear */
  394.     }
  395.     T.append(G[tree_edge_into[w]]); /* push would be equivalent */
  396.     while (!Ar.empty() && source(Ar.head()) == G[parent[w]]) { /* */
  397.       T.append(Ar.pop()); /* pop removes from the front */
  398.     }
  399.     w = parent[w];
  400.   } /* end while */
  401.   A.clear();
  402.   A.conc(Ar);
  403.   A.append(reversal[G[back_edge_into_w0]]);
  404.   A.conc(Al);
  405. }
  406. bool PLANAR(graph & Gin, bool embed)
  407. /* |Gin| is a directed graph. |planar| decides whether |Gin| is planar.
  408.  * If it is and |embed == true| then it also computes a
  409.  * combinatorial embedding of |Gin| by suitably reordering
  410.  * its adjacency lists.
  411.  * |Gin| must be bidirected in that case. */
  412. {
  413.   int n = Gin.number_of_nodes();
  414.   if (n <= 3)
  415.     return true;
  416.   if (Gin.number_of_edges() > 6 * n - 12)
  417.     return false;
  418. /* An undirected planar graph has at most $3n-6$ edges; a directed graph may
  419.  * have twice as many */
  420.   GRAPH < node, edge > G;
  421.   edge_array < edge > companion_in_G(Gin);
  422.   node_array < node > link(Gin);
  423.   bool Gin_is_bidirected = true;
  424.   {
  425.     node v;
  426.     forall_nodes(v, Gin) link[v] = G.new_node(v); /* bidirectional *
  427.  * links */
  428.     edge e;
  429.     forall_edges(e, Gin) companion_in_G[e] =
  430.       G.new_edge(link[source(e)], link[target(e)], e);
  431.   }
  432.   {
  433.     node_array < int >nr(G);
  434.     edge_array < int >cost(G);
  435.     int cur_nr = 0;
  436.     int n = G.number_of_nodes();
  437.     node v;
  438.     edge e;
  439.     forall_nodes(v, G) nr[v] = cur_nr++;
  440.     forall_edges(e, G) cost[e] = ((nr[source(e)] < nr[target(e)]) ?
  441.       n * nr[source(e)] + nr[target(e)] :
  442.       n * nr[target(e)] + nr[source(e)]);
  443.     G.sort_edges(cost);
  444.     list < edge > L = G.all_edges();
  445.     while (!L.empty()) {
  446.       e = L.pop();
  447. /* check whether the first edge on |L| is equal to the reversal of |e|. If so,
  448.  * delete it from |L|, if not, add the reversal to |G| */
  449.       if (!L.empty() && (source(e) == target(L.head())) && (source(L.head()) == target(e)))
  450. L.pop();
  451.       else {
  452. G.new_edge(target(e), source(e));
  453. Gin_is_bidirected = false;
  454.       }
  455.     }
  456.   }
  457.   make_biconnected_graph(G);
  458.   GRAPH < node, edge > H;
  459.   edge_array < edge > companion_in_H(Gin);
  460.   {
  461.     node v;
  462.     forall_nodes(v, G) G.assign(v, H.new_node(v));
  463.     edge e;
  464.     forall_edges(e, G) G.assign(e, H.new_edge(G[source(e)], G[target(e)], e));
  465.     edge ein;
  466.     forall_edges(ein, Gin) companion_in_H[ein] = G[companion_in_G[ein]];
  467.   }
  468.   edge_array < edge > reversal(H);
  469.   if (!compute_correspondence(H, reversal)) 
  470.      error_handler(1,"graph not bidirected");
  471.   node_array < int >dfsnum(G);
  472.   node_array < node > parent(G, nil);
  473.   reorder(G, dfsnum, parent);
  474.   edge_array < int >alpha(G, 0);
  475.   {
  476.     list < int >Att;
  477.     alpha[G.first_adj_edge(G.first_node())] = left;
  478.     if (!strongly_planar(G.first_adj_edge(G.first_node()), G, Att, alpha, dfsnum, parent))
  479.       return false;
  480.   }
  481.   if (embed) {
  482.     if (Gin_is_bidirected) {
  483.       list < edge > T, A; /* lists of edges of |H| */
  484.       int cur_nr = 0;
  485.       edge_array < int >sort_num(H);
  486.       node_array < edge > tree_edge_into(G);
  487.       embedding(G.first_adj_edge(G.first_node()), left, G, alpha, dfsnum, T, A,
  488. cur_nr, sort_num, tree_edge_into, parent, reversal);
  489. /* |T| contains all edges incident to the first node except the cycle edge into it.
  490.  * That edge comprises |A| */
  491.       T.conc(A);
  492.       edge e;
  493.       forall(e, T) sort_num[e] = cur_nr++;
  494.       edge_array < int >sort_Gin(Gin);
  495.       {
  496. edge ein;
  497. forall_edges(ein, Gin) sort_Gin[ein] = sort_num[companion_in_H[ein]];
  498.       }
  499.       Gin.sort_edges(sort_Gin);
  500.     }
  501.     else
  502.       error_handler(2, "sorry: can only embed bidirected graphs");
  503.   }
  504.   return true;
  505. }
  506. bool PLANAR(graph & G, list < edge > &P, bool embed)
  507. {
  508.   if (PLANAR(G, embed)) return true;
  509. /* We work on a copy |H| of |G| since the procedure alters |G|; we link every
  510.  * vertex and edge of |H| with its original. For the vertices we also have the
  511.  * reverse links. */
  512.   GRAPH < node, edge > H;
  513.   node_array < node > link(G);
  514.   node v;
  515.   forall_nodes(v, G) link[v] = H.new_node(v);
  516. /* This requires some explanation. |H.new_node(v)| adds a new node to
  517.  * |H|, returns the new node, and makes |v| the information associated
  518.  * with the new node. So the statement creates a copy of |v| and
  519.  * bidirectionally links it with |v| */
  520.   int N = G.number_of_nodes();
  521.   edge e;
  522.   forall_edges(e,G)
  523.   if (G.source(e) != G.target(e))
  524.   { H.new_edge(link[G.source(e)], link[G.target(e)], e);
  525.     if (--N < 1 && !PLANAR(H)) break;
  526.    }
  527. /* |link[source(e)]| and |link[target(e)]| are the copies of |source(e)|
  528.  * and |target(e)| in |H|. The operation |H.new_edge| creates a new edge
  529.  * with these endpoints, returns it, and makes |e| the information of that
  530.  * edge. So the effect of the loop is to make the edge set of |H| a copy
  531.  * of the edge set of |G| and to let every edge of |H| know its original.
  532.  * We can now determine a minimal non-planar subgraph of |H| */
  533.   list<edge> L = H.all_edges();
  534.   edge eh;
  535.   forall(eh, L) {
  536.     e = H[eh]; /* the edge in |G| corresponding to |eh| */
  537.     node x = G.source(eh);
  538.     node y = G.target(eh);
  539.     H.del_edge(eh);
  540.     if (PLANAR(H))
  541.       H.new_edge(x, y, e); /* put a new version of |eh| back in and *
  542.  * establish the correspondence */
  543.   }
  544. /* |H| is now a homeomorph of either $K_5$ or $K_{3,3}$. We still need
  545.  * to translate back to |G|. */
  546.   P.clear();
  547.   forall_edges(eh, H) P.append(H[eh]);
  548.   return false;
  549. }