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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _embedding.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. /*******************************************************************************
  12. *                                                                              *
  13. *  EMBEDDING   (straight line embedding)                                       *
  14. *                                                                              *
  15. *  K. Mehlhorn (1989)                                                          *
  16. *                                                                              *
  17. *******************************************************************************/
  18. #include <LEDA/graph_alg.h>
  19. const int A = -2; 
  20. const int B = -1; 
  21. static node_array<list_item>  Classloc;
  22. static node_array<int>  ord, labelled, Class;
  23. static node_array<node> first, second, last;
  24. static edge_array<edge> reversal;
  25. void label_node(graph& G, list<node>& L, int& count,
  26.                 list<node>& Al,list<node>& Bl,list<node>*& Il,
  27.                 node v, node c)
  28. { // labels the node v; c is the special node which is to be labelled
  29.   // last; the details are described in lemma 10
  30.   edge e;
  31.   L.append(v);
  32.   ord[v]=count++; 
  33.   labelled[v]=1;
  34.   forall_adj_edges(e,v)
  35.   { edge e1 = reversal[e];
  36.     node tt = target(e);
  37.     int i;
  38.     if (labelled[tt] && !labelled[target(G.cyclic_adj_succ(e))])
  39.       { first[v]=tt; 
  40.         second[v]=target(G.cyclic_adj_pred(e));
  41.        }
  42.     if (labelled[tt] && !labelled[target(G.cyclic_adj_pred(e))]) last[v]=tt;
  43.     if (!labelled[tt] && (tt != c))
  44.       { if (Class[tt] == A) 
  45.           { Al.del(Classloc[tt]); 
  46.             Classloc[tt] = Bl.push(tt);
  47.             Class[tt]=B;
  48.            }  
  49.         else 
  50.           { if (Class[tt] == B) 
  51.                { Bl.del(Classloc[tt]);
  52.                  i = 2-labelled[target(G.cyclic_adj_succ(e1))]
  53.                       -labelled[target(G.cyclic_adj_pred(e1))];
  54.                 }
  55.             else 
  56.                { i=Class[tt];
  57.                  Il[i].del(Classloc[tt]);
  58.                  i = i+1-labelled[target(G.cyclic_adj_succ(e1))]
  59.                         -labelled[target(G.cyclic_adj_pred(e1))];
  60.                 }
  61.              Class[tt]=i;
  62.              Classloc[tt]=Il[i].push(tt);
  63.            }//end else case
  64.       }//end if
  65.   }//end 
  66. }//end of label_node
  67. void compute_labelling(graph& G,list<node>& L, list<node>& Pi)
  68. { /* computes the ordering of lemma 10 in List L ,the sequence pi
  69.      in List Pi, the function L^-1(v) in Array ord, and the functions
  70.      first,second,last of lemma 11 in the corresponding Arrays
  71.    */
  72.   node v,a,b,c;
  73.   /* zuerst berechne ich die drei Knoten,die am Rand des aeusseren 
  74.      Gebiets liegen sollen
  75.    */
  76.   a=G.first_node();
  77.   list<edge> temp = G.adj_edges(a);
  78.   b = target(temp.pop());
  79.   c = target(temp.pop());
  80. /*
  81.   node_array<int> labelled(G,0);
  82. */
  83.   labelled.init(G,0);
  84.   int count = 0;
  85.   
  86.   list<node> Al ;
  87. /*
  88.   node_array<int> Class(G); 
  89.   node_array<list_item> Classloc(G);
  90. */
  91.   Class.init(G); 
  92.   Classloc.init(G);
  93.   forall_nodes(v,G) { Classloc[v] = Al.push(v);Class[v]=A;}
  94.   list<node> Bl;
  95.   list<node>* Il = new list<node>[G.number_of_nodes()];
  96.   
  97.   label_node(G,L,count,Al,Bl,Il,a,c);
  98.   label_node(G,L,count,Al,Bl,Il,b,c);
  99.   while (v=Il[1].pop()) label_node(G,L,count,Al,Bl,Il,v,c);
  100.   label_node(G,L,count,Al,Bl,Il,c,c);
  101.    //nun berechne ich noch first second und last des Knoten c 
  102.   first[c]=a;
  103.   last[c]=b;
  104.   edge e;
  105.   forall_adj_edges(e,c) if (target(e)==a) second[c]=target(G.cyclic_adj_pred(e));
  106.   
  107.  //nun die Folge Pi
  108.   node_array<list_item> Piloc(G);
  109.   Piloc[a] = Pi.push(a);
  110.   Piloc[b] = Pi.append(b);
  111.   forall(v,L) if (v != a && v != b) Piloc[v] = Pi.insert(v,Piloc[second[v]],-1);
  112. }//end of compute_labelling 
  113. void move_to_the_right(list<node>& Pi, node v, node w, 
  114.                        node_array<int>& ord, node_array<int>& x)
  115. { //increases the x-coordinate of all nodes which follow w in List Pi
  116.   //and precede v in List L,i.e., have a smaller ord value than v
  117.   int seen_w = 0;
  118.   node z;
  119.   forall(z,Pi)
  120.   { if (z==w) seen_w=1;
  121.     if (seen_w && (ord[z]<ord[v])) x[z]=x[z]+1;
  122.   }
  123. }
  124. int STRAIGHT_LINE_EMBEDDING(graph& G,node_array<int>& x, node_array<int>& y)
  125. {
  126.  // computes a straight-line embedding of the planar map G into
  127.  // the 2n by n grid. The coordinates of the nodes are returned
  128.  // in the Arrays x and y. Returns the maximal coordinate.
  129. list<node> L;
  130. list<node> Pi;
  131. list<edge> TL;
  132. node v;
  133. edge e;
  134. int maxcoord=0;
  135. /*
  136. node_array<int>  ord(G);
  137. node_array<node> first(G), second(G), last(G);
  138. */
  139. ord.init(G);
  140. first.init(G);
  141. second.init(G);
  142. last.init(G);
  143. TL = TRIANGULATE_PLANAR_MAP(G);
  144. /*
  145. edge_array<edge> reversal(G);
  146. */
  147. reversal.init(G);
  148. compute_correspondence(G,reversal);
  149. compute_labelling(G,L,Pi);
  150. //I now embed the first three nodes
  151. v = L.pop();
  152. x[v]=y[v]=0;
  153. v=L.pop();
  154. x[v]=2;y[v]=0;
  155. v=L.pop();
  156. x[v]=y[v]=1;
  157. //I now embed the remaining nodes
  158. while (v=L.pop())
  159.  { // I first move the nodes depending on second[v] by one unit
  160.    // and the the nodes depending on last[v] by another unit to the 
  161.    // right
  162.    move_to_the_right(Pi,v,second[v],ord,x);
  163.    move_to_the_right(Pi,v,last[v],ord,x);
  164.    // I now embed v at the intersection of the line with slope +1
  165.    // through first[v] and the line with slope -1 through last[v]
  166.    int x_first_v = x[first[v]];
  167.    int x_last_v =  x[last[v]];
  168.    int y_first_v = y[first[v]];
  169.    int y_last_v =  y[last[v]];
  170.    x[v]=(y_last_v - y_first_v + x_first_v + x_last_v)/2;
  171.    y[v]=(x_last_v - x_first_v + y_first_v + y_last_v)/2;
  172.  }
  173. // delete triangulation edges
  174. forall(e,TL) G.del_edge(e);
  175. forall_nodes(v,G) maxcoord = Max(maxcoord,Max(x[v],y[v]));
  176. return maxcoord;
  177. }
  178. int STRAIGHT_LINE_EMBEDDING(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. }