Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef LINKGRAPH_H
00013 #define LINKGRAPH_H
00014
00015 #include "../station_base.h"
00016 #include "../cargo_type.h"
00017 #include "../thread/thread.h"
00018 #include "../settings_type.h"
00019 #include "../date_func.h"
00020 #include "linkgraph_type.h"
00021 #include <list>
00022 #include <vector>
00023 #include <set>
00024
00025 struct SaveLoad;
00026 class Path;
00027
00028 typedef std::set<Path *> PathSet;
00029 typedef std::map<NodeID, Path *> PathViaMap;
00030 typedef std::map<StationID, int> FlowViaMap;
00031 typedef std::map<StationID, FlowViaMap> FlowMap;
00032
00038 class Node {
00039 public:
00040 uint supply;
00041 uint undelivered_supply;
00042 uint demand;
00043 StationID station;
00044 PathSet paths;
00045 FlowMap flows;
00046
00050 ~Node() { this->Init(); }
00051
00052 void Init(StationID st = INVALID_STATION, uint sup = 0, uint dem = 0);
00053 void ExportFlows(CargoID cargo);
00054
00055 private:
00056 void ExportFlows(FlowMap::iterator &it, FlowStatMap &station_flows, CargoID cargo);
00057 };
00058
00065 class Edge {
00066 public:
00067 uint distance;
00068 uint capacity;
00069 uint demand;
00070 uint unsatisfied_demand;
00071 uint flow;
00072 NodeID next_edge;
00073
00074 void Init(uint distance = 0, uint capacity = 0);
00075 };
00076
00083 class LinkGraphComponent {
00084 private:
00085 typedef std::vector<Node> NodeVector;
00086 typedef std::vector<std::vector<Edge> > EdgeMatrix;
00087
00088 public:
00089 LinkGraphComponent();
00090
00091 void Init(LinkGraphComponentID id);
00092
00099 inline Edge &GetEdge(NodeID from, NodeID to)
00100 {
00101 return this->edges[from][to];
00102 }
00103
00109 inline Node &GetNode(NodeID num)
00110 {
00111 return this->nodes[num];
00112 }
00113
00118 inline uint GetSize() const
00119 {
00120 return this->num_nodes;
00121 }
00122
00123 void SetSize();
00124
00125 NodeID AddNode(Station *st);
00126
00127 void AddEdge(NodeID from, NodeID to, uint capacity);
00128
00133 inline LinkGraphComponentID GetIndex() const
00134 {
00135 return this->index;
00136 }
00137
00142 inline CargoID GetCargo() const
00143 {
00144 return this->cargo;
00145 }
00146
00151 inline const LinkGraphSettings &GetSettings() const
00152 {
00153 return this->settings;
00154 }
00155
00161 inline NodeID GetFirstEdge(NodeID from) { return edges[from][from].next_edge; }
00162
00166 inline void Clear()
00167 {
00168 this->num_nodes = 0;
00169 }
00170
00171 protected:
00172 LinkGraphSettings settings;
00173 CargoID cargo;
00174 uint num_nodes;
00175 LinkGraphComponentID index;
00176 NodeVector nodes;
00177 EdgeMatrix edges;
00178 };
00179
00184 class ComponentHandler {
00185 public:
00189 virtual ~ComponentHandler() {}
00190
00196 virtual void Run(LinkGraphComponent *component) = 0;
00197 };
00198
00204 class LinkGraphJob : public LinkGraphComponent {
00205 private:
00206 typedef std::list<ComponentHandler *> HandlerList;
00207
00208 public:
00209
00210 LinkGraphJob() : thread(NULL) {}
00211
00215 ~LinkGraphJob()
00216 {
00217 this->Join();
00218 }
00219
00220 static void RunLinkGraphJob(void *j);
00221
00226 static void AddHandler(ComponentHandler *handler)
00227 {
00228 LinkGraphJob::_handlers.push_back(handler);
00229 }
00230
00231 static void ClearHandlers();
00232
00233 void SpawnThread();
00234
00235 void Join();
00236
00237 private:
00238 static HandlerList _handlers;
00239 ThreadObject *thread;
00240
00246 LinkGraphJob(const LinkGraphJob &other) : LinkGraphComponent(other) {NOT_REACHED();}
00247 };
00248
00252 class LinkGraph : public LinkGraphJob {
00253 public:
00254
00255
00256
00257 static const uint COMPONENTS_JOIN_TICK = 21;
00258 static const uint COMPONENTS_SPAWN_TICK = 58;
00259
00263 LinkGraph() : current_station_id(0) {}
00264
00265 void Init(CargoID cargo);
00266
00267 void NextComponent();
00268
00269 void Join();
00270
00271 private:
00272 StationID current_station_id;
00273
00274 friend const SaveLoad *GetLinkGraphDesc();
00275
00276 void CreateComponent(Station *first);
00277 };
00278
00282 class Path {
00283 public:
00284 Path(NodeID n, bool source = false);
00285
00287 inline NodeID GetNode() const { return this->node; }
00288
00290 inline NodeID GetOrigin() const { return this->origin; }
00291
00293 inline Path *GetParent() { return this->parent; }
00294
00296 inline uint GetCapacity() const { return this->capacity; }
00297
00299 inline int GetFreeCapacity() const { return this->free_capacity; }
00300
00308 inline static int GetCapacityRatio(int free, int total)
00309 {
00310 return (free << 4) / (total + 1);
00311 }
00312
00317 inline int GetCapacityRatio() const
00318 {
00319 return Path::GetCapacityRatio(this->free_capacity, this->capacity);
00320 }
00321
00323 inline uint GetDistance() const { return this->distance; }
00324
00326 inline void ReduceFlow(uint f) { this->flow -= f; }
00327
00329 inline void AddFlow(uint f) { this->flow += f; }
00330
00332 inline uint GetFlow() const { return this->flow; }
00333
00335 inline uint GetNumChildren() const { return this->num_children; }
00336
00340 inline void Detach()
00341 {
00342 if (this->parent != NULL) {
00343 this->parent->num_children--;
00344 this->parent = NULL;
00345 }
00346 }
00347
00348 uint AddFlow(uint f, LinkGraphComponent *graph, bool only_positive);
00349 void Fork(Path *base, uint cap, int free_cap, uint dist);
00350
00351 protected:
00352 uint distance;
00353 uint capacity;
00354 int free_capacity;
00355 uint flow;
00356 NodeID node;
00357 NodeID origin;
00358 uint num_children;
00359 Path *parent;
00360 };
00361
00362 void InitializeLinkGraphs();
00363 extern LinkGraph _link_graphs[NUM_CARGO];
00364
00365 #endif