From 3599e4b45b4bf9e531927dd37327079570b4be29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:54:35 +0000 Subject: [PATCH 1/2] Bump org.openjfx:javafx-graphics from 22.0.1 to 22.0.2 Bumps org.openjfx:javafx-graphics from 22.0.1 to 22.0.2. --- updated-dependencies: - dependency-name: org.openjfx:javafx-graphics dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- contribs/vsp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribs/vsp/pom.xml b/contribs/vsp/pom.xml index b2bf9fb3a41..8f4e01bec37 100644 --- a/contribs/vsp/pom.xml +++ b/contribs/vsp/pom.xml @@ -184,7 +184,7 @@ org.openjfx javafx-graphics - 22.0.1 + 22.0.2 com.graphhopper From 6bd4b3618f53a88a7cfc5be4110cb1d8751e76e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Fri, 30 Aug 2024 10:47:57 +0200 Subject: [PATCH 2/2] potentially more efficient version of PrebookingStopActivity --- .../prebooking/PrebookingStopActivity.java | 96 +++++++++++++------ 1 file changed, 67 insertions(+), 29 deletions(-) diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java index fd81c1745f3..3c04ba985a3 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java @@ -1,15 +1,15 @@ package org.matsim.contrib.drt.prebooking; -import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.PriorityQueue; import java.util.Queue; -import java.util.Set; import java.util.function.Supplier; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.IdSet; import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; @@ -39,9 +39,13 @@ public class PrebookingStopActivity extends FirstLastSimStepDynActivity implemen private final Map, ? extends AcceptedDrtRequest> pickupRequests; private final Map, ? extends AcceptedDrtRequest> dropoffRequests; - private final IdMap enterTimes = new IdMap<>(Request.class); + private final Queue enterTimes = new PriorityQueue<>(); private final Queue leaveTimes = new PriorityQueue<>(); - private final Set> enteredRequests = new HashSet<>(); + + private final IdSet enteredRequests = new IdSet<>(Request.class); + + private final IdSet registeredPickups = new IdSet<>(Request.class); + private final IdMap expectedPickups = new IdMap<>(Request.class); private final PrebookingManager prebookingManager; private final PassengerHandler passengerHandler; @@ -93,7 +97,6 @@ private void initDropoffRequests(double now) { } private boolean updateDropoffRequests(double now) { - while (!leaveTimes.isEmpty() && leaveTimes.peek().time <= now) { Id requestId = leaveTimes.poll().id; passengerHandler.dropOffPassengers(driver, requestId, now); @@ -105,60 +108,94 @@ private boolean updateDropoffRequests(double now) { } private record QueuedRequest(Id id, double time) implements Comparable { - @Override public int compareTo(QueuedRequest o) { return Double.compare(this.time, o.time); } } + private int cachedPickupRequestsHash = -1; + private boolean updatePickupRequests(double now, boolean isFirstStep) { - var pickupIterator = pickupRequests.values().iterator(); - - while (pickupIterator.hasNext()) { - var request = pickupIterator.next(); - - if (!enteredRequests.contains(request.getId()) && !enterTimes.containsKey(request.getId())) { - // this is a new request that has been added after the activity has been created - // or that had not arrived yet - - if (passengerHandler.notifyWaitForPassengers(this, this.driver, request.getId())) { - // agent starts to enter - queuePickup(request, now); - } else if (now > request.getEarliestStartTime() && !isFirstStep) { - if (abandonVoter.abandonRequest(now, vehicle, request)) { - prebookingManager.abandon(request.getId()); - } + int pickupRequestsHash = pickupRequests.hashCode(); + + // part 1: check if the pickup list has been updated dynamically + + if (isFirstStep || pickupRequestsHash != cachedPickupRequestsHash) { + cachedPickupRequestsHash = pickupRequestsHash; + + // added requests + for (AcceptedDrtRequest request : pickupRequests.values()) { + if (!registeredPickups.contains(request.getId())) { + // in the first step, this is a standard pickup request, later this is a request that has been added after the activity has been created + expectedPickups.put(request.getId(), request); + registeredPickups.add(request.getId()); + } + } + + // removed requests (for instance via cancellation) + var expectedIterator = expectedPickups.iterator(); + while (expectedIterator.hasNext()) { + if (!pickupRequests.containsKey(expectedIterator.next().getId())) { + // a request has been removed from the list of expected pickups + expectedIterator.remove(); } } } + + // part 2: handle the requests that we expect but which have not arrived yet + + var expectedIterator = expectedPickups.values().iterator(); + while (expectedIterator.hasNext()) { + AcceptedDrtRequest request = expectedIterator.next(); + + if (passengerHandler.notifyWaitForPassengers(this, this.driver, request.getId())) { + // agent starts to enter + queuePickup(request, now); + expectedIterator.remove(); + } else if (now > request.getEarliestStartTime() && !isFirstStep) { + if (abandonVoter.abandonRequest(now, vehicle, request)) { + // abandon the request, but not in the first time step for the sake of event timing + prebookingManager.abandon(request.getId()); + expectedIterator.remove(); + } + } + } + + // part 3: handle the requests that are currently entering the vehicle + + var enterIterator = enterTimes.iterator(); - var enterIterator = enterTimes.entrySet().iterator(); + // logic is as follows: + // - let people enter in the order at which they arrived + their interaction time + // - but in case there is no capacity (others still disembarking) they need to wait while (enterIterator.hasNext()) { var entry = enterIterator.next(); int availableCapacity = vehicle.getCapacity() - onboard; - if (entry.getValue() <= now) { - int requiredCapacity = pickupRequests.get(entry.getKey()).getPassengerCount(); + if (entry.time <= now) { + int requiredCapacity = pickupRequests.get(entry.id).getPassengerCount(); if (requiredCapacity <= availableCapacity) { // let agent enter now - Verify.verify(passengerHandler.tryPickUpPassengers(this, driver, entry.getKey(), now)); - enteredRequests.add(entry.getKey()); + Verify.verify(passengerHandler.tryPickUpPassengers(this, driver, entry.id, now)); + enteredRequests.add(entry.id); onboard += requiredCapacity; enterIterator.remove(); } + } else { + break; } } - return enterTimes.size() == 0 && pickupRequests.size() == enteredRequests.size(); + return expectedPickups.size() == 0 && pickupRequests.size() == enteredRequests.size(); } private void queuePickup(AcceptedDrtRequest request, double now) { prebookingManager.notifyPickup(now, request); double enterTime = now + stopDurationProvider.calcPickupDuration(vehicle, request.getRequest()); - enterTimes.put(request.getId(), enterTime); + enterTimes.add(new QueuedRequest(request.getId(), enterTime)); } @Override @@ -170,6 +207,7 @@ protected void simStep(double now) { public void notifyPassengersAreReadyForDeparture(List passengers, double now) { var request = getRequestForPassengers(passengers.stream().map(Identifiable::getId).toList()); queuePickup(request, now); + expectedPickups.remove(request.getId()); } private AcceptedDrtRequest getRequestForPassengers(List> passengerIds) {