mirror of https://github.com/OpenTTD/OpenTTD
Codechange: [Linkgraph] Skip MCF source node Dijkstra when all demand satisfied
MCF Dijkstra iterations are executed for all source nodes in a round-robin order. Source nodes typically require different numbers of MCF Dijkstra iterations to satisfy all of their demand. This change is to avoid performing MCF Dijkstra iterations on source nodes which have already been fully satisfied.pull/7921/head
parent
190e074287
commit
6e7117e04c
|
@ -494,13 +494,17 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job)
|
||||||
uint size = job.Size();
|
uint size = job.Size();
|
||||||
uint accuracy = job.Settings().accuracy;
|
uint accuracy = job.Settings().accuracy;
|
||||||
bool more_loops;
|
bool more_loops;
|
||||||
|
std::vector<bool> finished_sources(size);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
more_loops = false;
|
more_loops = false;
|
||||||
for (NodeID source = 0; source < size; ++source) {
|
for (NodeID source = 0; source < size; ++source) {
|
||||||
|
if (finished_sources[source]) continue;
|
||||||
|
|
||||||
/* First saturate the shortest paths. */
|
/* First saturate the shortest paths. */
|
||||||
this->Dijkstra<DistanceAnnotation, GraphEdgeIterator>(source, paths);
|
this->Dijkstra<DistanceAnnotation, GraphEdgeIterator>(source, paths);
|
||||||
|
|
||||||
|
bool source_demand_left = false;
|
||||||
for (NodeID dest = 0; dest < size; ++dest) {
|
for (NodeID dest = 0; dest < size; ++dest) {
|
||||||
Edge edge = job[source][dest];
|
Edge edge = job[source][dest];
|
||||||
if (edge.UnsatisfiedDemand() > 0) {
|
if (edge.UnsatisfiedDemand() > 0) {
|
||||||
|
@ -518,8 +522,10 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job)
|
||||||
path->GetFreeCapacity() > INT_MIN) {
|
path->GetFreeCapacity() > INT_MIN) {
|
||||||
this->PushFlow(edge, path, accuracy, UINT_MAX);
|
this->PushFlow(edge, path, accuracy, UINT_MAX);
|
||||||
}
|
}
|
||||||
|
if (edge.UnsatisfiedDemand() > 0) source_demand_left = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finished_sources[source] = !source_demand_left;
|
||||||
this->CleanupPaths(source, paths);
|
this->CleanupPaths(source, paths);
|
||||||
}
|
}
|
||||||
} while (more_loops || this->EliminateCycles());
|
} while (more_loops || this->EliminateCycles());
|
||||||
|
@ -537,18 +543,27 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job)
|
||||||
uint size = job.Size();
|
uint size = job.Size();
|
||||||
uint accuracy = job.Settings().accuracy;
|
uint accuracy = job.Settings().accuracy;
|
||||||
bool demand_left = true;
|
bool demand_left = true;
|
||||||
|
std::vector<bool> finished_sources(size);
|
||||||
while (demand_left) {
|
while (demand_left) {
|
||||||
demand_left = false;
|
demand_left = false;
|
||||||
for (NodeID source = 0; source < size; ++source) {
|
for (NodeID source = 0; source < size; ++source) {
|
||||||
|
if (finished_sources[source]) continue;
|
||||||
|
|
||||||
this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
|
this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
|
||||||
|
|
||||||
|
bool source_demand_left = false;
|
||||||
for (NodeID dest = 0; dest < size; ++dest) {
|
for (NodeID dest = 0; dest < size; ++dest) {
|
||||||
Edge edge = this->job[source][dest];
|
Edge edge = this->job[source][dest];
|
||||||
Path *path = paths[dest];
|
Path *path = paths[dest];
|
||||||
if (edge.UnsatisfiedDemand() > 0 && path->GetFreeCapacity() > INT_MIN) {
|
if (edge.UnsatisfiedDemand() > 0 && path->GetFreeCapacity() > INT_MIN) {
|
||||||
this->PushFlow(edge, path, accuracy, UINT_MAX);
|
this->PushFlow(edge, path, accuracy, UINT_MAX);
|
||||||
if (edge.UnsatisfiedDemand() > 0) demand_left = true;
|
if (edge.UnsatisfiedDemand() > 0) {
|
||||||
|
demand_left = true;
|
||||||
|
source_demand_left = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finished_sources[source] = !source_demand_left;
|
||||||
this->CleanupPaths(source, paths);
|
this->CleanupPaths(source, paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue