From 14a3484bac8ae0a35136563a8efb672328bd461b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 6 Oct 2019 17:02:38 +0100 Subject: [PATCH] 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. --- src/linkgraph/mcf.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index c64674237fb90..3c75c671d7dc9 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -494,13 +494,18 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) uint size = job.Size(); uint accuracy = job.Settings().accuracy; bool more_loops; + std::vector finished_sources; + finished_sources.resize(size); do { more_loops = false; for (NodeID source = 0; source < size; ++source) { + if (finished_sources[source]) continue; + /* First saturate the shortest paths. */ this->Dijkstra(source, paths); + bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { Edge edge = job[source][dest]; if (edge.UnsatisfiedDemand() > 0) { @@ -518,8 +523,10 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) path->GetFreeCapacity() > INT_MIN) { this->PushFlow(edge, path, accuracy, UINT_MAX); } + if (edge.UnsatisfiedDemand() > 0) source_demand_left = true; } } + if (!source_demand_left) finished_sources[source] = true; this->CleanupPaths(source, paths); } } while (more_loops || this->EliminateCycles()); @@ -537,18 +544,28 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job) uint size = job.Size(); uint accuracy = job.Settings().accuracy; bool demand_left = true; + std::vector finished_sources; + finished_sources.resize(size); while (demand_left) { demand_left = false; for (NodeID source = 0; source < size; ++source) { + if (finished_sources[source]) continue; + this->Dijkstra(source, paths); + + bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { Edge edge = this->job[source][dest]; Path *path = paths[dest]; if (edge.UnsatisfiedDemand() > 0 && path->GetFreeCapacity() > INT_MIN) { 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; + } } } + if (!source_demand_left) finished_sources[source] = true; this->CleanupPaths(source, paths); } }