00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef LINKGRAPH_H
00013 #define LINKGRAPH_H
00014
00015 #include "../core/pool_type.hpp"
00016 #include "../core/smallmap_type.hpp"
00017 #include "../core/smallmatrix_type.hpp"
00018 #include "../station_base.h"
00019 #include "../cargotype.h"
00020 #include "../date_func.h"
00021 #include "linkgraph_type.h"
00022
00023 struct SaveLoad;
00024 class LinkGraph;
00025
00030 typedef Pool<LinkGraph, LinkGraphID, 32, 0xFFFFFF> LinkGraphPool;
00032 extern LinkGraphPool _link_graph_pool;
00033
00040 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
00041 public:
00042
00048 struct BaseNode {
00049 uint supply;
00050 uint demand;
00051 StationID station;
00052 Date last_update;
00053 void Init(StationID st = INVALID_STATION, uint demand = 0);
00054 };
00055
00062 struct BaseEdge {
00063 uint distance;
00064 uint capacity;
00065 uint usage;
00066 Date last_update;
00067 NodeID next_edge;
00068 void Init(uint distance = 0);
00069 };
00070
00075 template<typename Tedge>
00076 class EdgeWrapper {
00077 protected:
00078 Tedge &edge;
00079
00080 public:
00081
00086 EdgeWrapper (Tedge &edge) : edge(edge) {}
00087
00092 uint Capacity() const { return this->edge.capacity; }
00093
00098 uint Usage() const { return this->edge.usage; }
00099
00104 uint Distance() const { return this->edge.distance; }
00105
00110 Date LastUpdate() const { return this->edge.last_update; }
00111 };
00112
00118 template<typename Tnode, typename Tedge>
00119 class NodeWrapper {
00120 protected:
00121 Tnode &node;
00122 Tedge *edges;
00123 NodeID index;
00124
00125 public:
00126
00133 NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
00134 edges(edges), index(index) {}
00135
00140 uint Supply() const { return this->node.supply; }
00141
00146 uint Demand() const { return this->node.demand; }
00147
00152 StationID Station() const { return this->node.station; }
00153
00158 Date LastUpdate() const { return this->node.last_update; }
00159 };
00160
00168 template <class Tedge, class Tedge_wrapper, class Titer>
00169 class BaseEdgeIterator {
00170 protected:
00171 Tedge *base;
00172 NodeID current;
00173
00180 class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
00181 public:
00182
00187 FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
00188
00193 SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
00194 };
00195
00196 public:
00202 BaseEdgeIterator (Tedge *base, NodeID current) :
00203 base(base),
00204 current(current == INVALID_NODE ? current : base[current].next_edge)
00205 {}
00206
00211 Titer &operator++()
00212 {
00213 this->current = this->base[this->current].next_edge;
00214 return static_cast<Titer &>(*this);
00215 }
00216
00221 Titer operator++(int)
00222 {
00223 Titer ret(static_cast<Titer &>(*this));
00224 this->current = this->base[this->current].next_edge;
00225 return ret;
00226 }
00227
00235 template<class Tother>
00236 bool operator==(const Tother &other)
00237 {
00238 return this->base == other.base && this->current == other.current;
00239 }
00240
00248 template<class Tother>
00249 bool operator!=(const Tother &other)
00250 {
00251 return this->base != other.base || this->current != other.current;
00252 }
00253
00258 SmallPair<NodeID, Tedge_wrapper> operator*() const
00259 {
00260 return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
00261 }
00262
00267 FakePointer operator->() const {
00268 return FakePointer(this->operator*());
00269 }
00270 };
00271
00275 typedef EdgeWrapper<const BaseEdge> ConstEdge;
00276
00280 class Edge : public EdgeWrapper<BaseEdge> {
00281 public:
00286 Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
00287 void Update(uint capacity, uint usage);
00288 };
00289
00294 class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
00295 public:
00301 ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
00302 BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
00303 };
00304
00309 class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
00310 public:
00316 EdgeIterator(BaseEdge *edges, NodeID current) :
00317 BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
00318 };
00319
00324 class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
00325 public:
00331 ConstNode(const LinkGraph *lg, NodeID node) :
00332 NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
00333 {}
00334
00341 ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
00342
00347 ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
00348
00353 ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
00354 };
00355
00359 class Node : public NodeWrapper<BaseNode, BaseEdge> {
00360 public:
00366 Node(LinkGraph *lg, NodeID node) :
00367 NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
00368 {}
00369
00376 Edge operator[](NodeID to) { return Edge(this->edges[to]); }
00377
00382 EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
00383
00388 EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
00389
00394 void UpdateSupply(uint supply)
00395 {
00396 this->node.supply += supply;
00397 this->node.last_update = _date;
00398 }
00399
00404 void SetDemand(uint demand)
00405 {
00406 this->node.demand = demand;
00407 }
00408
00409 void AddEdge(NodeID to, uint capacity, uint usage = 0);
00410 void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
00411 void RemoveEdge(NodeID to);
00412 };
00413
00414 typedef SmallVector<BaseNode, 16> NodeVector;
00415 typedef SmallMatrix<BaseEdge> EdgeMatrix;
00416
00418 static const uint MIN_TIMEOUT_DISTANCE = 48;
00419
00421 static const uint COMPRESSION_INTERVAL = 256;
00422
00431 inline static uint Scale(uint val, uint target_age, uint orig_age)
00432 {
00433 return val > 0 ? max(1U, val * target_age / orig_age) : 0;
00434 }
00435
00437 LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
00442 LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
00443
00444 void Init(uint size);
00445 void ShiftDates(int interval);
00446 void Compress();
00447 void Merge(LinkGraph *other);
00448
00449
00450
00451
00452
00453
00454
00455
00456
00462 inline Node operator[](NodeID num) { return Node(this, num); }
00463
00469 inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
00470
00475 inline uint Size() const { return this->nodes.Length(); }
00476
00481 inline Date LastCompression() const { return this->last_compression; }
00482
00487 inline CargoID Cargo() const { return this->cargo; }
00488
00494 inline uint Monthly(uint base) const
00495 {
00496 return base * 30 / (_date - this->last_compression + 1);
00497 }
00498
00499 NodeID AddNode(const Station *st);
00500 void RemoveNode(NodeID id);
00501
00502 protected:
00503 friend class LinkGraph::ConstNode;
00504 friend class LinkGraph::Node;
00505 friend const SaveLoad *GetLinkGraphDesc();
00506 friend const SaveLoad *GetLinkGraphJobDesc();
00507 friend void SaveLoad_LinkGraph(LinkGraph &lg);
00508
00509 CargoID cargo;
00510 Date last_compression;
00511 NodeVector nodes;
00512 EdgeMatrix edges;
00513 };
00514
00515 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
00516
00517 #endif