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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _schnyder.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/graph_alg.h>
  12. static void compute_labelling(const graph&G, node a, node b, node c, 
  13.                               list<node>& L)
  14. {
  15.    node_array<bool> marked(G,false);  // marked[v] == true iff v adjacent to a
  16.    node_array<int>  deg(G,0);         // deg[v] = # nodes adjacent to a and v
  17.    list<node> cand;    // candidate list:  marked nodes  with deg <= 2
  18.    int N = G.number_of_nodes();
  19.    L.clear();
  20.    marked[a] = true;
  21.    marked[b] = true;
  22.    marked[c] = true;
  23.    deg[a] = N;
  24.    deg[b] = N;
  25.    deg[c] = N;
  26.    
  27.    node v,w;
  28.    forall_adj_nodes(v,a)
  29.    { marked[v] = true;
  30.      forall_adj_nodes(w,v) deg[w]++;
  31.     }
  32.    { forall_adj_nodes(v,a)
  33.         if (deg[v] <= 2) cand.append(v);
  34.     }
  35.    while (!cand.empty())
  36.    { node u = cand.pop();
  37.      if (deg[u] > 2) continue;
  38.      L.push(u);
  39.      deg[u] = N;
  40.      forall_adj_nodes(v,u)
  41.      { deg[v]--;
  42.        if (!marked[v])  // v is new neighbor of a
  43.        { marked[v] = true;
  44.          if (deg[v] <= 2) cand.append(v);
  45.          forall_adj_nodes(w,v) deg[w]++;
  46.         }
  47.        else            // v has been adjacent to a before
  48.          if (deg[v] == 2) cand.append(v);
  49.       }
  50.     }
  51. }
  52. static void compute_realizer(const graph& G, node a, node b, node c,
  53.                              list<node>& L, 
  54.                              GRAPH<node,int>& T, node_array<node>& n)
  55. { node v;
  56.   edge e,e_1,e_r;
  57.   node_array<int> ord(G,0); 
  58.   
  59.   forall_nodes(v,G) n[v] = T.new_node(v);
  60.    ord[b] = 0;
  61.    ord[c] = 1;
  62.    int i = 2;
  63.    forall(v,L) ord[v] = i++;
  64.    ord[a] = i;
  65.   forall(v,L)
  66.   { node vt = n[v];
  67.     forall_adj_edges(e,v)
  68.     { if (target(e) == a) T.new_edge(n[a],vt,1);
  69.       if (ord[target(e)] > ord[v]) e_1 = e_r = e;
  70.      }
  71.     while (ord[target(e_1)] > ord[v]) e_1 = G.cyclic_adj_succ(e_1);
  72.     while (ord[target(e_r)] > ord[v]) e_r = G.cyclic_adj_pred(e_r);
  73.     T.new_edge(n[target(e_1)],vt,2);
  74.     T.new_edge(n[target(e_r)],vt,3);
  75.     for(e=G.cyclic_adj_succ(e_1); e != e_r; e = G.cyclic_adj_succ(e))
  76.        T.new_edge(vt,n[target(e)],1);
  77.    }
  78. }
  79. static void compute_subtree_sizes(const GRAPH<node,int>& T, int i, node r, 
  80.                                   node_array<int>& s)
  81.   // computes the size s[w] of all subtrees rooted at some node w in the
  82.   // the subtree of $T_i$ rooted at node v
  83.   int sum = 0;
  84.   edge e;
  85.   forall_adj_edges(e,r)
  86.     if (T[e] == i)
  87.     { node w = target(e);
  88.       compute_subtree_sizes(T,i,w,s);
  89.       sum += s[w];
  90.      }
  91.    s[r] = sum + 1;
  92. }
  93. void tree_prefix_sum(const GRAPH<node,int>& T, int i, node r, 
  94.                      const node_array<int>& val,
  95.                      node_array<int>& sum)
  96. {
  97.   // computes for every node $w$ in the subtree of $T_i$ rooted at node $r$
  98.   // sum[w] = $sum_{vin P_i(w)} val[v]$, where $P_i$ is the path from $w$
  99.   // to $r$ in $T_i$.
  100.   list<node> Q(r);
  101.   sum[r] = val[r];
  102.   while (!Q.empty())
  103.   { node v = Q.pop();
  104.     edge e;
  105.     forall_adj_edges(e,v)
  106.       if (T[e] == i)
  107.       { node w = target(e);
  108.         Q.append(w);
  109.         sum[w] = sum[v] + val[w];
  110.        }
  111.    }
  112. }
  113.   
  114. int STRAIGHT_LINE_EMBEDDING2(graph& G,
  115.                              node& a, node& b, node& c,
  116.                              node_array<int>& xcoord,
  117.                              node_array<int>& ycoord)
  118. {
  119.    int N = G.number_of_nodes();
  120.    node v;
  121.    edge e,r;
  122.    list<edge> TL = TRIANGULATE_PLANAR_MAP(G);
  123.    a = G.first_node();
  124.    e = G.first_adj_edge(a);
  125.    b = G.target(e);
  126.    forall_adj_edges(r,b)
  127.       if (G.target(r) == a) break;
  128.    c = G.target(G.cyclic_adj_succ(r));
  129.    list<node> L;
  130.    compute_labelling(G,a,b,c,L);
  131.    GRAPH<node,int> T;
  132.    node_array<node> n(G);
  133.    compute_realizer(G,a,b,c,L,T,n);
  134.    node ta = n[a];
  135.    node tb = n[b];
  136.    node tc = n[c];
  137.    node_array<int> t1(T);
  138.    node_array<int> t2(T);
  139.  //node_array<int> t3(T);
  140.    node_array<int> p1(T);
  141.  //node_array<int> p2(T);
  142.    node_array<int> p3(T);
  143.    node_array<int> r1(T);
  144.    node_array<int> r2(T);
  145.  //node_array<int> r3(T);
  146.    compute_subtree_sizes(T,1,ta,t1);
  147.    compute_subtree_sizes(T,2,tb,t2);
  148.  //compute_subtree_sizes(T,3,tc,t3);
  149.    node_array<int> val(T,1);
  150.    tree_prefix_sum(T,1,ta,val,p1);
  151.  //tree_prefix_sum(T,2,tb,val,p2);
  152.    tree_prefix_sum(T,3,tc,val,p3);
  153.    val.init(T,0);
  154.    tree_prefix_sum(T,2,tb,t1,r1);
  155.    tree_prefix_sum(T,3,tc,t1,val);
  156.    forall_nodes(v,T) r1[v] += val[v] - t1[v] - p3[v] + 1;
  157.    tree_prefix_sum(T,3,tc,t2,r2);
  158.    tree_prefix_sum(T,1,ta,t2,val);
  159.    forall_nodes(v,T) r2[v] += val[v] - t2[v] - p1[v] + 1;
  160.  //tree_prefix_sum(T,1,ta,t3,r3);
  161.  //tree_prefix_sum(T,2,tb,t3,val);
  162.  //forall_nodes(v,T) r3[v] += val[v] - t3[v] - p2[v] + 1;
  163.    
  164.    forall_nodes(v,G)  
  165.    { xcoord[v] = r1[n[v]];
  166.      ycoord[v] = r2[n[v]];
  167.     }
  168.    xcoord[a] = N-1;
  169.    ycoord[a] = 0;
  170.    xcoord[b] = 0;
  171.    ycoord[b] = N-1;
  172.    xcoord[c] = 0;
  173.    ycoord[c] = 0;
  174.    // delete triangulation edges
  175.    forall(e,TL) G.del_edge(e);
  176.    return N-1; // maxcoord
  177. }
  178. int STRAIGHT_LINE_EMBEDDING2(graph& G,node_array<double>& x, node_array<double>& y)
  179. { node v;
  180.   node_array<int> x0(G), y0(G);
  181.   int result = STRAIGHT_LINE_EMBEDDING(G,x0,y0);
  182.   forall_nodes(v,G) { x[v] = x0[v];
  183.                       y[v] = y0[v]; }
  184.   return result;
  185. }