⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcf_cost_scaling1.t

📁 A Library of Efficient Data Types and Algorithms,封装了常用的ADT及其相关算法的软件包
💻 T
📖 第 1 页 / 共 2 页
字号:
template <class cap_array, class flow_array, class cost_array>int adm_number(const graph_t& G, node v,                                     const cap_array& cap,                                    const flow_array& flow,                                    const cost_array& cost,                                    const pot_array& pot){   int count = 0;   edge e;   forall_out_edges(e,v)   { node w = target(G,e,v);     NT x = cap[e]-flow[e];     if (x > 0)     { rcost_t rc = rcost(e,v,w);       if (rc < 0) count++;     }    }   forall_in_edges(e,v)   { node w = source(G,e,v);     NT x = flow[e];     if (x > 0)     { rcost_t rc = -rcost(e,w,v);       if (rc < 0) count++;     }    }   return count;}template <class cap_array, class cost_array, class flow_array>bool cost_scaling(const graph_t& G, const cap_array& cap,                                    const cost_array& cost,                                    excess_array& excess,                                    flow_array& flow){  // returns true iff there exists a feasible flow  int n = G.number_of_nodes();  int global_update_delta     = (f_update > 0) ? int(f_update*n) : MAXINT;  int global_update_threshold = global_update_delta;  int beta4 = beta*beta*beta*beta;  pot_array  pot;   // potential  pot.use_node_data(G,0);  succ_array succ;  succ.use_node_data(G,0);  node v;  forall_nodes(v,G)  { pot[v] = 0;    succ[v] = 0;   }  NT C = 0;   // maximal cost of any edge in G  cost_array& ca = (cost_array&)cost;  edge e;  forall_edges(e,G)   { flow[e] = 0;    NT nc = n*cost[e];    ca[e] = nc;    if (nc > C) C = nc;    else if (-nc > C) C = -nc;   }  int eps=1;  while (eps < C) eps *= alpha;  feasible_flow<NT,graph_t,succ_array,dist_array> ff;    if (!ff.run(G,excess,cap,flow)) return false;  if (beta > 1)  { while (bellman_ford_refinement(G,eps/2,cap,flow,cost,pot,succ,n/100))     { eps /= 2;      cout << "new eps0 = " << eps << endl;    }  }  node_queue<graph_t,succ_array> active(G,succ);  counter push_count = 0;  counter discharge_count = 0;  int relabel_count = 0;  while (eps > 1)  {   //float t1 = used_time();   node v;   // compute 0-optimal pseudoflow    forall_nodes(v,G)   { edge e;     forall_out_edges(e,v)     { node w = target(G,e,v);       rcost_t rc = rcost(e,v,w);         if (rc > 0)         { NT x = flow[e];           if (x != 0)           { excess[v] += x;             excess[w] -= x;             flow[e] = 0;            }          }       else         if (rc < 0)         { NT x = cap[e] - flow[e];           if (x != 0)           { excess[v] -= x;             excess[w] += x;             flow[e] += x;            }          }       }     }  double total_excess = 0;  int    s_count = 0;  forall_nodes(v,G)   { NT ev = excess[v];    if (ev > 0)     { active.append(v);      total_excess += ev;      s_count++;     }   }/*   cout << string("eps = %9d  excess = %12.0f   |active| = %5d",                        eps, total_excess,s_count) << flush;*/       while (!active.empty())   {      node v = active.top();     NT ev = excess[v];     if (ev <= 0)      { active.del_top(v);       continue;      }     discharge_count++;     rcost_t min_rc = MAXINT;     edge min_e = 0;     NT   min_x = 0;     edge e;     forall_out_edges(e,v)     { NT f = flow[e];       NT x = cap[e] - f;       if (x == 0) continue;        node w = target(G,e,v);       rcost_t rc = rcost(e,v,w);       if (rc < 0)   // admissible       { NT ew = excess[w];/*         if (ew >= 0 && adm_number(G,w,cap,flow,cost,pot) == 0)         { pot[w] += eps;           rc += eps;           if (rc < min_rc) { min_rc = rc; min_e = e;  min_x = x; }           NT x = min(ew,f);           if (x > 0) // push back           { excess[w] -= x;             flow[e] -= x;             ev += x;            }          }         else*/         { push_count++;           if (ev <= x)            { flow[e] = f + ev;             ew += ev;             excess[w] = ew;             if (ew > 0 && !active.member(w)) active.fast_append(w);             goto NEXT_NODE;            }           flow[e] = f + x;           ew += x;           excess[w] = ew;           ev -= x;           if (ew > 0 && !active.member(w)) active.fast_append(w);          }        }       else       if (rc < min_rc) { min_rc = rc; min_e = e; min_x = x; }     }                forall_in_edges(e,v)     { NT f = flow[e];       if (f == 0) continue;        node w = source(G,e,v);       rcost_t rc = -rcost(e,w,v);       if (rc < 0) // admissible       { NT ew = excess[w];/*         if (ew >= 0 && adm_number(G,w,cap,flow,cost,pot) == 0)         { pot[w] += eps;           rc += eps;           if (rc < min_rc) { min_rc = rc; min_e = e; min_x = -f; }           NT x = cap[e] - f;           if (x > ew) x = ew;           if (x > 0) // push back           { excess[w] -= x;             flow[e] += x;             ev += x;            }          }         else*/         { push_count++;           if (ev <= f)           { flow[e] = f - ev;             ew += ev;             excess[w] = ew;             if (ew > 0 && !active.member(w)) active.fast_append(w);             //if (ew <= 0 && ev > -ew) active.append(w);             goto NEXT_NODE;            }           flow[e] = 0;           ew += f;           excess[w] = ew;           ev -= f;           if (ew > 0 && !active.member(w)) active.fast_append(w);           //if (ew <= 0 && f > -ew) active.append(w);          }        }       else       if (rc < min_rc) { min_rc = rc; min_e = e; min_x = -f; }     }     excess[v] = ev;     if (relabel_count > global_update_threshold && !active.empty())     { global_price_update(G, cap, flow, excess, cost, pot, eps);       global_update_threshold += global_update_delta;       continue;      }     relabel_count++;     pot[v] += (eps+min_rc);     //if (ev <= std::abs(min_x))      if (ev <= min_x || ev <= -min_x)     { push_count++;       if (min_x > 0)       { node w = target(G,min_e,v);         excess[w] += ev;         flow[min_e] += ev;         if (excess[w] > 0  && !active.member(w)) active.fast_append(w);        }       else       { node w = source(G,min_e,v);         excess[w] += ev;         flow[min_e] -= ev;         if (excess[w] > 0 && !active.member(w)) active.fast_append(w);        }       goto NEXT_NODE;      }         continue;NEXT_NODE:;     excess[v] = 0;     active.del_top(v);    } // while active not empty   if (eps < beta4)   { while (eps > 1 &&           bellman_ford_refinement(G,eps/beta,cap,flow,cost,pot,succ,n/100))      { eps /= beta;       cout << "new eps = " << eps << endl;     }   }   //check_eps_optimality(G,cost,pot,cap,flow,eps,"after eps-phase");   eps /= alpha;   //cout << string(" %.2f sec",used_time(t1)) << endl;  } // while eps > 1                                      num_discharges = discharge_count;  num_pushes = push_count;  num_relabels = relabel_count;  forall_edges(e,G) ca[e] /= n;  return true;}public:mcf_cost_scaling() : alpha(0), beta(0), f_update(0),                     num_nodes(0), num_edges(0), num_discharges(0),                      num_pushes(0), num_relabels(0), num_updates(0), T(0) {}template<class lcap_array, class ucap_array, class cost_array,                            class supply_array, class flow_array>bool run(const graph_t& G, const lcap_array& lcap,                           const ucap_array& ucap,                           const cost_array& cost,                           const supply_array& supply,                           flow_array&       flow,                           float f = 1.25,                           int a = 18,                           int b = 0){  T = used_time();  num_discharges = 0;  num_relabels = 0;  num_updates  = 0;  alpha = a;  beta  = b;  f_update = f;  num_nodes = G.number_of_nodes();  num_edges = G.number_of_edges();  excess_array excess;         // supply values after elimination of  excess.use_node_data(G,0);   // lower capacity bounds  ucap_array& cap = (ucap_array&)ucap;  // non-const reference to cap array                                        // used to modify capacities                                        // temporarily for elimination of                                        // lower capacity bounds  int lc_count = 0;  node v;  forall_nodes(v,G) excess[v] = supply[v];  forall_nodes(v,G)   { edge e;    forall_out_edges(e,v)     { NT lc = lcap[e];      if (lc != 0)                  // nonzero lower capacity bound      { node w  = target(G,e,v);        excess[v] -= lc;        excess[w] += lc;        cap[e] -= lc;        lc_count++;       }     }  }     bool feasible = cost_scaling(G, cap, cost, excess, flow);    if (lc_count)  { // adjust flow and restore capacities    edge e;    forall_edges(e, G)     { NT lc = lcap[e];      if (lc != 0)      { flow[e] += lc;        cap[e] += lc;       }     }   }  T = used_time(T);  if (feasible)  { // check flow    edge e;    forall_edges(e,G)    {      if (flow[e] < 0 || flow[e] > cap[e])           error_handler(1,"check_flow: illegal flow value");     }      forall_nodes(v,G)    { NT ev = supply[v];      edge e;      forall_out_edges(e,v) ev -= flow[e];      forall_in_edges(e,v) ev += flow[e];      if (ev != 0)           error_handler(1,"check_flow: non-zero excess");     }  }      return feasible;}float cpu_time() { return T; } void statistics(ostream& out){  out << string("%5d nodes  %5d edges   a = %d  b = %d  f = %.2f",         num_nodes,num_edges,alpha,beta,f_update) << endl;  out << string("%8d discharges %10d pushes %8d relabels %3d updates",                   num_discharges, num_pushes,num_relabels, num_updates) << endl;  out << endl;}};LEDA_END_NAMESPACE#if LEDA_ROOT_INCL_ID == 450457#undef LEDA_ROOT_INCL_ID#include <LEDA/POSTAMBLE.h>#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -