From ec492bfb7700b719e41553417cbe77c5d10549ae Mon Sep 17 00:00:00 2001 From: fonsinchen Date: Fri, 20 Dec 2013 14:57:44 +0000 Subject: [PATCH] (svn r26166) -Fix: Scale flows only after mapping to avoid rounding errors. --- src/linkgraph/flowmapper.cpp | 15 +++++++++------ src/linkgraph/flowmapper.h | 13 +++++++++++++ src/linkgraph/linkgraphschedule.cpp | 4 ++-- src/station_base.h | 2 ++ 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 b9aa9cd59c..79e0f09f3f 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 6dc84ffea5..6f874e5b30 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 366a3c5177..f056d7cfcd 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; - this->handlers[3] = new FlowMapper; + this->handlers[3] = new FlowMapper(false); this->handlers[4] = new MCFHandler; - this->handlers[5] = new FlowMapper; + this->handlers[5] = new FlowMapper(true); } /** diff --git a/src/station_base.h b/src/station_base.h index c0bb96cd92..a4ad69547e 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 6b158aaf13..6ef602b83f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -4289,6 +4289,22 @@ void FlowStat::ReleaseShare(StationID st) assert(!this->shares.empty()); } +/** + * 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.