diff options
author | fonsinchen <fonsinchen@openttd.org> | 2013-12-20 14:57:44 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2013-12-20 14:57:44 +0000 |
commit | ec492bfb7700b719e41553417cbe77c5d10549ae (patch) | |
tree | 3e32848d29e0a9326bb9ff373a2248fe7239ca68 | |
parent | 4818b72c759f3845a28b94d3f1fad9541d4e8304 (diff) | |
download | openttd-ec492bfb7700b719e41553417cbe77c5d10549ae.tar.xz |
(svn r26166) -Fix: Scale flows only after mapping to avoid rounding errors.
-rw-r--r-- | src/linkgraph/flowmapper.cpp | 15 | ||||
-rw-r--r-- | src/linkgraph/flowmapper.h | 13 | ||||
-rw-r--r-- | src/linkgraph/linkgraphschedule.cpp | 4 | ||||
-rw-r--r-- | src/station_base.h | 2 | ||||
-rw-r--r-- | src/station_cmd.cpp | 16 |
5 files changed, 42 insertions, 8 deletions
diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index b9aa9cd59..79e0f09f3 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -18,9 +18,6 @@ */ void FlowMapper::Run(LinkGraphJob &job) const { - /* Time the graph has been running without being compressed. */ - uint runtime = job.JoinDate() - job.Settings().recalc_time - job.LastCompression(); - for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { Node prev_node = job[node_id]; StationID prev = prev_node.Station(); @@ -29,8 +26,6 @@ void FlowMapper::Run(LinkGraphJob &job) const Path *path = *i; uint flow = path->GetFlow(); if (flow == 0) break; - /* compress to monthly value */ - flow = max(1U, flow * 30 / runtime); Node node = job[path->GetNode()]; StationID via = node.Station(); StationID origin = job[path->GetOrigin()].Station(); @@ -51,7 +46,15 @@ void FlowMapper::Run(LinkGraphJob &job) const for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { /* Remove local consumption shares marked as invalid. */ Node node = job[node_id]; - node.Flows().FinalizeLocalConsumption(node.Station()); + FlowStatMap &flows = node.Flows(); + flows.FinalizeLocalConsumption(node.Station()); + if (this->scale) { + /* Scale by time the graph has been running without being compressed. */ + uint runtime = job.JoinDate() - job.Settings().recalc_time - job.LastCompression(); + for (FlowStatMap::iterator i = flows.begin(); i != flows.end(); ++i) { + i->second.ScaleToMonthly(runtime); + } + } /* Clear paths. */ PathList &paths = node.Paths(); for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { diff --git a/src/linkgraph/flowmapper.h b/src/linkgraph/flowmapper.h index 6dc84ffea..6f874e5b3 100644 --- a/src/linkgraph/flowmapper.h +++ b/src/linkgraph/flowmapper.h @@ -23,12 +23,25 @@ */ class FlowMapper : public ComponentHandler { public: + + /** + * Create a flow mapper. + * @param scale Whether the flow mapper should scale all flows to monthly + * values. Only do that on the very last flow mapping. + */ + FlowMapper(bool scale) : scale(scale) {} virtual void Run(LinkGraphJob &job) const; /** * Virtual destructor has to be defined because of virtual Run(). */ virtual ~FlowMapper() {} +private: + + /** + * Whether the flow mapper should scale all flows to monthly values. + */ + const bool scale; }; #endif /* FLOWMAPPER_H_ */ diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 366a3c517..f056d7cfc 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -146,9 +146,9 @@ LinkGraphSchedule::LinkGraphSchedule() this->handlers[0] = new InitHandler; this->handlers[1] = new DemandHandler; this->handlers[2] = new MCFHandler<MCF1stPass>; - this->handlers[3] = new FlowMapper; + this->handlers[3] = new FlowMapper(false); this->handlers[4] = new MCFHandler<MCF2ndPass>; - this->handlers[5] = new FlowMapper; + this->handlers[5] = new FlowMapper(true); } /** diff --git a/src/station_base.h b/src/station_base.h index c0bb96cd9..a4ad69547 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -79,6 +79,8 @@ public: void ReleaseShare(StationID st); + void ScaleToMonthly(uint runtime); + /** * Get the actual shares as a const pointer so that they can be iterated * over. diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 6b158aaf1..6ef602b83 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -4290,6 +4290,22 @@ void FlowStat::ReleaseShare(StationID st) } /** + * Scale all shares from link graph's runtime to monthly values. + * @param runtime Time the link graph has been running without compression. + */ +void FlowStat::ScaleToMonthly(uint runtime) +{ + SharesMap new_shares; + uint share = 0; + for (SharesMap::iterator i = this->shares.begin(); i != this->shares.end(); ++i) { + share = max(share + 1, i->first * 30 / runtime); + new_shares[share] = i->second; + if (this->unrestricted == i->first) this->unrestricted = share; + } + this->shares.swap(new_shares); +} + +/** * Add some flow from "origin", going via "via". * @param origin Origin of the flow. * @param via Next hop. |