mcf.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef MCF_H_
00013 #define MCF_H_
00014 
00015 #include "linkgraph.h"
00016 #include <vector>
00017 
00023 class DistanceAnnotation : public Path {
00024 public:
00025   DistanceAnnotation(NodeID n, bool source = false) : Path(n, source) {}
00026 
00027   bool IsBetter(const DistanceAnnotation *base, uint cap, int free_cap, uint dist) const;
00028 
00033   FORCEINLINE  uint GetAnnotation() const {return this->distance;}
00034 
00035   struct comp {
00036     bool operator()(const DistanceAnnotation *x, const DistanceAnnotation *y) const;
00037   };
00038 };
00039 
00046 class CapacityAnnotation : public Path {
00047 public:
00048   CapacityAnnotation(NodeID n, bool source = false) : Path(n, source) {}
00049 
00050   bool IsBetter(const CapacityAnnotation *base, uint cap, int free_cap, uint dist) const;
00051 
00056   FORCEINLINE int GetAnnotation() const {return this->GetCapacityRatio();}
00057 
00058   struct comp {
00059     bool operator()(const CapacityAnnotation *x, const CapacityAnnotation *y) const;
00060   };
00061 };
00062 
00063 
00064 typedef std::vector<Path *> PathVector;
00065 
00069 class MultiCommodityFlow {
00070 protected:
00071   MultiCommodityFlow(LinkGraphComponent *graph) : graph(graph) {}
00072 
00073   template<class ANNOTATION> void Dijkstra(NodeID from, PathVector &paths, bool create_new_paths);
00074 
00075   uint PushFlow(Edge &edge, Path *path, uint accuracy, bool positive_cap);
00076 
00077   void CleanupPaths(NodeID source, PathVector &paths);
00078 
00079   LinkGraphComponent *graph; 
00080 };
00081 
00097 class MCF1stPass : public MultiCommodityFlow {
00098 private:
00099   bool EliminateCycles();
00100   bool EliminateCycles(PathVector &path, NodeID origin_id, NodeID next_id);
00101   void EliminateCycle(PathVector &path, Path *cycle_begin, uint flow);
00102   uint FindCycleFlow(const PathVector &path, const Path *cycle_begin);
00103 public:
00104   MCF1stPass(LinkGraphComponent *graph);
00105 };
00106 
00114 class MCF2ndPass : public MultiCommodityFlow {
00115 public:
00116   MCF2ndPass(LinkGraphComponent *graph);
00117 };
00118 
00123 template<class Tpass>
00124 class MCFHandler : public ComponentHandler {
00125 public:
00130   virtual void Run(LinkGraphComponent *graph) {Tpass pass(graph);}
00131 
00132   virtual ~MCFHandler() {}
00133 };
00134 
00135 #endif /* MCF_H_ */