mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-12 18:40:29 +00:00
(svn r25885) -Codechange: Keep paths sorted so that the ones with flow == 0 are in the back and don't have to be iterated over so often.
This commit is contained in:
parent
c08259fe92
commit
b3b460cae2
@ -28,7 +28,7 @@ void FlowMapper::Run(LinkGraphJob &job) const
|
|||||||
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) {
|
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) {
|
||||||
Path *path = *i;
|
Path *path = *i;
|
||||||
uint flow = path->GetFlow();
|
uint flow = path->GetFlow();
|
||||||
if (flow == 0) continue;
|
if (flow == 0) break;
|
||||||
/* compress to monthly value */
|
/* compress to monthly value */
|
||||||
flow = max(1U, flow * 30 / runtime);
|
flow = max(1U, flow * 30 / runtime);
|
||||||
Node node = job[path->GetNode()];
|
Node node = job[path->GetNode()];
|
||||||
|
@ -181,7 +181,7 @@ uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation)
|
|||||||
}
|
}
|
||||||
new_flow = this->parent->AddFlow(new_flow, job, max_saturation);
|
new_flow = this->parent->AddFlow(new_flow, job, max_saturation);
|
||||||
if (this->flow == 0 && new_flow > 0) {
|
if (this->flow == 0 && new_flow > 0) {
|
||||||
job[this->parent->node].Paths().push_back(this);
|
job[this->parent->node].Paths().push_front(this);
|
||||||
}
|
}
|
||||||
edge.AddFlow(new_flow);
|
edge.AddFlow(new_flow);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
struct NodeAnnotation {
|
struct NodeAnnotation {
|
||||||
uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet.
|
uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet.
|
||||||
PathList paths; ///< Paths through this node.
|
PathList paths; ///< Paths through this node, sorted so that those with flow == 0 are in the back.
|
||||||
FlowStatMap flows; ///< Planned flows to other nodes.
|
FlowStatMap flows; ///< Planned flows to other nodes.
|
||||||
void Init(uint supply);
|
void Init(uint supply);
|
||||||
};
|
};
|
||||||
@ -234,7 +234,8 @@ public:
|
|||||||
const FlowStatMap &Flows() const { return this->node_anno.flows; }
|
const FlowStatMap &Flows() const { return this->node_anno.flows; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the paths this node is part of.
|
* 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.
|
* @return Paths.
|
||||||
*/
|
*/
|
||||||
PathList &Paths() { return this->node_anno.paths; }
|
PathList &Paths() { return this->node_anno.paths; }
|
||||||
|
@ -351,7 +351,17 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow)
|
|||||||
do {
|
do {
|
||||||
NodeID prev = cycle_begin->GetNode();
|
NodeID prev = cycle_begin->GetNode();
|
||||||
cycle_begin->ReduceFlow(flow);
|
cycle_begin->ReduceFlow(flow);
|
||||||
cycle_begin = path[cycle_begin->GetNode()];
|
if (cycle_begin->GetFlow() == 0) {
|
||||||
|
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);
|
||||||
|
node_paths.push_back(cycle_begin);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cycle_begin = path[prev];
|
||||||
Edge edge = this->job[prev][cycle_begin->GetNode()];
|
Edge edge = this->job[prev][cycle_begin->GetNode()];
|
||||||
edge.RemoveFlow(flow);
|
edge.RemoveFlow(flow);
|
||||||
} while (cycle_begin != cycle_end);
|
} while (cycle_begin != cycle_end);
|
||||||
@ -379,18 +389,28 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next
|
|||||||
* in one path each. */
|
* in one path each. */
|
||||||
PathList &paths = this->job[next_id].Paths();
|
PathList &paths = this->job[next_id].Paths();
|
||||||
PathViaMap next_hops;
|
PathViaMap next_hops;
|
||||||
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) {
|
for (PathList::iterator i = paths.begin(); i != paths.end();) {
|
||||||
Path *new_child = *i;
|
Path *new_child = *i;
|
||||||
|
uint new_flow = new_child->GetFlow();
|
||||||
|
if (new_flow == 0) break;
|
||||||
if (new_child->GetOrigin() == origin_id) {
|
if (new_child->GetOrigin() == origin_id) {
|
||||||
PathViaMap::iterator via_it = next_hops.find(new_child->GetNode());
|
PathViaMap::iterator via_it = next_hops.find(new_child->GetNode());
|
||||||
if (via_it == next_hops.end()) {
|
if (via_it == next_hops.end()) {
|
||||||
next_hops[new_child->GetNode()] = new_child;
|
next_hops[new_child->GetNode()] = new_child;
|
||||||
|
++i;
|
||||||
} else {
|
} else {
|
||||||
Path *child = via_it->second;
|
Path *child = via_it->second;
|
||||||
uint new_flow = new_child->GetFlow();
|
|
||||||
child->AddFlow(new_flow);
|
child->AddFlow(new_flow);
|
||||||
new_child->ReduceFlow(new_flow);
|
new_child->ReduceFlow(new_flow);
|
||||||
|
|
||||||
|
/* We might hit end() with with the ++ here and skip the
|
||||||
|
* newly push_back'ed path. That's good as the flow of that
|
||||||
|
* path is 0 anyway. */
|
||||||
|
paths.erase(i++);
|
||||||
|
paths.push_back(new_child);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user