00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef LINKGRAPHJOB_H
00013 #define LINKGRAPHJOB_H
00014
00015 #include "../thread/thread.h"
00016 #include "linkgraph.h"
00017 #include <list>
00018
00019 class LinkGraphJob;
00020 class Path;
00021 typedef std::list<Path *> PathList;
00022
00024 typedef Pool<LinkGraphJob, LinkGraphJobID, 32, 0xFFFFFF> LinkGraphJobPool;
00026 extern LinkGraphJobPool _link_graph_job_pool;
00027
00031 class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
00032 private:
00036 struct EdgeAnnotation {
00037 uint demand;
00038 uint unsatisfied_demand;
00039 uint flow;
00040 void Init();
00041 };
00042
00046 struct NodeAnnotation {
00047 uint undelivered_supply;
00048 PathList paths;
00049 FlowStatMap flows;
00050 void Init(uint supply);
00051 };
00052
00053 typedef SmallVector<NodeAnnotation, 16> NodeAnnotationVector;
00054 typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix;
00055
00056 friend const SaveLoad *GetLinkGraphJobDesc();
00057 friend class LinkGraphSchedule;
00058
00059 protected:
00060 const LinkGraph link_graph;
00061 const LinkGraphSettings settings;
00062 ThreadObject *thread;
00063 const Date join_date;
00064 NodeAnnotationVector nodes;
00065 EdgeAnnotationMatrix edges;
00066
00067 public:
00068
00073 class Edge : public LinkGraph::ConstEdge {
00074 private:
00075 EdgeAnnotation &anno;
00076 public:
00082 Edge(const LinkGraph::BaseEdge &edge, EdgeAnnotation &anno) :
00083 LinkGraph::ConstEdge(edge), anno(anno) {}
00084
00089 uint Demand() const { return this->anno.demand; }
00090
00095 uint UnsatisfiedDemand() const { return this->anno.unsatisfied_demand; }
00096
00101 uint Flow() const { return this->anno.flow; }
00102
00107 void AddFlow(uint flow) { this->anno.flow += flow; }
00108
00113 void RemoveFlow(uint flow)
00114 {
00115 assert(flow <= this->anno.flow);
00116 this->anno.flow -= flow;
00117 }
00118
00123 void AddDemand(uint demand)
00124 {
00125 this->anno.demand += demand;
00126 this->anno.unsatisfied_demand += demand;
00127 }
00128
00133 void SatisfyDemand(uint demand)
00134 {
00135 assert(demand <= this->anno.unsatisfied_demand);
00136 this->anno.unsatisfied_demand -= demand;
00137 }
00138 };
00139
00143 class EdgeIterator : public LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator> {
00144 EdgeAnnotation *base_anno;
00145 public:
00152 EdgeIterator(const LinkGraph::BaseEdge *base, EdgeAnnotation *base_anno, NodeID current) :
00153 LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator>(base, current),
00154 base_anno(base_anno) {}
00155
00161 SmallPair<NodeID, Edge> operator*() const
00162 {
00163 return SmallPair<NodeID, Edge>(this->current, Edge(this->base[this->current], this->base_anno[this->current]));
00164 }
00165
00171 FakePointer operator->() const {
00172 return FakePointer(this->operator*());
00173 }
00174 };
00175
00180 class Node : public LinkGraph::ConstNode {
00181 private:
00182 NodeAnnotation &node_anno;
00183 EdgeAnnotation *edge_annos;
00184 public:
00185
00191 Node (LinkGraphJob *lgj, NodeID node) :
00192 LinkGraph::ConstNode(&lgj->link_graph, node),
00193 node_anno(lgj->nodes[node]), edge_annos(lgj->edges[node])
00194 {}
00195
00202 Edge operator[](NodeID to) const { return Edge(this->edges[to], this->edge_annos[to]); }
00203
00209 EdgeIterator Begin() const { return EdgeIterator(this->edges, this->edge_annos, index); }
00210
00216 EdgeIterator End() const { return EdgeIterator(this->edges, this->edge_annos, INVALID_NODE); }
00217
00222 uint UndeliveredSupply() const { return this->node_anno.undelivered_supply; }
00223
00228 FlowStatMap &Flows() { return this->node_anno.flows; }
00229
00234 const FlowStatMap &Flows() const { return this->node_anno.flows; }
00235
00240 PathList &Paths() { return this->node_anno.paths; }
00241
00246 const PathList &Paths() const { return this->node_anno.paths; }
00247
00253 void DeliverSupply(NodeID to, uint amount)
00254 {
00255 this->node_anno.undelivered_supply -= amount;
00256 (*this)[to].AddDemand(amount);
00257 }
00258 };
00259
00264 LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL),
00265 join_date(INVALID_DATE) {}
00266
00267 LinkGraphJob(const LinkGraph &orig);
00268 ~LinkGraphJob();
00269
00270 void Init();
00271
00276 inline bool IsFinished() const { return this->join_date <= _date; }
00277
00282 inline Date JoinDate() const { return join_date; }
00283
00288 inline const LinkGraphSettings &Settings() const { return this->settings; }
00289
00295 inline Node operator[](NodeID num) { return Node(this, num); }
00296
00301 inline uint Size() const { return this->link_graph.Size(); }
00302
00307 inline CargoID Cargo() const { return this->link_graph.Cargo(); }
00308
00313 inline Date LastCompression() const { return this->link_graph.LastCompression(); }
00314
00319 inline LinkGraphID LinkGraphIndex() const { return this->link_graph.index; }
00320
00325 inline const LinkGraph &Graph() const { return this->link_graph; }
00326 };
00327
00328 #define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0)
00329
00333 class Path {
00334 public:
00335 Path(NodeID n, bool source = false);
00336
00338 inline NodeID GetNode() const { return this->node; }
00339
00341 inline NodeID GetOrigin() const { return this->origin; }
00342
00344 inline Path *GetParent() { return this->parent; }
00345
00347 inline uint GetCapacity() const { return this->capacity; }
00348
00350 inline int GetFreeCapacity() const { return this->free_capacity; }
00351
00359 inline static int GetCapacityRatio(int free, int total)
00360 {
00361 return (free << 4) / (total + 1);
00362 }
00363
00368 inline int GetCapacityRatio() const
00369 {
00370 return Path::GetCapacityRatio(this->free_capacity, this->capacity);
00371 }
00372
00374 inline uint GetDistance() const { return this->distance; }
00375
00377 inline void ReduceFlow(uint f) { this->flow -= f; }
00378
00380 inline void AddFlow(uint f) { this->flow += f; }
00381
00383 inline uint GetFlow() const { return this->flow; }
00384
00386 inline uint GetNumChildren() const { return this->num_children; }
00387
00391 inline void Detach()
00392 {
00393 if (this->parent != NULL) {
00394 this->parent->num_children--;
00395 this->parent = NULL;
00396 }
00397 }
00398
00399 uint AddFlow(uint f, LinkGraphJob &job, uint max_saturation);
00400 void Fork(Path *base, uint cap, int free_cap, uint dist);
00401
00402 protected:
00403 uint distance;
00404 uint capacity;
00405 int free_capacity;
00406 uint flow;
00407 NodeID node;
00408 NodeID origin;
00409 uint num_children;
00410 Path *parent;
00411 };
00412
00413 #endif