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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _mcmflow.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. // MIN_COST_MAX_FLOW(G,s,t,cap,cost,flow)
  14. //
  15. // computes a maximal s-t flow of minimal total cost in network (G,cap,cost)
  16. //
  17. // Algorithm: successive shortest path augmentation + capacity scaling
  18. //
  19. // Based on:  J. Edmonds and R. M. Karp: 
  20. //            "Theoretical Improvements in Algorithmic Efficiency for Network 
  21. //            Flow Problems", Journal of the  ACM, Vol. 19, No. 2, 1972
  22. //
  23. //            R.K. Ahuja, T.L. Magnanti, J.B. Orlin: 
  24. //            "Network Flows", Section 10.2, Prentice Hall Publ. Company, 1993
  25. //
  26. //
  27. // S. N"aher  (December 1993)
  28. //------------------------------------------------------------------------------
  29. #include <LEDA/graph_alg.h>
  30. #include <LEDA/node_pq.h>
  31. static node DIJKSTRA_IN_RESIDUAL(const graph& G, node s, int delta, 
  32.                                  const edge_array<num_type>& cost,
  33.                                  const edge_array<num_type>& cap_minus_flow,
  34.                                  const edge_array<num_type>& flow,
  35.                                  const node_array<num_type>& excess,
  36.                                  node_array<num_type>& pi,
  37.                                  node_array<edge>& pred)
  38. {
  39.    /*  Computes a shortest path from node s until a node t with excess <= -delta
  40.        is reached in the delta-residual graph of network G. Edges are traversed
  41.        in both directions using the forall_in/out_edges iteration macros.The 
  42.        residual capacity of an edge e is cap_minus_flow[e] if e is used from 
  43.        source(e) to target(e) and flow[e] otherwise. The reduced cost of an
  44.        edge e = (u,v) is equal to cost[e] + pi[u] - pi[v] if it is used from 
  45.        u and -cost[e] + pi[v] - pi[u] if it is used from v.
  46.        precondition: every edge in the delta-residual network has non-negative 
  47.                      reduced cost.
  48.        
  49.        returns t (nil,if there is no path from s to a node with excess<-delta)
  50.        and
  51.        pred[v] = predecessor edge of v on the shortest path from s to t
  52.        pi[v]   = pi'[v] + dist[v] - dist[t], if v is permanently labeled
  53.                  pi'[v],                     if v is temporarily labeled
  54.                  (here pi' is the old potential vector)
  55.   */
  56.   node_array<num_type> dist(G,MAXINT);
  57.   node_pq<num_type> PQ(G);
  58.   node v;
  59.   edge e;
  60.   node t = nil;
  61.   node_list perm_labeled; // list of permanently labeled nodes
  62.   dist[s] = 0;
  63.   PQ.insert(s,0);
  64.   while (!PQ.empty())
  65.   { node u = PQ.del_min();
  66.     perm_labeled.append(u);
  67.     if (excess[u] <= -delta) 
  68.     { t = u;
  69.       break;
  70.      }
  71.     num_type du = dist[u] + pi[u]; 
  72.     forall_out_edges(e,u) 
  73.       if (cap_minus_flow[e] >= delta)  // e in delta-residual graph
  74.       { v = target(e);
  75.         num_type c = du - pi[v] + cost[e];
  76.         if (c < dist[v])
  77.         { if (dist[v] == MAXINT) // v has not been reached before
  78.             PQ.insert(v,c);
  79.           else
  80.             PQ.decrease_p(v,c);
  81.           dist[v] = c;
  82.           pred[v] = e;
  83.          }
  84.        }
  85.     forall_in_edges(e,u) 
  86.       if (flow[e] >= delta)  // e in delta-residual graph
  87.       { v = source(e);
  88.         num_type c = du - pi[v] - cost[e];
  89.         if (c < dist[v])
  90.         { if (dist[v] == MAXINT) // v has not been reached before
  91.             PQ.insert(v,c);
  92.           else
  93.             PQ.decrease_p(v,c);
  94.           dist[v] = c;
  95.           pred[v] = e;
  96.          }
  97.        }
  98.    }
  99.    if (t != nil) // update potentials of all permanently labeled nodes
  100.    { num_type dt = dist[t];
  101.      forall(v,perm_labeled) pi[v] += dist[v] - dt;
  102.     }
  103.    return t;
  104. }
  105. num_type MIN_COST_MAX_FLOW(graph& G, node src, node sink,
  106.                                               const edge_array<num_type>& cap0,
  107.                                               const edge_array<num_type>& cost0,
  108.                                               edge_array<num_type>& flow0)
  109.   double n = G.number_of_nodes();
  110.   double m = G.number_of_edges();
  111.   num_type total_flow = 0;               // total flow value (returned)
  112.   int  count = 0;                        // number of augmentations
  113.   node v;
  114.   edge e;
  115.   num_type supply = MAX_FLOW(G,src,sink,cap0,flow0);
  116.   num_type C = 0;  // maximal cost of an s-t path in G
  117.   forall_edges(e,G)
  118.   { if (cost0[e] > C)  C = cost0[e];
  119.     if (cost0[e] < -C) C = -cost0[e];
  120.    }
  121.   C = C * G.number_of_nodes();
  122.   list<edge> art_edges;  // list of artificial edges (see below)
  123.   list<edge> neg_edges;  // list of negative cost edges
  124.   // add artificial edges to guarantee existence of a path of infinite
  125.   // capacity (MAXINT) and huge cost (C) between any pair of nodes  (v,w)
  126.   // with b(v) > 0 and b(w) < 0
  127.    
  128.   //forall_nodes(v,G) 
  129.   //if (v != src) 
  130.   //{ art_edges.append(G.new_edge(v,src));
  131.   //  art_edges.append(G.new_edge(src,v));
  132.   // }
  133.   art_edges.append(G.new_edge(src,sink));
  134.   node_array<num_type> pi(G,0);           // node potential
  135.   node_array<num_type> excess(G,0);       // excess
  136.   node_array<edge>     pred(G,nil);       // predecessor edge on shortest path
  137.   edge_array<num_type> flow(G,0);
  138.   edge_array<num_type> cap(G,0);
  139.   edge_array<num_type> cost(G,0);
  140.   edge_array<num_type> cap_minus_flow(G,0);
  141.   forall_edges(e,G)
  142.   { cap[e] = cap0[e];
  143.     cost[e] = cost0[e];
  144.     cap_minus_flow[e] = cap[e];
  145.     if (cost[e] < 0) neg_edges.append(e);
  146.    }
  147.   forall(e,art_edges)
  148.   { cap[e] = MAXINT;
  149.     cost[e] = C;
  150.     cap_minus_flow[e] = MAXINT;
  151.    }
  152.   excess[src]  =  supply;
  153.   excess[sink] = -supply;
  154.   // eliminate negative cost edges by edge reversals 
  155.   // (Ahuja/Magnanti/Orlin, section 2.4)
  156.   forall(e,neg_edges)
  157.   { node u = source(e);
  158.     node v = target(e);
  159.     excess[u] -= cap[e];
  160.     excess[v] += cap[e];
  161.     cost[e] = -cost[e];
  162.     G.rev_edge(e);
  163.   }
  164.  
  165.   int delta = 1;
  166.   double delta_max = supply * m/(n*n);  // seems to be a good choice
  167.   while (2*delta <= delta_max) delta = 2*delta;
  168.   while (delta > 0)  // delta scaling phase
  169.   {
  170.     forall_edges(e,G)  
  171.     { // Saturate all edges entering the delta residual network which have
  172.       // a negative reduced edge cost. Then only the reverse edge (with positive
  173.       // reduced edge cost) will stay in the residual network. 
  174.       node u = source(e);
  175.       node v = target(e);
  176.       num_type c = cost[e] + pi[u] - pi[v];
  177.       if (cap_minus_flow[e] >= delta && c < 0)
  178.         { excess[v] += cap_minus_flow[e];
  179.           excess[u] -= cap_minus_flow[e];
  180.           flow[e] = cap[e];
  181.           cap_minus_flow[e] = 0;
  182.          }
  183.       else
  184.         if (flow[e] >= delta && c > 0)
  185.         { excess[u] += flow[e];
  186.           excess[v] -= flow[e];
  187.           flow[e] = 0;
  188.           cap_minus_flow[e] = cap[e];
  189.          }
  190.      }
  191.     // As long as there is a node s with excess >= delta compute a minimum
  192.     // cost augmenting path from s to a sink node t with excess <= -delta in 
  193.     // the delta-residual network and augment the flow by at least delta units 
  194.     // along P (if there are nodes with excess > delta and excess < -delta
  195.     // respectively, the existence of P is guaranteed by the artificial edges 
  196.     // inserted at the begining of the algorithm)
  197.     node s;
  198.     node t;
  199.   
  200.     forall_nodes(s,G)
  201.     while (excess[s] >= delta)
  202.     { 
  203.       count++;
  204.   
  205.       t = DIJKSTRA_IN_RESIDUAL(G,s,delta,cost,cap_minus_flow,flow,excess,pi,pred);
  206.       if (t == nil) break; // there is no node with excess < -delta
  207.   
  208.       // compute maximal amount f of flow that can be pushed through P
  209.   
  210.       num_type f = excess[s];
  211.   
  212.       v = t; 
  213.       while (v != s)
  214.       { e = pred[v]; 
  215.         num_type rcap;
  216.         if (v==target(e))
  217.            { rcap = cap_minus_flow[e];
  218.              v = source(e);
  219.             }
  220.         else
  221.            { rcap = flow[e];
  222.              v = target(e);
  223.             }
  224.         if (rcap < f) f = rcap;
  225.        }
  226.   
  227.       if (f > -excess[t]) f = -excess[t];
  228.   
  229.   
  230.       // add f units of flow along the augmenting path 
  231.   
  232.       v = t; 
  233.       while (v != s)
  234.       { e = pred[v]; 
  235.         if (v==target(e))
  236.            { flow[e] += f;
  237.              cap_minus_flow[e] -= f;
  238.              v = source(e);
  239.             }
  240.         else
  241.            { flow[e] -= f;
  242.              cap_minus_flow[e] += f;
  243.              v = target(e);
  244.             }
  245.        }
  246.   
  247.        excess[s] -= f;
  248.        excess[t] += f;
  249.   
  250.     } // end of delta-phase
  251.   
  252.    delta /= 2;
  253.   
  254.   } // end of scaling
  255.   
  256.   edge x;
  257.   // restore negative edges
  258.   forall(x,neg_edges) 
  259.   { flow[x] = cap[x] - flow[x];
  260.     G.rev_edge(x);
  261.    }
  262.   // delete artificial edges
  263.   forall(x,art_edges) G.del_edge(x); 
  264.   // total flow  = total flow out of the source node
  265.   forall_out_edges(x,src) total_flow += flow[x];
  266.   forall_edges(x,G) flow0[x] = flow[x];
  267.   //cout << "count = " << count << endl;
  268.   return total_flow;
  269. }