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

MultiPlatform

  1. #include <math.h>
  2. #include <LEDA/graph.h>
  3. #include <LEDA/graph_alg.h>
  4. #include <LEDA/window.h>
  5. #include <LEDA/graph_edit.h>
  6. void circular_embedding(GRAPH<point,int>& G, int x, int y, int radius)
  7. { int n = G.number_of_nodes();
  8.   float ang = 0;
  9.   node v;
  10.   forall_nodes(v,G)
  11.   { G[v] = point(x+radius*sin(ang),y+radius*cos(ang));
  12.     ang += 6.283/n;
  13.   }
  14. }
  15. void grid_embedding(GRAPH<point,int>& G, int c0, int c1)
  16. { int l = int(sqrt(G.number_of_nodes()) + 1);
  17.   int d = (c1-c0)/l;
  18.   int i = 0;
  19.   node v;
  20.   forall_nodes(v,G)
  21.   { int row = i/l;
  22.     int col = i%l;
  23.     G[v] = point(c0+col*d ,c0+row*d);
  24.     i++;
  25.    }
  26. }
  27.   
  28. void random_embedding(GRAPH<point,int>& G, int c0, int c1)
  29. { int n = G.number_of_nodes();
  30.   random_source ran(c0,c1);
  31.   node v;
  32.   forall_nodes(v,G)
  33.   { int x,y;
  34.     ran >> x >> y;
  35.     G[v] = point(x,y);
  36.    }
  37. }
  38.   
  39. void draw_graph(const GRAPH<point,int>& G, window& W, bool numbering=false)
  40. { node v;
  41.   edge e;
  42.   if (numbering)
  43.      { int i = 0;
  44.        forall_nodes(v,G) W.draw_int_node(G[v],i++,red);
  45.       }
  46.   else
  47.      forall_nodes(v,G) W.draw_filled_node(G[v],red);
  48.   forall_edges(e,G)
  49.     W.draw_edge(G[source(e)],G[target(e)],blue);
  50. }
  51. void draw_graph(const GRAPH<point,int>& G, window& W, 
  52.                 const node_array<double>& xc, const node_array<double>& yc,
  53.                 const node_array<double>& dx, const node_array<double>& dy)
  54. { node v;
  55.   forall_nodes(v,G) W.draw_filled_node(xc[v]+dx[v],yc[v]+dy[v],red);
  56.   edge e;
  57.   forall_edges(e,G)
  58.   { node v = source(e);
  59.     node w = target(e);
  60.     W.draw_edge(xc[v]+dx[v],yc[v]+dy[v],xc[w]+dx[w],yc[w]+dy[w],blue);
  61.    }
  62. }
  63. void draw_graph(const GRAPH<point,int>& G, window& W, 
  64.                 const node_array<double>& xc, const node_array<double>& yc)
  65. { node v;
  66.   forall_nodes(v,G) W.draw_filled_node(xc[v],yc[v],red);
  67.   edge e;
  68.   forall_edges(e,G)
  69.   { node v = source(e);
  70.     node w = target(e);
  71.     W.draw_edge(xc[v],yc[v],xc[w],yc[w],blue);
  72.    }
  73. }
  74. void move_graph_x11(window& W, GRAPH<point,int>& G, 
  75.                     node_array<double>& xc,
  76.                     node_array<double>& yc, int speed)
  77. {
  78.   node_array<double> dx(G);
  79.   node_array<double> dy(G);
  80.   int d = 400/speed;
  81.   W.clear();
  82.   W.set_mode(xor_mode);
  83.   draw_graph(G,W);
  84.   node v;
  85.   forall_nodes(v,G) 
  86.   { dx[v] = (xc[v] - G[v].xcoord())/d;
  87.     dy[v] = (yc[v] - G[v].ycoord())/d;
  88.     xc[v] = G[v].xcoord();
  89.     yc[v] = G[v].ycoord();
  90.    }
  91.   while(d--)
  92.   { draw_graph(G,W,xc,yc,dx,dy);
  93.     draw_graph(G,W,xc,yc);
  94.     forall_nodes(v,G) 
  95.     { xc[v] += dx[v];
  96.       yc[v] += dy[v];
  97.      }
  98.    }
  99.   W.set_mode(src_mode);
  100. }
  101. void move_graph_os2(window& W, GRAPH<point,int>& G, 
  102.                     node_array<double>& xc,
  103.                     node_array<double>& yc, int speed)
  104. {
  105.   node_array<double> dx(G);
  106.   node_array<double> dy(G);
  107.   int d = 200/speed;
  108.   node v;
  109.   forall_nodes(v,G) 
  110.   { dx[v] = (xc[v] - G[v].xcoord())/d;
  111.     dy[v] = (yc[v] - G[v].ycoord())/d;
  112.     xc[v] = G[v].xcoord();
  113.     yc[v] = G[v].ycoord();
  114.    }
  115.   while(d--)
  116.   { W.start_batch();
  117.     W.clear();
  118.     draw_graph(G,W,xc,yc,dx,dy);
  119.     W.end_batch();
  120.     forall_nodes(v,G) 
  121.     { xc[v] += dx[v];
  122.       yc[v] += dy[v];
  123.      }
  124.    }
  125. }
  126. void move_graph(window& W, GRAPH<point,int>& G, 
  127.                 node_array<double>& xc,
  128.                 node_array<double>& yc, int speed)
  129. {
  130. #if defined(__OS2__)
  131.      move_graph_os2(W,G,xc,yc,speed);
  132. #else
  133.      move_graph_x11(W,G,xc,yc,speed);
  134. #endif
  135.  }
  136. main()
  137. {
  138. panel P("LEDA Planarity Test Demo");
  139. P.text_item("");
  140. P.text_item("This demo illustrates planarity testing and straight-line");
  141. P.text_item("embedding. You have two ways to construct a graph: either");
  142. P.text_item("interactively by using the LEDA graph editor or by calling");
  143. P.text_item("one of two graph generators. The first generator constructs");
  144. P.text_item("a random graph with a certain number of nodes and edges and");
  145. P.text_item("the second constructs a planar graph with a certain number");
  146. P.text_item("of nodes by intersecting random lines in the unit square");
  147. P.text_item("");
  148. P.text_item("The graph is displayed and then tested for planarity. If it");
  149. P.text_item("is planar a straight-line drawing is produced, otherwise, a");
  150. P.text_item("Kuratowski subgraph is highlighted.");
  151. P.button("continue");
  152. P.open();
  153. window W;
  154. GRAPH<point,int>G;
  155. node v,w;
  156. edge e;
  157. int n = 30;
  158. int m = 40;
  159. int init_embed = 2;
  160. int final_embed = 0;
  161. int speed = 0;
  162. panel P1("PLANARITY TEST");
  163. P1.text_item("The first slider asks for the number n of nodes and the second");
  164. P1.text_item("slider asks for the number m of edges. If you select the random");
  165. P1.text_item("button then a graph with n nodes and m edges is constructed, if");
  166. P1.text_item("you select the planar button then a set of random line segments");
  167. P1.text_item("is chosen and intersected to yield a planar graph with about n");
  168. P1.text_item("n nodes, and if you select the edit button the graph editor is");
  169. P1.text_item("called.");
  170. P1.text_item(" ");
  171. P1.int_item("number of nodes",n,0,200);
  172. P1.int_item("number of edges",m,0,200);
  173. P1.choice_item("initial embedding",init_embed,"random","grid","circular");
  174. P1.choice_item("final embedding",final_embed,"fary","schnyder");
  175. P1.int_item("animation speed",speed,0,20);
  176. P1.button("random");
  177. P1.button("planar");
  178. P1.button("triang");
  179. P1.button("edit");
  180. P1.button("quit");
  181. for(;;) 
  182. {
  183.   int inp = P1.open(W);
  184.   if (inp == 4) break;   // quit button pressed
  185.   W.init(-50,950,-50);
  186.   W.set_node_width(4);
  187.   G.clear();
  188.   switch(inp) {
  189.   case 0: { random_graph(G,n,m);
  190.             eliminate_parallel_edges(G);
  191.             list<edge> Del;
  192.             forall_edges(e,G) 
  193.                if (source(e)==target(e)) Del.append(e);
  194.             forall(e,Del) G.del_edge(e);
  195.             break;
  196.            }
  197.   
  198.   case 1:  random_planar_graph(G,n);
  199.            break;
  200.   case 2:  triangulated_planar_graph(G,n);
  201.            break;
  202.   case 3:  W.set_node_width(10);
  203.            graph_edit(W,G,false);
  204.            break;
  205.   
  206.    }
  207.   
  208.    if (inp != 3)
  209.    { if (init_embed == 0) random_embedding(G,0,850);
  210.      if (init_embed == 1) grid_embedding(G,0,850);
  211.      if (init_embed == 2) circular_embedding(G,450,400,350);
  212.      draw_graph(G,W);
  213.     }
  214.   
  215.   if (PLANAR(G,false))
  216.   { 
  217.     if(G.number_of_nodes()<4)
  218.         W.message("That's an insult: Every graph with |V| <= 4 is planar");
  219.     else
  220.       { 
  221.         W.message("G is planar. I compute a straight-line embedding ...");
  222.         // first make graph bi-directed and bi-connected
  223.         edge_array<edge> rev(G); 
  224.         list<edge> single;
  225.         edge e; 
  226.         // collect all "singles" and give each of them a "partner"
  227.         Is_Bidirected(G,rev);
  228.         
  229.         forall_edges(e,G)
  230.              if (rev[e] == nil)  single.append(e);
  231.   
  232.         forall(e,single) 
  233.              rev[e] = G.new_edge(target(e),source(e));
  234.         list<edge> bi_edges = make_biconnected_graph(G);
  235.         PLANAR(G,true);
  236.   
  237.         node_array<int> xcoord(G);
  238.         node_array<int> ycoord(G);
  239.         float fx = 900.0/G.number_of_nodes();
  240.         float fy = fx;
  241.   
  242.         if (final_embed == 0)
  243.           { STRAIGHT_LINE_EMBEDDING(G,xcoord,ycoord);
  244.             fx /= 2;
  245.            }
  246.         else
  247.             STRAIGHT_LINE_EMBEDDING2(G,xcoord,ycoord);
  248.         forall(e,single) G.del_edge(rev[e]);
  249.         forall(e,bi_edges) G.del_edge(e);
  250.         node_array<double> xc(G);
  251.         node_array<double> yc(G);
  252.          forall_nodes(v,G) 
  253.          { xc[v] = fx*xcoord[v];
  254.            yc[v] = fy*ycoord[v];
  255.           }
  256.         if (speed > 0) // animate
  257.           { W.message("click any button");
  258.             W.read_mouse();
  259.             move_graph(W,G,xc,yc,speed);
  260.            }
  261.          else
  262.           { forall_nodes(v,G) G[v] = point(xc[v],yc[v]);
  263.             W.clear();
  264.             draw_graph(G,W);
  265.            }
  266.       }
  267.    }
  268.   else
  269.     { 
  270.       W.message("Graph is not planar. I compute the Kuratowski subgraph ...");
  271.       list<edge> L;
  272.       PLANAR(G,L,false);
  273.       // display Kuratowski subdivision with edge set L
  274.       edge_array<bool> marked(G,false);
  275.       node_array<int>  side(G,0);
  276.       edge e;
  277.       forall(e,L) marked[e] = true;
  278.       list<edge> el = G.all_edges();
  279.       forall(e,el) 
  280.         if (!marked[e]) 
  281.           { //W.draw_edge(G[source(e)],G[target(e)],yellow);
  282.             G.del_edge(e);
  283.            }
  284.       int lw = W.set_line_width(3);
  285.       forall_edges(e,G) W.draw_edge(G[source(e)],G[target(e)]);
  286.       node v;
  287.       forall_nodes(v,G) if (G.degree(v) == 3) break; 
  288.       if (G.degree(v) == 3)
  289.         forall_inout_edges(e,v)
  290.         { marked[e] = false;
  291.           node w = G.opposite(v,e);
  292.           while (G.degree(w) == 2)
  293.           { edge x,y;
  294.             forall_inout_edges(x,w) 
  295.                if (marked[x]) y=x;
  296.              marked[y] = false;
  297.              w = G.opposite(w,y);
  298.            }
  299.           side[w] = 1;
  300.          }
  301.         
  302.       int i = 1;
  303.       int j = 4;
  304.       forall_nodes(v,G) 
  305.       { 
  306.         if (G.degree(v)==2) W.draw_filled_node(G[v],black);
  307.         if (G.degree(v) > 2)
  308.         { int nw = W.set_node_width(10);
  309.           if (side[v]==0)
  310.              W.draw_int_node(G[v],i++,green);
  311.           else
  312.              if (W.mono())
  313.                 W.draw_int_node(G[v],j++,black);
  314.              else
  315.                 W.draw_int_node(G[v],j++,violet);
  316.           W.set_node_width(nw);
  317.          }
  318.       }
  319.       W.set_line_width(lw);
  320.    }
  321.    W.set_show_coordinates(false);
  322.    W.set_frame_label("click any button to continue");
  323.    W.read_mouse(); // wait for a click
  324.    W.reset_frame_label();
  325.    W.set_show_coordinates(true);
  326.  } //  Main Loop
  327. return 0;
  328. }