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

MultiPlatform

  1. #include <LEDA/graph_edit.h>
  2. #include <LEDA/ugraph.h>
  3. #include <LEDA/stack.h>
  4. #include <LEDA/array2.h>
  5. window win;
  6. bool trace;
  7. bool step;
  8. #if !defined(__TEMPLATE_FUNCTIONS__)
  9. int compare(list<node>&, list<node>&) { return 0; }
  10. LEDA_TYPE_PARAMETER(list<node>)
  11. #endif
  12. void FIND_INDEPENDENT_NEIGHBORS(const ugraph& G, const node_array<int>&, 
  13.                                 node v, node& u, node& w);
  14. int  UNUSED_ADJ_COLOR(node v, const node_array<int>& col);
  15. void FIVE_COLOR(const GRAPH<point,int>& G, node_array<int>& C)
  16. {
  17.   // G is a planar graph
  18.   UGRAPH<point,int> G1;
  19.   G1 = G;
  20.   //we have to avoid parallel edges
  21.   node_array<int>  C1(G1,0);       // C1[v] = color of node v in G1
  22.   node_array<bool> mark(G1,false);
  23.   node_array<int>  deg(G1);        // deg[v] = current degree of v
  24.   list<node> small_deg;            // list of nodes with deg[v] <= 5
  25.   node_array<list_item> I(G1,nil); // I[v] = location of v in small_deg
  26.   node_array<list<node> > L(G1);   // L[v] = list of nodes of G represented by v
  27.   stack<node>  removed;            // stack of (conceptually) removed nodes
  28.   int N;                           // current number of valid nodes of G1
  29.   // Initialization
  30.   N = G1.number_of_nodes();
  31.   node u,v,w,x;
  32.   u = G.first_node();
  33.   forall_nodes(v,G1)
  34.   { deg[v] = G1.degree(v);
  35.     if(deg[v] <= 5) I[v] = small_deg.append(v);
  36.     L[v].append(u);
  37.     u = G.succ_node(u);
  38.    }
  39.   // shrinking G1
  40. if (trace) win.message("shrinking graph G ---> G1");
  41.   while (N > 0)
  42.   {
  43.     forall_nodes(v,G1)
  44.     { int d = 0;
  45.       forall_adj_nodes(x,v) if (C1[x] != -1) d++;
  46.       if (C1[v] != -1 && deg[v] != d) 
  47.       { win.draw_filled_node(G1[v]); 
  48.         error_handler(1,string("N = %d  deg = %d   d = %d",N,deg[v],d));
  49.        }
  50.      }
  51.     if (small_deg.empty())
  52.        error_handler(1,"smalldeg is empty");
  53.     v = small_deg.pop();
  54.     I[v] = nil;
  55.     if (trace) 
  56.     { win.set_mode(xor_mode);
  57.       win.draw_text_node(G1[v],"?");
  58.       win.draw_filled_node(G1[v]);
  59.       win.set_mode(src_mode);
  60.      }
  61.     if (deg[v] == 5)
  62.     {
  63.       FIND_INDEPENDENT_NEIGHBORS(G1,C1,v,u,w);
  64.       if (w == u) error_handler(1,"merging identical nodes"); //parallel edges
  65.       if(trace)
  66.       { win.set_mode(xor_mode);
  67.         win.draw_text_node(G1[w],"?");
  68.         win.draw_filled_node(G1[w]);
  69.         win.draw_filled_node(G1[u]);
  70.         win.draw_edge(G1[v],G1[u]);
  71.         win.draw_edge(G1[v],G1[w]);
  72.         win.set_line_width(2);
  73.         win.draw_edge(G1[v],G1[u]);
  74.         win.draw_edge(G1[v],G1[w]);
  75.         if (step) win.read_mouse();
  76.         win.draw_edge(G1[v],G1[u]);
  77.         win.draw_edge(G1[v],G1[w]);
  78.         win.set_line_width(1);
  79.         win.draw_edge(G1[v],G1[u]);
  80.         win.draw_edge(G1[v],G1[w]);
  81.         win.draw_filled_node(G1[v]);
  82.         win.draw_node(G1[v]);
  83.        }
  84.       { forall_adj_nodes(x,u) mark[x] = true; }
  85.       forall_adj_nodes(x,w)
  86.       { if (x == u) error_handler(1,"merging adjacent nodes");
  87.         if (mark[x]) 
  88.            { deg[x]--;
  89.              if (deg[x] == 5) 
  90.                 I[x] = small_deg.append(x);
  91.             }
  92.         else
  93.            { G1.new_edge(u,x,0);
  94.              if (C1[x] != -1) deg[u]++;  
  95.              if(trace) win.draw_edge(G1[u],G1[x]);
  96.             }
  97.        }
  98.       { forall_adj_nodes(x,u) mark[x] = false; }
  99.       deg[v]--;
  100.       if (deg[u] > 5 && I[u] != nil)
  101.       { small_deg.del(I[u]);
  102.         I[u] = nil;
  103.        }
  104.       L[u].conc(L[w]);
  105.      
  106.       if (I[w] != nil) small_deg.del(I[w]);
  107.       if (trace)
  108.       { forall_adj_nodes(x,w) win.draw_edge(G1[w],G1[x]);
  109.         win.draw_filled_node(G1[w]);
  110.         win.draw_filled_node(G1[u]);
  111.         win.set_mode(src_mode);
  112.        }
  113.       G1.del_node(w);
  114.       N--;
  115.     }
  116.     if (step)  win.read_mouse();
  117.     //  now deg[v] <= 4
  118.     C1[v] = -1;
  119.     removed.push(v);
  120.     forall_adj_nodes(x,v)
  121.        if ( --deg[x] == 5) 
  122.          I[x] = small_deg.append(x);
  123.     N--;
  124.    }
  125. if (trace)
  126. { win.read_mouse();
  127.   win.del_messages();
  128.   win.message("coloring G1");
  129. }
  130.    // now color the nodes in "removed" from top to bottom
  131.    while ( ! removed.empty() )
  132.    { v = removed.pop();
  133.      int c = UNUSED_ADJ_COLOR(v,C1);
  134.      if (c == 5) error_handler(1,"more than 5 different adjacent colors");
  135.      C1[v] = c;
  136.      forall(x,L[v]) C[x] = c;
  137.      if (trace) win.draw_int_node(G1[v],c);
  138.      if (step)  win.read_mouse();
  139.     }
  140.     if (trace) 
  141.     { edge e;
  142.       win.read_mouse();
  143.       win.del_messages();
  144.       win.message("coloring G");
  145.       win.set_mode(xor_mode);
  146.       forall_edges(e,G1) win.draw_edge(G1[source(e)],G1[target(e)]);
  147.       win.set_mode(src_mode);
  148.      }
  149. }
  150.      
  151. void  FIND_INDEPENDENT_NEIGHBORS(const ugraph& G, const node_array<int>& col,
  152.                                  node v, node& u, node& w)
  153. { node x;
  154.   list<node> L;
  155.   forall_adj_nodes(x,v)
  156.       if (col[x] != -1) L.append(x);
  157.   for (list_item it1 = L.first(); it1 != nil; it1 = L.succ(it1))
  158.     { u = L[it1];
  159.       for (list_item it2 = L.succ(it1); it2 != nil; it2 = L.succ(it2))
  160.         { w = L[it2];
  161.           forall_adj_nodes(x,w) if (x == u) break;
  162.           G.init_adj_iterator(w);
  163.           if (x != u) return;
  164.          }
  165.      }
  166.   error_handler(1,"no independent neighbors found!");
  167.   return;
  168.  }
  169. int UNUSED_ADJ_COLOR(node v, const node_array<int>& col)
  170.   int used[6];
  171.   int c;
  172.   node x;
  173.   for(c = 0; c < 6; c++) used[c] = 0;
  174.   forall_adj_nodes(x,v)
  175.   { c = col[x];
  176.     if (c != -1) used[c] = 1;
  177.    }
  178.   c = 0; 
  179.   while(used[c]) c++;
  180.   return c;
  181.  }
  182. void grid_graph(GRAPH<point,int>& G, int n, float win_width)
  183. {
  184.   array2<node>  A(n,n);
  185.   float dist = win_width/(n+3);
  186.   int i,j;
  187.   G.clear();
  188.   for(i=0; i<n; i++)
  189.     for(j=0; j<n; j++)
  190.       A(i,j) = G.new_node(point(dist*(j+2),dist*(i+2)));
  191.   for(i=0; i<n; i++)
  192.     for(j=0; j<n; j++)
  193.        { if (i < n-1) G.new_edge(A(i,j),A(i+1,j));
  194.          if (j < n-1) G.new_edge(A(i,j),A(i
  195. ,j+1));
  196.          if (i < n-1 && j < n-1) G.new_edge(A(i,j),A(i+1,j+1));
  197.         }
  198.   node north = G.new_node(point(dist*((n-1)/2.0 + 2),dist*(n+2)));
  199.   node south = G.new_node(point(dist*((n-1)/2.0 + 2),dist));
  200.   node west  = G.new_node(point(dist,dist*((n-1)/2.0 + 2)));
  201.   node east  = G.new_node(point(dist*(n+2),dist*((n-1)/2.0 + 2)));
  202.   for(i=0; i < n; i++)
  203.   { G.new_edge(north,A(n-1,i));
  204.     G.new_edge(south,A(0,i));
  205.     G.new_edge(west,A(i,0));
  206.     G.new_edge(east,A(i,n-1));
  207.    }
  208.   
  209.   //G.new_edge(A(0,n-1),A(n-1,0));
  210. /*
  211.   list<edge> E = G.all_edges();
  212.   edge e;
  213.   forall(e,E) G.new_edge(target(e),source(e));
  214. */
  215. }
  216.          
  217. char* COLOR[] = {"blue","red","green","violet","orange"};
  218.     
  219. main()
  220. {
  221.   GRAPH<point,int>  G;
  222.   node v;
  223.   edge e;
  224.   int n = 8;
  225.   int t = 0;
  226.   win.init(0,1000,0);
  227.   win.set_node_width(10);
  228.   panel P("five coloring a planar graph");
  229.   P.choice_item("trace",t,"off","step","movie");
  230.   P.int_item("N = ",n,1,30);
  231.   P.button("edit");
  232.   P.button("grid");
  233.   P.button("quit");
  234.   for(;;)
  235.   { 
  236.     int inp = P.open(win);
  237.     
  238.     trace = (t > 0);
  239.     step  = (t == 1);
  240.     if (inp == 2) break;
  241.     win.clear();
  242.     if (inp == 0) graph_edit(win,G,false);
  243.    
  244.     if (inp == 1) grid_graph(G,n,1000);
  245.     forall_nodes(v,G) win.draw_text_node(G[v],"?");
  246.     forall_edges(e,G) win.draw_edge(G[source(e)],G[target(e)]);
  247.     node_array<int> col(G,-1);
  248.     FIVE_COLOR(G,col);
  249.     forall_edges(e,G) win.draw_edge(G[source(e)],G[target(e)]);
  250.     forall_nodes(v,G) win.draw_int_node(G[v],col[v],col[v]+2);
  251.     win.set_frame_label("click any button to continue");
  252.     win.read_mouse();
  253.     win.reset_frame_label();
  254.   }
  255.   return 0;
  256. }