From 4d3da0cf14ed8bdb31a0bd2923d1f05c99c92e26 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 3 Jan 2023 01:27:16 +0100 Subject: [PATCH] Codechange: [Linkgraph] Drop node/edge wrappers from LinkGraphJob. --- src/linkgraph/demands.cpp | 26 +-- src/linkgraph/flowmapper.cpp | 33 ++-- src/linkgraph/linkgraph.h | 8 +- src/linkgraph/linkgraphjob.cpp | 29 +-- src/linkgraph/linkgraphjob.h | 294 ++++++++++-------------------- src/linkgraph/linkgraphjob_base.h | 5 +- src/linkgraph/mcf.cpp | 35 ++-- 7 files changed, 166 insertions(+), 264 deletions(-) diff --git a/src/linkgraph/demands.cpp b/src/linkgraph/demands.cpp index 6fc529c497..7d7e182132 100644 --- a/src/linkgraph/demands.cpp +++ b/src/linkgraph/demands.cpp @@ -36,7 +36,7 @@ public: */ inline void AddNode(const Node &node) { - this->supply_sum += node.Supply(); + this->supply_sum += node.base.supply; } /** @@ -57,7 +57,7 @@ public: */ inline uint EffectiveSupply(const Node &from, const Node &to) { - return std::max(from.Supply() * std::max(1U, to.Supply()) * this->mod_size / 100 / this->demand_per_node, 1U); + return std::max(from.base.supply * std::max(1U, to.base.supply) * this->mod_size / 100 / this->demand_per_node, 1U); } /** @@ -69,7 +69,7 @@ public: */ inline bool HasDemandLeft(const Node &to) { - return (to.Supply() == 0 || to.UndeliveredSupply() > 0) && to.Demand() > 0; + return (to.base.supply == 0 || to.undelivered_supply > 0) && to.base.demand > 0; } void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw); @@ -108,7 +108,7 @@ public: */ inline uint EffectiveSupply(const Node &from, const Node &) { - return from.Supply(); + return from.base.supply; } /** @@ -116,7 +116,7 @@ public: * nodes always accept as long as their demand > 0. * @param to The node to be checked. */ - inline bool HasDemandLeft(const Node &to) { return to.Demand() > 0; } + inline bool HasDemandLeft(const Node &to) { return to.base.demand > 0; } }; /** @@ -129,9 +129,9 @@ public: */ void SymmetricScaler::SetDemands(LinkGraphJob &job, NodeID from_id, NodeID to_id, uint demand_forw) { - if (job[from_id].Demand() > 0) { + if (job[from_id].base.demand > 0) { uint demand_back = demand_forw * this->mod_size / 100; - uint undelivered = job[to_id].UndeliveredSupply(); + uint undelivered = job[to_id].undelivered_supply; if (demand_back > undelivered) { demand_back = undelivered; demand_forw = std::max(1U, demand_back * 100 / this->mod_size); @@ -170,11 +170,11 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) for (NodeID node = 0; node < job.Size(); node++) { scaler.AddNode(job[node]); - if (job[node].Supply() > 0) { + if (job[node].base.supply > 0) { supplies.push(node); num_supplies++; } - if (job[node].Demand() > 0) { + if (job[node].base.demand > 0) { demands.push(node); num_demands++; } @@ -209,7 +209,7 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) /* Scale the distance by mod_dist around max_distance */ int32 distance = this->max_distance - (this->max_distance - - (int32)DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY())) * + (int32)DistanceMaxPlusManhattan(job[from_id].base.xy, job[to_id].base.xy)) * this->mod_dist / 100; /* Scale the accuracy by distance around accuracy / 2 */ @@ -230,7 +230,7 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) demand_forw = 1; } - demand_forw = std::min(demand_forw, job[from_id].UndeliveredSupply()); + demand_forw = std::min(demand_forw, job[from_id].undelivered_supply); scaler.SetDemands(job, from_id, to_id, demand_forw); @@ -240,10 +240,10 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) num_demands--; } - if (job[from_id].UndeliveredSupply() == 0) break; + if (job[from_id].undelivered_supply == 0) break; } - if (job[from_id].UndeliveredSupply() != 0) { + if (job[from_id].undelivered_supply != 0) { supplies.push(from_id); } else { num_supplies--; diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index 2e0257fc1b..eb86d5e32e 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -19,35 +19,33 @@ void FlowMapper::Run(LinkGraphJob &job) const { for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { - Node prev_node = job[node_id]; - StationID prev = prev_node.Station(); - PathList &paths = prev_node.Paths(); - for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { - Path *path = *i; + Node &prev_node = job[node_id]; + StationID prev = prev_node.base.station; + for (const Path *path : prev_node.paths) { uint flow = path->GetFlow(); if (flow == 0) break; - Node node = job[path->GetNode()]; - StationID via = node.Station(); - StationID origin = job[path->GetOrigin()].Station(); + Node &node = job[path->GetNode()]; + StationID via = node.base.station; + StationID origin = job[path->GetOrigin()].base.station; assert(prev != via && via != origin); /* Mark all of the flow for local consumption at "first". */ - node.Flows().AddFlow(origin, via, flow); + node.flows.AddFlow(origin, via, flow); if (prev != origin) { /* Pass some of the flow marked for local consumption at "prev" on * to this node. */ - prev_node.Flows().PassOnFlow(origin, via, flow); + prev_node.flows.PassOnFlow(origin, via, flow); } else { /* Prev node is origin. Simply add flow. */ - prev_node.Flows().AddFlow(origin, via, flow); + prev_node.flows.AddFlow(origin, via, flow); } } } for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { /* Remove local consumption shares marked as invalid. */ - Node node = job[node_id]; - FlowStatMap &flows = node.Flows(); - flows.FinalizeLocalConsumption(node.Station()); + Node &node = job[node_id]; + FlowStatMap &flows = node.flows; + flows.FinalizeLocalConsumption(node.base.station); if (this->scale) { /* Scale by time the graph has been running without being compressed. Add 1 to avoid * division by 0 if spawn date == last compression date. This matches @@ -58,10 +56,7 @@ void FlowMapper::Run(LinkGraphJob &job) const } } /* Clear paths. */ - PathList &paths = node.Paths(); - for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { - delete *i; - } - paths.clear(); + for (Path *i : node.paths) delete i; + node.paths.clear(); } } diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 6403168144..cd9c176930 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -50,6 +50,12 @@ public: BaseEdge(NodeID dest_node = INVALID_NODE); + /** + * Get edge's average travel time. + * @return Travel time, in ticks. + */ + uint32 TravelTime() const { return this->travel_time_sum / this->capacity; } + /** Comparison operator based on \c dest_node. */ bool operator <(const BaseEdge &rhs) const { @@ -117,7 +123,7 @@ public: * Get edge's average travel time. * @return Travel time, in ticks. */ - uint32 TravelTime() const { return this->edge.travel_time_sum / this->edge.capacity; } + uint32 TravelTime() const { return this->edge.TravelTime(); } /** * Get the date of the last update to the edge's unrestricted capacity. diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 763485ce07..2a59ea9948 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -50,7 +50,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) : void LinkGraphJob::EraseFlows(NodeID from) { for (NodeID node_id = 0; node_id < this->Size(); ++node_id) { - (*this)[node_id].Flows().erase(from); + (*this)[node_id].flows.erase(from); } } @@ -103,10 +103,10 @@ LinkGraphJob::~LinkGraphJob() uint16 size = this->Size(); for (NodeID node_id = 0; node_id < size; ++node_id) { - Node from = (*this)[node_id]; + NodeAnnotation &from = this->nodes[node_id]; /* The station can have been deleted. Remove all flows originating from it then. */ - Station *st = Station::GetIfValid(from.Station()); + Station *st = Station::GetIfValid(from.base.station); if (st == nullptr) { this->EraseFlows(node_id); continue; @@ -121,23 +121,24 @@ LinkGraphJob::~LinkGraphJob() } LinkGraph *lg = LinkGraph::Get(ge.link_graph); - FlowStatMap &flows = from.Flows(); + FlowStatMap &flows = from.flows; - for (EdgeIterator it(from.Begin()); it != from.End(); ++it) { - if (it->second.Flow() == 0) continue; - StationID to = (*this)[it->first].Station(); + for (const auto &edge : from.edges) { + if (edge.Flow() == 0) continue; + NodeID dest_id = edge.base.dest_node; + StationID to = this->nodes[dest_id].base.station; Station *st2 = Station::GetIfValid(to); if (st2 == nullptr || st2->goods[this->Cargo()].link_graph != this->link_graph.index || - st2->goods[this->Cargo()].node != it->first || - !(*lg)[node_id].HasEdgeTo(it->first) || - (*lg)[node_id][it->first].LastUpdate() == INVALID_DATE) { + st2->goods[this->Cargo()].node != dest_id || + !(*lg)[node_id].HasEdgeTo(dest_id) || + (*lg)[node_id][dest_id].LastUpdate() == INVALID_DATE) { /* Edge has been removed. Delete flows. */ StationIDStack erased = flows.DeleteFlows(to); /* Delete old flows for source stations which have been deleted * from the new flows. This avoids flow cycles between old and * new flows. */ while (!erased.IsEmpty()) ge.flows.erase(erased.Pop()); - } else if ((*lg)[node_id][it->first].LastUnrestrictedUpdate() == INVALID_DATE) { + } else if ((*lg)[node_id][dest_id].LastUnrestrictedUpdate() == INVALID_DATE) { /* Edge is fully restricted. */ flows.RestrictFlows(to); } @@ -220,9 +221,9 @@ void Path::Fork(Path *base, uint cap, int free_cap, uint dist) uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation) { if (this->parent != nullptr) { - LinkGraphJob::Edge edge = job[this->parent->node][this->node]; + LinkGraphJob::EdgeAnnotation edge = job[this->parent->node][this->node]; if (max_saturation != UINT_MAX) { - uint usable_cap = edge.Capacity() * max_saturation / 100; + uint usable_cap = edge.base.capacity * max_saturation / 100; if (usable_cap > edge.Flow()) { new_flow = std::min(new_flow, usable_cap - edge.Flow()); } else { @@ -231,7 +232,7 @@ uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation) } new_flow = this->parent->AddFlow(new_flow, job, max_saturation); if (this->flow == 0 && new_flow > 0) { - job[this->parent->node].Paths().push_front(this); + job[this->parent->node].paths.push_front(this); } edge.AddFlow(new_flow); } diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index 980c27b067..5a25664ad2 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -28,7 +28,7 @@ extern LinkGraphJobPool _link_graph_job_pool; * Class for calculation jobs to be run on link graphs. */ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{ -private: +public: /** * Demand between two nodes. */ @@ -41,13 +41,46 @@ private: * Annotation for a link graph edge. */ struct EdgeAnnotation { + const LinkGraph::BaseEdge &base; ///< Reference to the edge that is annotated. + uint flow; ///< Planned flow over this edge. + + EdgeAnnotation(const LinkGraph::BaseEdge &base) : base(base), flow(0) {} + + /** + * Get the total flow on the edge. + * @return Flow. + */ + uint Flow() const { return this->flow; } + + /** + * Add some flow. + * @param flow Flow to be added. + */ + void AddFlow(uint flow) { this->flow += flow; } + + /** + * Remove some flow. + * @param flow Flow to be removed. + */ + void RemoveFlow(uint flow) + { + assert(flow <= this->flow); + this->flow -= flow; + } + + friend inline bool operator <(NodeID dest, const EdgeAnnotation &rhs) + { + return dest < rhs.base.dest_node; + } }; /** * Annotation for a link graph node. */ struct NodeAnnotation { + const LinkGraph::BaseNode &base; ///< Reference to the node that is annotated. + uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet. PathList paths; ///< Paths through this node, sorted so that those with flow == 0 are in the back. FlowStatMap flows; ///< Planned flows to other nodes. @@ -55,13 +88,73 @@ private: std::vector edges; ///< Annotations for all edges originating at this node. std::vector demands; ///< Annotations for the demand to all other nodes. - NodeAnnotation(const LinkGraph::BaseNode &node, size_t size) : undelivered_supply(node.supply), paths(), flows() + NodeAnnotation(const LinkGraph::BaseNode &node, size_t size) : base(node), undelivered_supply(node.supply), paths(), flows() { - this->edges.resize(node.edges.size()); + this->edges.reserve(node.edges.size()); + for (auto &e : node.edges) this->edges.emplace_back(e); this->demands.resize(size); } + + /** + * Retrieve an edge starting at this node. + * @param to Remote end of the edge. + * @return Edge between this node and "to". + */ + EdgeAnnotation &operator[](NodeID to) + { + auto it = std::find_if(this->edges.begin(), this->edges.end(), [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; }); + assert(it != this->edges.end()); + return *it; + } + + /** + * Retrieve an edge starting at this node. + * @param to Remote end of the edge. + * @return Edge between this node and "to". + */ + const EdgeAnnotation &operator[](NodeID to) const + { + auto it = std::find_if(this->edges.begin(), this->edges.end(), [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; }); + assert(it != this->edges.end()); + return *it; + } + + /** + * Get the transport demand between end the points of the edge. + * @return Demand. + */ + uint DemandTo(NodeID to) const { return this->demands[to].demand; } + + /** + * Get the transport demand that hasn't been satisfied by flows, yet. + * @return Unsatisfied demand. + */ + uint UnsatisfiedDemandTo(NodeID to) const { return this->demands[to].unsatisfied_demand; } + + /** + * Satisfy some demand. + * @param demand Demand to be satisfied. + */ + void SatisfyDemandTo(NodeID to, uint demand) + { + assert(demand <= this->demands[to].unsatisfied_demand); + this->demands[to].unsatisfied_demand -= demand; + } + + /** + * Deliver some supply, adding demand to the respective edge. + * @param to Destination for supply. + * @param amount Amount of supply to be delivered. + */ + void DeliverSupply(NodeID to, uint amount) + { + this->undelivered_supply -= amount; + this->demands[to].demand += amount; + this->demands[to].unsatisfied_demand += amount; + } }; +private: typedef std::vector NodeAnnotationVector; friend SaveLoadTable GetLinkGraphJobDesc(); @@ -81,199 +174,6 @@ protected: void SpawnThread(); public: - - /** - * A job edge. Wraps a link graph edge and an edge annotation. The - * annotation can be modified, the edge is constant. - */ - class Edge : public LinkGraph::ConstEdge { - private: - EdgeAnnotation &anno; ///< Annotation being wrapped. - public: - /** - * Constructor. - * @param edge Link graph edge to be wrapped. - * @param anno Annotation to be wrapped. - */ - Edge(const LinkGraph::BaseEdge &edge, EdgeAnnotation &anno) : - LinkGraph::ConstEdge(edge), anno(anno) {} - - /** - * Get the total flow on the edge. - * @return Flow. - */ - uint Flow() const { return this->anno.flow; } - - /** - * Add some flow. - * @param flow Flow to be added. - */ - void AddFlow(uint flow) { this->anno.flow += flow; } - - /** - * Remove some flow. - * @param flow Flow to be removed. - */ - void RemoveFlow(uint flow) - { - assert(flow <= this->anno.flow); - this->anno.flow -= flow; - } - }; - - /** - * Iterator for job edges. - */ - class EdgeIterator : public LinkGraph::BaseEdgeIterator { - span base_anno; ///< Array of annotations to be (indirectly) iterated. - public: - /** - * Constructor. - * @param base Array of edges to be iterated. - * @param base_anno Array of annotations to be iterated. - * @param current Start offset of iteration. - */ - EdgeIterator(span base, span base_anno, bool end) : - LinkGraph::BaseEdgeIterator(base, end), - base_anno(base_anno) {} - - EdgeIterator() : - LinkGraph::BaseEdgeIterator(span(), true), - base_anno() {} - - /** - * Dereference. - * @return Pair of the edge currently pointed to and the ID of its - * other end. - */ - std::pair operator*() const - { - return std::pair(this->base[this->current].dest_node, Edge(this->base[this->current], this->base_anno[this->current])); - } - - /** - * Dereference. Has to be repeated here as operator* is different than - * in LinkGraph::EdgeWrapper. - * @return Fake pointer to pair of NodeID/Edge. - */ - FakePointer operator->() const { - return FakePointer(this->operator*()); - } - }; - - /** - * Link graph job node. Wraps a constant link graph node and a modifiable - * node annotation. - */ - class Node : public LinkGraph::ConstNode { - private: - NodeAnnotation &node_anno; ///< Annotation being wrapped. - span edge_annos; ///< Edge annotations belonging to this node. - public: - - /** - * Constructor. - * @param lgj Job to take the node from. - * @param node ID of the node. - */ - Node (LinkGraphJob *lgj, NodeID node) : - LinkGraph::ConstNode(&lgj->link_graph, node), - node_anno(lgj->nodes[node]), edge_annos(lgj->nodes[node].edges) - {} - - /** - * Retrieve an edge starting at this node. Mind that this returns an - * object, not a reference. - * @param to Remote end of the edge. - * @return Edge between this node and "to". - */ - Edge operator[](NodeID to) const - { - assert(this->HasEdgeTo(to)); - auto index = std::distance(this->node.edges.begin(), this->GetEdge(to)); - return Edge(this->node.edges[index], this->edge_annos[index]); - } - - /** - * Iterator for the "begin" of the edge array. Only edges with capacity - * are iterated. The others are skipped. - * @return Iterator pointing to the first edge. - */ - EdgeIterator Begin() const { return EdgeIterator(this->node.edges, this->edge_annos, false); } - - /** - * Iterator for the "end" of the edge array. Only edges with capacity - * are iterated. The others are skipped. - * @return Iterator pointing beyond the last edge. - */ - EdgeIterator End() const { return EdgeIterator(this->node.edges, this->edge_annos, true); } - - /** - * Get amount of supply that hasn't been delivered, yet. - * @return Undelivered supply. - */ - uint UndeliveredSupply() const { return this->node_anno.undelivered_supply; } - - /** - * Get the flows running through this node. - * @return Flows. - */ - FlowStatMap &Flows() { return this->node_anno.flows; } - - /** - * Get a constant version of the flows running through this node. - * @return Flows. - */ - const FlowStatMap &Flows() const { return this->node_anno.flows; } - - /** - * Get the paths this node is part of. Paths are always expected to be - * sorted so that those with flow == 0 are in the back of the list. - * @return Paths. - */ - PathList &Paths() { return this->node_anno.paths; } - - /** - * Get a constant version of the paths this node is part of. - * @return Paths. - */ - const PathList &Paths() const { return this->node_anno.paths; } - - /** - * Get the transport demand between end the points of the edge. - * @return Demand. - */ - uint DemandTo(NodeID to) const { return this->node_anno.demands[to].demand; } - - /** - * Get the transport demand that hasn't been satisfied by flows, yet. - * @return Unsatisfied demand. - */ - uint UnsatisfiedDemandTo(NodeID to) const { return this->node_anno.demands[to].unsatisfied_demand; } - - /** - * Satisfy some demand. - * @param demand Demand to be satisfied. - */ - void SatisfyDemandTo(NodeID to, uint demand) - { - assert(demand <= this->node_anno.demands[to].unsatisfied_demand); - this->node_anno.demands[to].unsatisfied_demand -= demand; - } - - /** - * Deliver some supply, adding demand to the respective edge. - * @param to Destination for supply. - * @param amount Amount of supply to be delivered. - */ - void DeliverSupply(NodeID to, uint amount) - { - this->node_anno.undelivered_supply -= amount; - this->node_anno.demands[to].demand += amount; - this->node_anno.demands[to].unsatisfied_demand += amount; - } - }; - /** * Bare constructor, only for save/load. link_graph, join_date and actually * settings have to be brutally const-casted in order to populate them. @@ -337,7 +237,7 @@ public: * @param num ID of the node. * @return the Requested node. */ - inline Node operator[](NodeID num) { return Node(this, num); } + inline NodeAnnotation &operator[](NodeID num) { return this->nodes[num]; } /** * Get the size of the underlying link graph. diff --git a/src/linkgraph/linkgraphjob_base.h b/src/linkgraph/linkgraphjob_base.h index a05d6ef8d6..1a0c3667b2 100644 --- a/src/linkgraph/linkgraphjob_base.h +++ b/src/linkgraph/linkgraphjob_base.h @@ -14,8 +14,7 @@ #include "linkgraphjob.h" #include "linkgraphschedule.h" -typedef LinkGraphJob::Node Node; -typedef LinkGraphJob::Edge Edge; -typedef LinkGraphJob::EdgeIterator EdgeIterator; +typedef LinkGraphJob::NodeAnnotation Node; +typedef LinkGraphJob::EdgeAnnotation Edge; #endif /* LINKGRAPHJOB_BASE_H */ diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index 599bac3d52..c7b5d6d075 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -94,8 +94,9 @@ public: class GraphEdgeIterator { private: LinkGraphJob &job; ///< Job being executed - EdgeIterator i; ///< Iterator pointing to current edge. - EdgeIterator end; ///< Iterator pointing beyond last edge. + + std::vector::const_iterator i; ///< Iterator pointing to current edge. + std::vector::const_iterator end; ///< Iterator pointing beyond last edge. public: @@ -112,8 +113,8 @@ public: */ void SetNode(NodeID source, NodeID node) { - this->i = this->job[node].Begin(); - this->end = this->job[node].End(); + this->i = this->job[node].edges.cbegin(); + this->end = this->job[node].edges.cend(); } /** @@ -122,7 +123,7 @@ public: */ NodeID Next() { - return this->i != this->end ? (this->i++)->first : INVALID_NODE; + return this->i != this->end ? (this->i++)->base.dest_node : INVALID_NODE; } }; @@ -150,7 +151,7 @@ public: FlowEdgeIterator(LinkGraphJob &job) : job(job) { for (NodeID i = 0; i < job.Size(); ++i) { - StationID st = job[i].Station(); + StationID st = job[i].base.station; if (st >= this->station_to_node.size()) { this->station_to_node.resize(st + 1); } @@ -165,8 +166,8 @@ public: */ void SetNode(NodeID source, NodeID node) { - const FlowStatMap &flows = this->job[node].Flows(); - FlowStatMap::const_iterator it = flows.find(this->job[source].Station()); + const FlowStatMap &flows = this->job[node].flows; + FlowStatMap::const_iterator it = flows.find(this->job[source].base.station); if (it != flows.end()) { this->it = it->second.GetShares()->begin(); this->end = it->second.GetShares()->end(); @@ -275,8 +276,8 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) iter.SetNode(source_node, from); for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) { if (to == from) continue; // Not a real edge but a consumption sign. - Edge edge = this->job[from][to]; - uint capacity = edge.Capacity(); + const Edge &edge = this->job[from][to]; + uint capacity = edge.base.capacity; if (this->max_saturation != UINT_MAX) { capacity *= this->max_saturation; capacity /= 100; @@ -288,9 +289,9 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) bool express = IsCargoInClass(this->job.Cargo(), CC_PASSENGERS) || IsCargoInClass(this->job.Cargo(), CC_MAIL) || IsCargoInClass(this->job.Cargo(), CC_EXPRESS); - uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1; + uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1; /* Compute a default travel time from the distance and an average speed of 1 tile/day. */ - uint time = (edge.TravelTime() != 0) ? edge.TravelTime() + DAY_TICKS : distance * DAY_TICKS; + uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + DAY_TICKS : distance * DAY_TICKS; uint distance_anno = express ? time : distance; Tannotation *dest = static_cast(paths[to]); @@ -381,7 +382,7 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow) NodeID prev = cycle_begin->GetNode(); cycle_begin->ReduceFlow(flow); if (cycle_begin->GetFlow() == 0) { - PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].Paths(); + PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].paths; for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) { if (*i == cycle_begin) { node_paths.erase(i); @@ -391,7 +392,7 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow) } } cycle_begin = path[prev]; - Edge edge = this->job[prev][cycle_begin->GetNode()]; + Edge &edge = this->job[prev][cycle_begin->GetNode()]; edge.RemoveFlow(flow); } while (cycle_begin != cycle_end); } @@ -415,7 +416,7 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next if (at_next_pos == nullptr) { /* Summarize paths; add up the paths with the same source and next hop * in one path each. */ - PathList &paths = this->job[next_id].Paths(); + PathList &paths = this->job[next_id].paths; PathViaMap next_hops; for (PathList::iterator i = paths.begin(); i != paths.end();) { Path *new_child = *i; @@ -512,7 +513,7 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) /* First saturate the shortest paths. */ this->Dijkstra(source, paths); - Node src_node = job[source]; + Node &src_node = job[source]; bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { if (src_node.UnsatisfiedDemandTo(dest) > 0) { @@ -559,7 +560,7 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job) this->Dijkstra(source, paths); - Node src_node = job[source]; + Node &src_node = job[source]; bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { Path *path = paths[dest];