From 0ee1ec74993a7d2b30e74bfff460954a0d81c187 Mon Sep 17 00:00:00 2001 From: Michal Maciejewski Date: Sun, 12 Nov 2023 22:46:17 +0100 Subject: [PATCH] dvrp: skip computing sparse TT matrix when not needed When max duration and distance are set to zero, there is no point in computing te sparce matrix, which may be very time consuming for very large networks. --- .../zone/skims/FreeSpeedTravelTimeMatrix.java | 12 ++++++---- .../zone/skims/TravelTimeMatrices.java | 24 ++++++++++++------- .../zone/skims/TravelTimeMatricesTest.java | 4 ++-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java index 6ee572bb03f..0adab8701df 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java @@ -33,7 +33,7 @@ */ public class FreeSpeedTravelTimeMatrix implements TravelTimeMatrix { public static FreeSpeedTravelTimeMatrix createFreeSpeedMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams params, int numberOfThreads, - double qSimTimeStepSize) { + double qSimTimeStepSize) { return new FreeSpeedTravelTimeMatrix(dvrpNetwork, params, numberOfThreads, new QSimFreeSpeedTravelTime(qSimTimeStepSize)); } @@ -48,7 +48,7 @@ public FreeSpeedTravelTimeMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams var routingParams = new TravelTimeMatrices.RoutingParams(dvrpNetwork, travelTime, travelDisutility, numberOfThreads); freeSpeedTravelTimeMatrix = TravelTimeMatrices.calculateTravelTimeMatrix(routingParams, centralNodes, 0); freeSpeedTravelTimeSparseMatrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams, params.maxNeighborDistance, - params.maxNeighborTravelTime, 0); + params.maxNeighborTravelTime, 0).orElse(null); } @Override @@ -56,9 +56,11 @@ public int getTravelTime(Node fromNode, Node toNode, double departureTime) { if (fromNode == toNode) { return 0; } - int time = freeSpeedTravelTimeSparseMatrix.get(fromNode, toNode); - if (time >= 0) {// value is present - return time; + if (freeSpeedTravelTimeSparseMatrix != null) { + int time = freeSpeedTravelTimeSparseMatrix.get(fromNode, toNode); + if (time >= 0) {// value is present + return time; + } } return freeSpeedTravelTimeMatrix.get(gridSystem.getZone(fromNode), gridSystem.getZone(toNode)); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java index 792140c173d..dcea254ac6c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.IntStream; import org.matsim.api.core.v01.network.Network; @@ -56,7 +57,7 @@ public static Matrix calculateTravelTimeMatrix(RoutingParams params, Map centralNodes, double departureTime, Matrix travelTimeMatrix, - LeastCostPathTree lcpTree) { + LeastCostPathTree lcpTree) { Node fromNode = centralNodes.get(fromZone); lcpTree.calculate(fromNode.getId().index(), departureTime, null, null); @@ -65,26 +66,31 @@ private static void computeForDepartureZone(Zone fromZone, Map centr int nodeIndex = toNode.getId().index(); OptionalTime currOptionalTime = lcpTree.getTime(nodeIndex); double currTime = currOptionalTime.orElseThrow(() -> new RuntimeException( - "Undefined Time. Reason could be that the dvrp network is not fully connected. Please check and/or clean.")); + "Undefined Time. Reason could be that the dvrp network is not fully connected. Please check and/or clean.")); double tt = currTime - departureTime; travelTimeMatrix.set(fromZone, toZone, tt); } } - public static SparseMatrix calculateTravelTimeSparseMatrix(RoutingParams params, double maxDistance, double maxTravelTime, double departureTime) { + public static Optional calculateTravelTimeSparseMatrix(RoutingParams params, double maxDistance, double maxTravelTime, + double departureTime) { SparseMatrix travelTimeMatrix = new SparseMatrix(); + if (maxDistance == 0 && maxTravelTime == 0) { + return Optional.empty(); + } + var nodes = params.routingNetwork.getNodes().values(); var counter = "DVRP free-speed TT sparse matrix: node "; Calculation calculation = (lcpTree, n) -> computeForDepartureNode(n, nodes, departureTime, travelTimeMatrix, lcpTree, maxDistance, - maxTravelTime); + maxTravelTime); calculate(params, nodes, calculation, counter); - return travelTimeMatrix; + return Optional.of(travelTimeMatrix); } private static void computeForDepartureNode(Node fromNode, Collection nodes, double departureTime, SparseMatrix sparseMatrix, - LeastCostPathTree lcpTree, double maxDistance, double maxTravelTime) { + LeastCostPathTree lcpTree, double maxDistance, double maxTravelTime) { lcpTree.calculate(fromNode.getId().index(), departureTime, null, null, - (nodeIndex, arrivalTime, travelCost, distance, departTime) -> distance >= maxDistance && arrivalTime >= departTime + maxTravelTime); + (nodeIndex, arrivalTime, travelCost, distance, departTime) -> distance >= maxDistance && arrivalTime >= departTime + maxTravelTime); List neighborNodes = new ArrayList<>(); for (Node toNode : nodes) { @@ -109,8 +115,8 @@ private interface Calculation { private static void calculate(RoutingParams params, Collection elements, Calculation calculation, String counterPrefix) { var trees = IntStream.range(0, params.numberOfThreads) - .mapToObj(i -> new LeastCostPathTree(new SpeedyGraph(params.routingNetwork), params.travelTime, params.travelDisutility)) - .toList(); + .mapToObj(i -> new LeastCostPathTree(new SpeedyGraph(params.routingNetwork), params.travelTime, params.travelDisutility)) + .toList(); var executorService = new ExecutorServiceWithResource<>(trees); var counter = new Counter(counterPrefix, " / " + elements.size()); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java index 380ab35182c..d60f34f7fa2 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java @@ -69,7 +69,7 @@ public void travelTimeSparseMatrix_maxDistance() { NetworkUtils.createAndAddLink(network, Id.createLinkId("CA"), nodeC, nodeA, 600, 15, 80, 1); double maxDistance = 300;// B->A->C and C->A->B are pruned by the limit - var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), maxDistance, 0, 0); + var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), maxDistance, 0, 0).orElseThrow(); assertThat(matrix.get(nodeA, nodeA)).isEqualTo(0); assertThat(matrix.get(nodeA, nodeB)).isEqualTo(10); @@ -97,7 +97,7 @@ public void travelTimeSparseMatrix_maxTravelTime() { // 20 s (max TT) corresponds to 300 m (max distance) in another test (see: travelTimeSparseMatrix_maxDistance()) double maxTravelTime = 20;// B->A->C and C->A->B are pruned by the limit - var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), 0, maxTravelTime, 0); + var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), 0, maxTravelTime, 0).orElseThrow(); assertThat(matrix.get(nodeA, nodeA)).isEqualTo(0); assertThat(matrix.get(nodeA, nodeB)).isEqualTo(10);