MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / Dijkstra

Method Dijkstra

src/linkgraph/mcf.cpp:257–305  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

255 */
256template <class Tannotation, class Tedge_iterator>
257void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
258{
259 typedef std::set<Tannotation *, typename Tannotation::Comparator> AnnoSet;
260 Tedge_iterator iter(this->job);
261 uint16_t size = this->job.Size();
262 AnnoSet annos;
263 paths.resize(size, nullptr);
264 for (NodeID node = 0; node < size; ++node) {
265 Tannotation *anno = new Tannotation(node, node == source_node);
266 anno->UpdateAnnotation();
267 annos.insert(anno);
268 paths[node] = anno;
269 }
270 while (!annos.empty()) {
271 typename AnnoSet::iterator i = annos.begin();
272 Tannotation *source = *i;
273 annos.erase(i);
274 NodeID from = source->GetNode();
275 iter.SetNode(source_node, from);
276 for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
277 if (to == from) continue; // Not a real edge but a consumption sign.
278 const Edge &edge = this->job[from][to];
279 uint capacity = edge.base.capacity;
280 if (this->max_saturation != UINT_MAX) {
281 capacity *= this->max_saturation;
282 capacity /= 100;
283 if (capacity == 0) capacity = 1;
284 }
285 /* Prioritize the fastest route for passengers, mail and express cargo,
286 * and the shortest route for other classes of cargo.
287 * In-between stops are punished with a 1 tile or 1 day penalty. */
288 bool express = IsCargoInClass(this->job.Cargo(), CargoClass::Passengers) ||
289 IsCargoInClass(this->job.Cargo(), CargoClass::Mail) ||
290 IsCargoInClass(this->job.Cargo(), CargoClass::Express);
291 uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1;
292 /* Compute a default travel time from the distance and an average speed of 1 tile/day. */
293 uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + Ticks::DAY_TICKS : distance * Ticks::DAY_TICKS;
294 uint distance_anno = express ? time : distance;
295
296 Tannotation *dest = static_cast<Tannotation *>(paths[to]);
297 if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance_anno)) {
298 annos.erase(dest);
299 dest->Fork(source, capacity, capacity - edge.Flow(), distance_anno);
300 dest->UpdateAnnotation();
301 annos.insert(dest);
302 }
303 }
304 }
305}
306
307/**
308 * Clean up paths that lead nowhere and the root path.

Callers

nothing calls this directly

Calls 15

IsCargoInClassFunction · 0.85
DistanceMaxPlusManhattanFunction · 0.85
resizeMethod · 0.80
GetNodeMethod · 0.80
TravelTimeMethod · 0.80
IsBetterMethod · 0.80
FlowMethod · 0.80
ForkMethod · 0.80
SizeMethod · 0.45
UpdateAnnotationMethod · 0.45
insertMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected