src/work/athos/mincostflow.h
changeset 659 c5984e925384
parent 657 531fc5f575ef
child 661 d306e777117e
equal deleted inserted replaced
3:97c30c04b2d4 4:336fbb1bba78
    57     typedef typename ResGraphType::Edge ResGraphEdge;
    57     typedef typename ResGraphType::Edge ResGraphEdge;
    58 
    58 
    59     class ModLengthMap {   
    59     class ModLengthMap {   
    60       //typedef typename ResGraphType::template NodeMap<Length> NodeMap;
    60       //typedef typename ResGraphType::template NodeMap<Length> NodeMap;
    61       typedef typename Graph::template NodeMap<Length> NodeMap;
    61       typedef typename Graph::template NodeMap<Length> NodeMap;
    62       const ResGraphType& G;
    62       const ResGraphType& res_graph;
    63       //      const EdgeIntMap& rev;
    63       //      const EdgeIntMap& rev;
    64       const LengthMap &ol;
    64       const LengthMap &ol;
    65       const NodeMap &pot;
    65       const NodeMap &pot;
    66     public :
    66     public :
    67       typedef typename LengthMap::KeyType KeyType;
    67       typedef typename LengthMap::KeyType KeyType;
    68       typedef typename LengthMap::ValueType ValueType;
    68       typedef typename LengthMap::ValueType ValueType;
    69 	
    69 	
    70       ValueType operator[](typename ResGraphType::Edge e) const {     
    70       ValueType operator[](typename ResGraphType::Edge e) const {     
    71 	if (G.forward(e))
    71 	if (res_graph.forward(e))
    72 	  return  ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
    72 	  return  ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);   
    73 	else
    73 	else
    74 	  return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
    74 	  return -ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);   
    75       }     
    75       }     
    76 	
    76 	
    77       ModLengthMap(const ResGraphType& _G,
    77       ModLengthMap(const ResGraphType& _res_graph,
    78 		   const LengthMap &o,  const NodeMap &p) : 
    78 		   const LengthMap &o,  const NodeMap &p) : 
    79 	G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 
    79 	res_graph(_res_graph), /*rev(_rev),*/ ol(o), pot(p){}; 
    80     };//ModLengthMap
    80     };//ModLengthMap
    81 
    81 
    82 
    82 
    83   protected:
    83   protected:
    84     
    84     
    85     //Input
    85     //Input
    86     const Graph& G;
    86     const Graph& graph;
    87     const LengthMap& length;
    87     const LengthMap& length;
    88     const SupplyDemandMap& supply_demand;//supply or demand of nodes
    88     const SupplyDemandMap& supply_demand;//supply or demand of nodes
    89 
    89 
    90 
    90 
    91     //auxiliary variables
    91     //auxiliary variables
   102 
   102 
   103 
   103 
   104   public :
   104   public :
   105 
   105 
   106 
   106 
   107     MinCostFlow(Graph& _G, LengthMap& _length, SupplyDemandMap& _supply_demand) : G(_G), 
   107     MinCostFlow(Graph& _graph, LengthMap& _length, SupplyDemandMap& _supply_demand) : graph(_graph), 
   108       length(_length), supply_demand(_supply_demand), flow(_G), potential(_G){ }
   108       length(_length), supply_demand(_supply_demand), flow(_graph), potential(_graph){ }
   109 
   109 
   110     
   110     
   111     ///Runs the algorithm.
   111     ///Runs the algorithm.
   112 
   112 
   113     ///Runs the algorithm.
   113     ///Runs the algorithm.
   114 
   114 
   115     ///\todo May be it does make sense to be able to start with a nonzero 
   115     ///\todo May be it does make sense to be able to start with a nonzero 
   116     /// feasible primal-dual solution pair as well.
   116     /// feasible primal-dual solution pair as well.
   117     int run() {
   117     void run() {
   118 
   118 
   119       //Resetting variables from previous runs
   119       //Resetting variables from previous runs
   120       //total_length = 0;
   120       //total_length = 0;
   121 
   121 
   122       typedef typename Graph::template NodeMap<int> HeapMap;
   122       typedef typename Graph::template NodeMap<int> HeapMap;
   123       typedef Heap< Node, SupplyDemand, typename Graph::template NodeMap<int>,
   123       typedef Heap< Node, SupplyDemand, typename Graph::template NodeMap<int>,
   124 	std::greater<SupplyDemand> > 	HeapType;
   124 	std::greater<SupplyDemand> > 	HeapType;
   125 
   125 
   126       //A heap for the excess nodes
   126       //A heap for the excess nodes
   127       HeapMap excess_nodes_map(G,-1);
   127       HeapMap excess_nodes_map(graph,-1);
   128       HeapType excess_nodes(excess_nodes_map);
   128       HeapType excess_nodes(excess_nodes_map);
   129 
   129 
   130       //A heap for the deficit nodes
   130       //A heap for the deficit nodes
   131       HeapMap deficit_nodes_map(G,-1);
   131       HeapMap deficit_nodes_map(graph,-1);
   132       HeapType deficit_nodes(deficit_nodes_map);
   132       HeapType deficit_nodes(deficit_nodes_map);
   133 
   133 
   134       //A container to store nonabundant arcs
   134       //A container to store nonabundant arcs
   135       list<Edge> nonabundant_arcs;
   135       list<Edge> nonabundant_arcs;
   136       
   136 
   137       FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
   137 	
       
   138       FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
   138 	flow.set(e,0);
   139 	flow.set(e,0);
   139 	nonabundant_arcs.push_back(e);
   140 	nonabundant_arcs.push_back(e);
   140       }
   141       }
   141 
   142 
   142       //Initial value for delta
   143       //Initial value for delta
   143       SupplyDemand delta = 0;
   144       SupplyDemand delta = 0;
   144 
   145 
   145       typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
   146       typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
   146 
   147 
   147       //A union-find structure to store the abundant components
   148       //A union-find structure to store the abundant components
   148       UFE::MapType abund_comp_map(G);
   149       UFE::MapType abund_comp_map(graph);
   149       UFE abundant_components(abund_comp_map);
   150       UFE abundant_components(abund_comp_map);
   150 
   151 
   151 
   152 
   152 
   153 
   153       FOR_EACH_LOC(typename Graph::NodeIt, n, G){
   154       FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
   154        	excess_deficit.set(n,supply_demand[n]);
   155        	excess_deficit.set(n,supply_demand[n]);
   155 	//A supply node
   156 	//A supply node
   156 	if (excess_deficit[n] > 0){
   157 	if (excess_deficit[n] > 0){
   157 	  excess_nodes.push(n,excess_deficit[n]);
   158 	  excess_nodes.push(n,excess_deficit[n]);
   158 	}
   159 	}
   172 
   173 
   173       //It'll be allright as an initial value, though this value 
   174       //It'll be allright as an initial value, though this value 
   174       //can be the maximum deficit here
   175       //can be the maximum deficit here
   175       SupplyDemand max_excess = delta;
   176       SupplyDemand max_excess = delta;
   176       
   177       
       
   178       //ConstMap<Edge,SupplyDemand> ConstEdgeMap;
       
   179 
   177       //We need a residual graph which is uncapacitated
   180       //We need a residual graph which is uncapacitated
   178       ResGraphType res_graph(G, flow);
   181       ResGraphType res_graph(graph, flow);
   179 
   182       
   180 
   183       //An EdgeMap to tell which arcs are abundant
       
   184       template typename Graph::EdgeMap<bool> abundant_arcs(graph);
       
   185 
       
   186       //Let's construct the sugraph consisting only of the abundant edges
       
   187       typedef ConstMap< typename Graph::Node, bool > ConstNodeMap;
       
   188       ConstNodeMap const_true_map(true);
       
   189       typedef SubGraphWrapper< Graph, ConstNodeMap, 
       
   190 	 template typename Graph::EdgeMap<bool> > 
       
   191 	AbundantGraph;
       
   192       AbundantGraph abundant_graph(graph, const_true_map, abundant_arcs );
       
   193       
       
   194       //Let's construct the residual graph for the abundant graph
       
   195       typedef ResGraphWrapper<const AbundantGraph,int,CapacityMap,EdgeIntMap> 
       
   196 	ResAbGraph;
       
   197       //Again uncapacitated
       
   198       ResAbGraph res_ab_graph(abundant_graph, flow);
       
   199       
       
   200       //We need things for the bfs
       
   201       typename ResAbGraph::NodeMap<bool> bfs_reached(res_ab_graph);
       
   202       typename ResAbGraph::NodeMap<typename ResAbGraph::Edge> 
       
   203 	bfs_pred(res_ab_graph); 
       
   204       NullMap<typename ResAbGraph::Node, int> bfs_dist_dummy(res_ab_graph);
       
   205       //We want to run bfs-es (more) on this graph 'res_ab_graph'
       
   206       Bfs < ResAbGraph , 
       
   207 	typename ResAbGraph::NodeMap<bool>, 
       
   208 	typename ResAbGraph::NodeMap<typename ResAbGraph::Edge>,
       
   209 	NullMap<typename ResAbGraph::Node, int> > 
       
   210 	bfs(res_ab_graph, bfs_reached, bfs_pred, bfs_dist_dummy);
   181       
   211       
   182       ModLengthMap mod_length(res_graph, length, potential);
   212       ModLengthMap mod_length(res_graph, length, potential);
   183 
   213 
   184       Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
   214       Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
   185 
   215 
   203 	    if (flow[i]>=buf){
   233 	    if (flow[i]>=buf){
   204 	      Node a = abundant_components.find(res_graph.head(i));
   234 	      Node a = abundant_components.find(res_graph.head(i));
   205 	      Node b = abundant_components.find(res_graph.tail(i));
   235 	      Node b = abundant_components.find(res_graph.tail(i));
   206 	      //Merge
   236 	      //Merge
   207 	      if (a != b){
   237 	      if (a != b){
   208 		//Find path and augment
       
   209 		//!!!
       
   210 		//Find path and augment
       
   211 		abundant_components.join(a,b);
   238 		abundant_components.join(a,b);
       
   239 		//We want to push the smaller
       
   240 		//Which has greater absolut value excess/deficit
       
   241 		Node root=(abs(excess_deficit[a])>abs(excess_deficit[b]))?a:b;
       
   242 		//Which is the other
       
   243 		Node non_root = ( a == root ) ? b : a ;
       
   244 		abundant_components.makeRep(root);
       
   245 		SupplyDemand qty_to_augment = abs(excess_deficit[non_root]); 
       
   246 		//Push the positive value
       
   247 		if (excess_deficit[non_root] < 0)
       
   248 		  swap(root, non_root);
       
   249 		//If the non_root node has excess/deficit at all
       
   250 		if (qty_to_augment>0){
       
   251 		  //Find path and augment
       
   252 		  bfs.run(non_root);
       
   253 		  //root should be reached
       
   254 		  
       
   255 		  //Augmenting on the found path
       
   256 		  Node n=root;
       
   257 		  ResGraphEdge e;
       
   258 		  while (n!=non_root){
       
   259 		    e = bfs_pred(n);
       
   260 		    n = res_graph.tail(e);
       
   261 		    res_graph.augment(e,qty_to_augment);
       
   262 		  }
       
   263 	  
       
   264 		  //We know that non_root had positive excess
       
   265 		  excess_nodes[non_root] -= qty_to_augment;
       
   266 		  //But what about root node
       
   267 		  //It might have been positive and so became larger
       
   268 		  if (excess_deficit[root]>0){
       
   269 		    excess_nodes[root] += qty_to_augment;
       
   270 		  }
       
   271 		  else{
       
   272 		    //Or negative but not turned into positive
       
   273 		    deficit_nodes[root] -= qty_to_augment;
       
   274 		  }
       
   275 
       
   276 		  //Update the excess_deficit map
       
   277 		  excess_deficit[non_root] -= qty_to_augment;
       
   278 		  excess_deficit[root] += qty_to_augment;
       
   279 
       
   280 		  
       
   281 		}
   212 	      }
   282 	      }
   213 	      //What happens to i?
   283 	      //What happens to i?
   214 	      nonabundant_arcs.erase(i);
   284 	      //Marci and Zsolt says I shouldn't do such things
       
   285 	      nonabundant_arcs.erase(i++);
       
   286 	      abundant_arcs[i] = true;
   215 	    }
   287 	    }
   216 	    else
   288 	    else
   217 	      ++i;
   289 	      ++i;
   218 	  }
   290 	  }
   219 	}
   291 	}
   220 
   292 
   221 
   293 
   222 	Node s = excess_nodes.top(); 
   294 	Node s = excess_nodes.top(); 
   223 	SupplyDemand max_excess = excess_nodes[s];
   295 	SupplyDemand max_excess = excess_nodes[s];
   224 	Node t = deficit_nodes.top(); 
   296 	Node t = deficit_nodes.top(); 
   225 	if (max_excess < dificit_nodes[t]){
   297 	if (max_excess < deficit_nodes[t]){
   226 	  max_excess = dificit_nodes[t];
   298 	  max_excess = deficit_nodes[t];
   227 	}
   299 	}
   228 
   300 
   229 
   301 
   230 	while(max_excess > 0){
   302 	while(max_excess > (n-1)*delta/n){
   231 
   303 	  
   232 	  
   304 	  
   233 	  //s es t valasztasa
   305 	  //s es t valasztasa
   234 
   306 	  
   235 	  //Dijkstra part	
   307 	  //Dijkstra part	
   236 	  dijkstra.run(s);
   308 	  dijkstra.run(s);
   237 
   309 	  
   238 	  /*We know from theory that t can be reached
   310 	  /*We know from theory that t can be reached
   239 	  if (!dijkstra.reached(t)){
   311 	  if (!dijkstra.reached(t)){
   240 	    //There are no k paths from s to t
   312 	    //There are no k paths from s to t
   241 	    break;
   313 	    break;
   242 	  };
   314 	  };
   261 	      total_length += length[e];
   333 	      total_length += length[e];
   262 	    else 
   334 	    else 
   263 	      total_length -= length[e];	    
   335 	      total_length -= length[e];	    
   264 	    */
   336 	    */
   265 	  }
   337 	  }
       
   338 	  
       
   339 	  //Update the excess_deficit map
       
   340 	  excess_deficit[s] -= delta;
       
   341 	  excess_deficit[t] += delta;
       
   342 	  
   266 
   343 
   267 	  //Update the excess_nodes heap
   344 	  //Update the excess_nodes heap
   268 	  if (delta >= excess_nodes[s]){
   345 	  if (delta >= excess_nodes[s]){
   269 	    if (delta > excess_nodes[s])
   346 	    if (delta > excess_nodes[s])
   270 	      deficit_nodes.push(s,delta - excess_nodes[s]);
   347 	      deficit_nodes.push(s,delta - excess_nodes[s]);
   283 	  } 
   360 	  } 
   284 	  else{
   361 	  else{
   285 	    deficit_nodes[t] -= delta;
   362 	    deficit_nodes[t] -= delta;
   286 	  }
   363 	  }
   287 	  //Dijkstra part ends here
   364 	  //Dijkstra part ends here
       
   365 	  
       
   366 	  //Choose s and t again
       
   367 	  s = excess_nodes.top(); 
       
   368 	  max_excess = excess_nodes[s];
       
   369 	  t = deficit_nodes.top(); 
       
   370 	  if (max_excess < deficit_nodes[t]){
       
   371 	    max_excess = deficit_nodes[t];
       
   372 	  }
       
   373 
   288 	}
   374 	}
   289 
   375 
   290 	/*
   376 	/*
   291 	 * End of the delta scaling phase 
   377 	 * End of the delta scaling phase 
   292 	*/
   378 	*/
   295 	delta = delta / 2;
   381 	delta = delta / 2;
   296 
   382 
   297 	/*This is not necessary here
   383 	/*This is not necessary here
   298 	//Update the max_excess
   384 	//Update the max_excess
   299 	max_excess = 0;
   385 	max_excess = 0;
   300 	FOR_EACH_LOC(typename Graph::NodeIt, n, G){
   386 	FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
   301 	  if (max_excess < excess_deficit[n]){
   387 	  if (max_excess < excess_deficit[n]){
   302 	    max_excess = excess_deficit[n];
   388 	    max_excess = excess_deficit[n];
   303 	  }
   389 	  }
   304 	}
   390 	}
   305 	*/
   391 	*/
   334     ///
   420     ///
   335     ///\todo Is this OK here?
   421     ///\todo Is this OK here?
   336     bool checkComplementarySlackness(){
   422     bool checkComplementarySlackness(){
   337       Length mod_pot;
   423       Length mod_pot;
   338       Length fl_e;
   424       Length fl_e;
   339       FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
   425       FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
   340 	//C^{\Pi}_{i,j}
   426 	//C^{\Pi}_{i,j}
   341 	mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
   427 	mod_pot = length[e]-potential[graph.head(e)]+potential[graph.tail(e)];
   342 	fl_e = flow[e];
   428 	fl_e = flow[e];
   343 	//	std::cout << fl_e << std::endl;
   429 	//	std::cout << fl_e << std::endl;
   344 	if (0<fl_e && fl_e<capacity[e]){
   430 	if (0<fl_e && fl_e<capacity[e]){
   345 	  if (mod_pot != 0)
   431 	  if (mod_pot != 0)
   346 	    return false;
   432 	    return false;