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

MultiPlatform

  1. //---------------------------------------------------------------
  2. //
  3. //
  4. //  A List Scheduling Algorithm
  5. //
  6. //   S. Naeher (August 1993)
  7. //---------------------------------------------------------------
  8. #include <LEDA/graph_alg.h>
  9. #include <LEDA/node_pq.h>
  10. static int compute_depth(graph& G, node_array<int>& depth);
  11. static void make_acyclic(graph& G)
  12. { node_array<int> dfsnum(G);
  13.   node_array<int> compnum(G);
  14.   DFS_NUM(G,dfsnum,compnum);
  15.   list<edge> back;
  16.   edge e;
  17.   forall_edges(e,G)
  18.   { node v = source(e);
  19.     node w = target(e);
  20.     if (v == w || (dfsnum[v] > dfsnum[w] && compnum[v] < compnum[w]))
  21.       back.append(e);
  22.    }
  23.   forall(e,back) G.del_edge(e);
  24. }
  25.     
  26. void list_schedule(graph& G, int k)
  27. {
  28.   node u;
  29.   node v;
  30.   node_array<int> path(G);     // path[v] = length of longest path starting in v
  31.   node_array<int> degree(G);   // degree[v] = current indegree of v
  32.   list<node> zero_deg;         // set of nodes v with degree[v] = 0
  33.   node_pq<int> Vd(G);
  34.   forall_nodes(v,G) 
  35.   { degree[v] = G.indeg(v);
  36.     if ( G.indeg(v) == 0) zero_deg.append(v);
  37.    }
  38.   int max_depth = compute_depth(G,path);
  39.   forall(v,zero_deg) Vd.insert(v,max_depth-path[v]);
  40.   zero_deg.clear();
  41.   for(int level=0; !Vd.empty(); level++) 
  42.   { 
  43.     //cout << level << ": ";
  44.     for(int i=0; i < k && !Vd.empty(); i++) 
  45.     { v = Vd.del_min();
  46.       //G.print_node(v); 
  47.       //cout <<  " ";
  48.       forall_adj_nodes(u,v)
  49.       if (--degree[u] == 0) zero_deg.append(u);
  50.      }
  51.     //newline;
  52.     forall(v,zero_deg) Vd.insert(v,max_depth-path[v]);
  53.     zero_deg.clear();
  54.   }
  55. }
  56.  
  57. static int compute_depth(graph& G, node_array<int>& depth)
  58. {
  59.   // reverse all edges and compute longest paths in topological order
  60.   // starting in nodes with indegree 0
  61.   // PRECONDITION: G is acyclic
  62.  
  63.   G.rev();  
  64.  
  65.   node_array<int>  degree(G);
  66.   list<node>       zero_deg;
  67.   node v;
  68.   edge e;
  69.   int count = 0;
  70.   int max_depth = 0;
  71.  
  72.   forall_nodes(v,G)
  73.   { depth[v] = 0;
  74.     degree[v] = G.indeg(v);
  75.     if (G.indeg(v) == 0) zero_deg.append(v);
  76.    }
  77.  
  78.   while(! zero_deg.empty())
  79.   { count++;
  80.     v = zero_deg.pop();
  81.     forall_adj_edges(e,v)
  82.     { int  d = depth[v]+1;
  83.       node w = G.target(e);
  84.       if (depth[w] < d) 
  85.       { depth[w] = d;
  86.         if (max_depth < d) max_depth = d;
  87.        }
  88.       if (--degree[w] == 0) zero_deg.append(w);
  89.      }
  90.    }
  91.   if (count < G.number_of_nodes()) 
  92.   { cerr << "Error: cyclic graphn";
  93.     exit(1);
  94.    }
  95.   G.rev();  // restore original graph
  96.   return max_depth;
  97. }
  98. main()
  99. {
  100.   graph G;
  101.   
  102.   test_graph(G);
  103.   int k = read_int("k = ");
  104.   make_acyclic(G);
  105.   cout << "|E| = " << G.number_of_edges() << endl;
  106.   newline;
  107.   float T = used_time();
  108.   list_schedule(G,k);
  109.   cout << string(" %f sec",used_time(T));
  110.   newline;
  111. }