diff --git a/contribs/application/pom.xml b/contribs/application/pom.xml index b2b75824e01..b427dfbfcf9 100644 --- a/contribs/application/pom.xml +++ b/contribs/application/pom.xml @@ -87,7 +87,7 @@ com.github.matsim-org gtfs2matsim - 47b0802a29 + 19f1676fc6 diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java index ddbe0e7868a..5483167fcdf 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java @@ -25,6 +25,7 @@ import org.matsim.core.utils.io.IOUtils; import org.matsim.pt.transitSchedule.api.*; import org.matsim.pt.utils.CreatePseudoNetwork; +import org.matsim.pt.utils.CreatePseudoNetworkWithLoopLinks; import org.matsim.pt.utils.TransitScheduleValidator; import org.matsim.vehicles.*; import picocli.CommandLine; @@ -85,8 +86,8 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand { @CommandLine.Option(names = "--transform-schedule", description = "Fully qualified class name to a Consumer to be executed after the schedule was created", arity = "0..*", split = ",") private List> transformSchedule; - @CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate") - private boolean mergeStops; + @CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate", defaultValue = "doNotMerge") + private GtfsConverter.MergeGtfsStops mergeStops; @CommandLine.Option(names = "--prefix", description = "Prefixes to add to the gtfs ids. Required if multiple inputs are used and ids are not unique.", split = ",") private List prefixes = new ArrayList<>(); @@ -100,10 +101,29 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand { @CommandLine.Option(names = "--shp-crs", description = "Overwrite coordinate system of the shape file") private String shpCrs; + @CommandLine.Option(names = "--pseudo-network", description = "Define how the pseudo network should be created", defaultValue = "singleLinkBetweenStops") + private PseudoNetwork pseudoNetwork; + + public static void main(String[] args) { System.exit(new CommandLine(new CreateTransitScheduleFromGtfs()).execute(args)); } + private static void addHbefaMapping(VehicleType vehicleType, HbefaVehicleCategory category) { + EngineInformation carEngineInformation = vehicleType.getEngineInformation(); + VehicleUtils.setHbefaVehicleCategory(carEngineInformation, String.valueOf(category)); + VehicleUtils.setHbefaTechnology(carEngineInformation, "average"); + VehicleUtils.setHbefaSizeClass(carEngineInformation, "average"); + VehicleUtils.setHbefaEmissionsConcept(carEngineInformation, "average"); + vehicleType.setNetworkMode(TransportMode.pt); + } + + private static void increaseLinkFreespeedIfLower(Link link, double newFreespeed) { + if (link.getFreespeed() < newFreespeed) { + link.setFreespeed(newFreespeed); + } + } + @Override public Integer call() throws Exception { @@ -183,6 +203,13 @@ public Integer call() throws Exception { Scenario ptScenario = getScenarioWithPseudoPtNetworkAndTransitVehicles(network, scenario.getTransitSchedule(), "pt_"); + for (TransitLine line : new ArrayList<>(scenario.getTransitSchedule().getTransitLines().values())) { + if (line.getRoutes().isEmpty()) { + log.warn("Line {} with no routes removed.", line.getId()); + scenario.getTransitSchedule().removeTransitLine(line); + } + } + if (validate) { //Check schedule and network TransitScheduleValidator.ValidationResult checkResult = TransitScheduleValidator.validateAll(ptScenario.getTransitSchedule(), ptScenario.getNetwork()); @@ -237,14 +264,19 @@ private Predicate createFilter(int i) throws Exception { /** * Creates the pt scenario and network. */ - private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network network, TransitSchedule schedule, String ptNetworkIdentifier) { + private Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network network, TransitSchedule schedule, String ptNetworkIdentifier) { ScenarioUtils.ScenarioBuilder builder = new ScenarioUtils.ScenarioBuilder(ConfigUtils.createConfig()); builder.setNetwork(network); builder.setTransitSchedule(schedule); Scenario scenario = builder.build(); // add pseudo network for pt - new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork(); + switch (pseudoNetwork) { + case singleLinkBetweenStops -> + new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork(); + case withLoopLinks -> + new CreatePseudoNetworkWithLoopLinks(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork(); + } // create TransitVehicle types // see https://svn.vsp.tu-berlin.de/repos/public-svn/publications/vspwp/2014/14-24/ for veh capacities @@ -449,8 +481,12 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network // so we need to add time for passengers to board and alight double minStopTime = 30.0; + List> routeIds = new LinkedList<>(); + routeIds.add(route.getRoute().getStartLinkId()); + routeIds.addAll(route.getRoute().getLinkIds()); + routeIds.add(route.getRoute().getEndLinkId()); + for (int i = 1; i < routeStops.size(); i++) { - // TODO cater for loop link at first stop? Seems to just work without. TransitRouteStop routeStop = routeStops.get(i); // if there is no departure offset set (or infinity), it is the last stop of the line, // so we don't need to care about the stop duration @@ -462,8 +498,23 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network // Math.max to avoid negative values of travelTime double travelTime = Math.max(1, routeStop.getArrivalOffset().seconds() - lastDepartureOffset - 1.0 - (stopDuration >= minStopTime ? 0 : (minStopTime - stopDuration))); - Link link = network.getLinks().get(routeStop.getStopFacility().getLinkId()); - increaseLinkFreespeedIfLower(link, link.getLength() / travelTime); + + + Id stopLink = routeStop.getStopFacility().getLinkId(); + List> subRoute = new LinkedList<>(); + do { + Id linkId = routeIds.removeFirst(); + subRoute.add(linkId); + } while (!subRoute.contains(stopLink)); + + List links = subRoute.stream().map(scenario.getNetwork().getLinks()::get) + .toList(); + + double length = links.stream().mapToDouble(Link::getLength).sum(); + + for (Link link : links) { + increaseLinkFreespeedIfLower(link, length / travelTime); + } lastDepartureOffset = routeStop.getDepartureOffset().seconds(); } @@ -481,20 +532,15 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network return scenario; } - private static void addHbefaMapping(VehicleType vehicleType, HbefaVehicleCategory category) { - EngineInformation carEngineInformation = vehicleType.getEngineInformation(); - VehicleUtils.setHbefaVehicleCategory(carEngineInformation, String.valueOf(category)); - VehicleUtils.setHbefaTechnology(carEngineInformation, "average"); - VehicleUtils.setHbefaSizeClass(carEngineInformation, "average"); - VehicleUtils.setHbefaEmissionsConcept(carEngineInformation, "average"); - vehicleType.setNetworkMode(TransportMode.pt); - } - - private static void increaseLinkFreespeedIfLower(Link link, double newFreespeed) { - if (link.getFreespeed() < newFreespeed) { - link.setFreespeed(newFreespeed); - } + public enum PseudoNetwork { + /** + * Create links between all stops and possibly duplicate stops. + */ + singleLinkBetweenStops, + /** + * Create a pseudo network with loop links at each stop. + */ + withLoopLinks, } - } diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java index 4dcd8a6bf5a..909d311d64f 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java @@ -590,9 +590,12 @@ public void run(Person person) { } // Remove all unselected plans because these are not handled - person.getPlans().stream() - .filter(p -> p != person.getSelectedPlan()) - .forEach(person::removePlan); + List plans = new ArrayList<>(person.getPlans()); + for(Plan p : plans){ + if (p != person.getSelectedPlan()){ + person.removePlan(p); + } + } } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java index 61e3a64a97a..e4286bed31c 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java @@ -280,8 +280,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(5000); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 1800.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5000.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 1800.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 5000.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); @@ -295,8 +295,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(5000); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 900.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5005.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 900.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 5005.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); @@ -310,8 +310,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(5000); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5000.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 4000.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 5000.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); @@ -325,8 +325,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(8000); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 11000.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 4000.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 11000.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); @@ -340,8 +340,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(6000.); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 6000.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 4000.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 6000.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); @@ -355,8 +355,8 @@ private void preparePopulation(Scenario scenario) { Plan plan = factory.createPlan(); Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1)); start.setEndTime(6500.); - start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.); - start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 6500.); + AttributeBasedPrebookingLogic.setSubmissionTime("drt", start, 4000.0); + AttributeBasedPrebookingLogic.setPlannedDepartureTime("drt", start, 6500.0); plan.addActivity(start); plan.addLeg(factory.createLeg("drt")); plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2))); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DefaultDrtOptimizationConstraintsSet.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DefaultDrtOptimizationConstraintsSet.java index 3ba0a7ce169..fd26a90256a 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DefaultDrtOptimizationConstraintsSet.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DefaultDrtOptimizationConstraintsSet.java @@ -23,34 +23,35 @@ public class DefaultDrtOptimizationConstraintsSet extends DrtOptimizationConstra @Parameter @Comment( - "Defines the maximum allowed absolute detour in seconds. Note that the detour is computed from the latest promised pickup time. " + - "To enable the max detour constraint, maxAllowedPickupDelay has to be specified. maxAbsoluteDetour should not be smaller than 0, " + "Defines the maximum allowed absolute detour in seconds. maxAbsoluteDetour should not be smaller than 0, " + "and should be higher than the offset maxDetourBeta. By default, this limit is disabled (i.e. set to Inf)") @PositiveOrZero public double maxAbsoluteDetour = Double.POSITIVE_INFINITY;// [s] @Parameter @Comment( - "Defines the maximum allowed absolute detour based on the unsharedRideTime. Note that the detour is computed from the latest promised " - + "pickup time. To enable the max detour constraint, maxAllowedPickupDelay has to be specified. A linear combination similar to travel " + "Defines the maximum allowed absolute detour based on the unsharedRideTime. A linear combination similar to travel " + "time constrain is used. This is the ratio part. By default, this limit is disabled (i.e. set to Inf, together with maxDetourBeta).") @DecimalMin("1.0") public double maxDetourAlpha = Double.POSITIVE_INFINITY; @Parameter @Comment( - "Defines the maximum allowed absolute detour based on the unsharedRideTime. Note that the detour is computed from the latest promised " - + "pickup time. To enable the max detour constraint, maxAllowedPickupDelay has to be specified. A linear combination similar to travel " + "Defines the maximum allowed absolute detour based on the unsharedRideTime. A linear combination similar to travel " + "time constrain is used. This is the constant part. By default, this limit is disabled (i.e. set to Inf, together with maxDetourAlpha).") @PositiveOrZero public double maxDetourBeta = Double.POSITIVE_INFINITY;// [s] + @Parameter + @Comment( + "Defines the minimum allowed absolute detour in seconds. By default, this bound is disabled (i.e. set to 0.)") + @PositiveOrZero + public double minimumAllowedDetour = 0; + @Override protected void checkConsistency(Config config) { super.checkConsistency(config); - if ((maxDetourAlpha != Double.POSITIVE_INFINITY && maxDetourBeta != Double.POSITIVE_INFINITY) || maxAbsoluteDetour != Double.POSITIVE_INFINITY) { - Verify.verify(maxAllowedPickupDelay != Double.POSITIVE_INFINITY, "Detour constraints are activated, " + - "maxAllowedPickupDelay must be specified! A value between 0 and 240 seconds can be a good choice for maxAllowedPickupDelay."); - } + Verify.verify(maxAbsoluteDetour > minimumAllowedDetour, "The minimum allowed detour must" + + "be lower than the maximum allowed detour."); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategy.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategy.java index 4e06666ed05..f3892019345 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategy.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategy.java @@ -40,6 +40,9 @@ */ public class MinCostFlowRebalancingStrategy implements RebalancingStrategy { + public static final String REBALANCING_ZONAL_TARGET_ALPHA = "rebalalpha"; + public static final String REBALANCING_ZONAL_TARGET_BETA = "rebalbeta"; + private final RebalancingTargetCalculator rebalancingTargetCalculator; private final ZoneSystem zonalSystem; private final Fleet fleet; @@ -68,18 +71,37 @@ public List calcRelocations(Stream rebalancab return calculateMinCostRelocations(time, rebalancableVehiclesPerZone, soonIdleVehiclesPerZone); } - private List calculateMinCostRelocations(double time, + List calculateMinCostRelocations(double time, Map> rebalancableVehiclesPerZone, Map> soonIdleVehiclesPerZone) { ToDoubleFunction targetFunction = rebalancingTargetCalculator.calculate(time, rebalancableVehiclesPerZone); var minCostFlowRebalancingStrategyParams = (MinCostFlowRebalancingStrategyParams)params.getRebalancingStrategyParams(); - double alpha = minCostFlowRebalancingStrategyParams.targetAlpha; - double beta = minCostFlowRebalancingStrategyParams.targetBeta; - List vehicleSurpluses = zonalSystem.getZones().values().stream().map(z -> { + List vehicleSurpluses = zonalSystem.getZones().values().stream().map(z -> { + double alpha; + double beta; int rebalancable = rebalancableVehiclesPerZone.getOrDefault(z, List.of()).size(); int soonIdle = soonIdleVehiclesPerZone.getOrDefault(z, List.of()).size(); + + switch (minCostFlowRebalancingStrategyParams.targetCoefficientSource) { + case Static -> { + alpha = minCostFlowRebalancingStrategyParams.targetAlpha; + beta = minCostFlowRebalancingStrategyParams.targetBeta; + } + case FromZoneAttribute -> { + alpha = (Double) z.getAttributes().getAttribute(REBALANCING_ZONAL_TARGET_ALPHA); + beta = (Double) z.getAttributes().getAttribute(REBALANCING_ZONAL_TARGET_BETA); + } + case FromZoneAttributeOrStatic -> { + Object alphaAttribute = z.getAttributes().getAttribute(REBALANCING_ZONAL_TARGET_ALPHA); + alpha = alphaAttribute == null ? minCostFlowRebalancingStrategyParams.targetAlpha : (Double) alphaAttribute; + Object betaAttribute = z.getAttributes().getAttribute(REBALANCING_ZONAL_TARGET_BETA); + beta = betaAttribute == null ? minCostFlowRebalancingStrategyParams.targetBeta : (Double) betaAttribute; + } + default -> throw new IllegalStateException("Unknown target coefficient source " + minCostFlowRebalancingStrategyParams.targetCoefficientSource); + } + int target = (int)Math.floor(alpha * targetFunction.applyAsDouble(z) + beta); int surplus = Math.min(rebalancable + soonIdle - target, rebalancable); return new DrtZoneVehicleSurplus(z, surplus); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyParams.java index 7c0a72e3a07..a09867d4785 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyParams.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyParams.java @@ -56,6 +56,19 @@ public enum RebalancingTargetCalculatorType { @NotNull public RebalancingTargetCalculatorType rebalancingTargetCalculatorType = RebalancingTargetCalculatorType.EstimatedDemand; + + public enum TargetCoefficientSource { + Static, FromZoneAttribute, FromZoneAttributeOrStatic + } + + @Parameter + @Comment("Defines whether the alpha and beta of the target function should be" + + " [Static] or [FromZoneAttribute] in which case alpha and beta can be provided per zone as an attribute." + + " [FromZoneAttributeOrStatic] will fall back to the static coefficients if no attribute is found for a given zone." + + " Use " + MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_ALPHA + " and " + MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_BETA + + " to set values accordingly.") + public TargetCoefficientSource targetCoefficientSource = TargetCoefficientSource.Static; + public enum ZonalDemandEstimatorType {PreviousIterationDemand, None} @Parameter diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java index a48cbe50e46..7908ca1378c 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java @@ -2,6 +2,7 @@ import java.util.Optional; +import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator; @@ -35,23 +36,40 @@ * @author Sebastian Hörl (sebhoerl), IRT SystemX */ public class AttributeBasedPrebookingLogic implements PrebookingLogic, MobsimInitializedListener { - static private final String SUBMISSION_TIME_ATTRIBUTE_PREFIX = "prebooking:submissionTime"; - static private final String PLANNED_DEPARTURE_ATTRIBUTE_PREFIX = "prebooking:plannedDepartureTime"; + static private final String SUBMISSION_TIME_ATTRIBUTE_PREFIX = "prebooking:submissionTime:"; + static private final String PLANNED_DEPARTURE_ATTRIBUTE_PREFIX = "prebooking:plannedDepartureTime:"; - static public String getSubmissionAttribute(String mode) { + static public String getSubmissionTimeAttribute(String mode) { return SUBMISSION_TIME_ATTRIBUTE_PREFIX + mode; } - static public String getPlannedDepartureAttribute(String mode) { + static public String getPlannedDepartureTimeAttribute(String mode) { return PLANNED_DEPARTURE_ATTRIBUTE_PREFIX + mode; } static public Optional getSubmissionTime(String mode, Trip trip) { - return Optional.ofNullable((Double) trip.getTripAttributes().getAttribute(getSubmissionAttribute(mode))); + return Optional.ofNullable((Double) trip.getTripAttributes().getAttribute(getSubmissionTimeAttribute(mode))); } static public Optional getPlannedDepartureTime(String mode, Trip trip) { - return Optional.ofNullable((Double) trip.getTripAttributes().getAttribute(getPlannedDepartureAttribute(mode))); + return Optional + .ofNullable((Double) trip.getTripAttributes().getAttribute(getPlannedDepartureTimeAttribute(mode))); + } + + static public void setSubmissionTime(String mode, Trip trip, double submissionTime) { + trip.getTripAttributes().putAttribute(getSubmissionTimeAttribute(mode), submissionTime); + } + + static public void setPlannedDepartureTime(String mode, Trip trip, double plannedDepartureTime) { + trip.getTripAttributes().putAttribute(getPlannedDepartureTimeAttribute(mode), plannedDepartureTime); + } + + static public void setSubmissionTime(String mode, Activity originActivity, double submissionTime) { + originActivity.getAttributes().putAttribute(getSubmissionTimeAttribute(mode), submissionTime); + } + + static public void setPlannedDepartureTime(String mode, Activity originActivity, double plannedDepartureTime) { + originActivity.getAttributes().putAttribute(getPlannedDepartureTimeAttribute(mode), plannedDepartureTime); } private final PrebookingQueue prebookingQueue; diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java index f8e1f9b36eb..cfcaaa3e5c8 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java @@ -25,9 +25,12 @@ public DefaultDrtRouteConstraintsCalculator(DrtConfigGroup drtCfg, ConstraintSet /** * Calculates the maximum travel time defined as: drtCfg.getMaxTravelTimeAlpha() * unsharedRideTime + drtCfg.getMaxTravelTimeBeta() - * - * Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha * - * unsharedRideTime + drtCfg.maxDetourBeta + * + * Calculates the maximum ride time defined as: + * unsharedRideTime + min( + * maxAbsoluteDetour, + * max(minimumAllowedDetour, unsharedRideTime * (1-drtCfg.maxDetourAlpha) + drtCfg.maxDetourBeta) + * ) * * @return DrtRouteConstraints constraints */ @@ -40,8 +43,8 @@ public DrtRouteConstraints calculateRouteConstraints(double departureTime, Link if (constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) { double maxTravelTime = defaultSet.maxTravelTimeAlpha * unsharedRideTime + defaultSet.maxTravelTimeBeta; - double maxRideTime = Math.min(unsharedRideTime + defaultSet.maxAbsoluteDetour, - defaultSet.maxDetourAlpha * unsharedRideTime + defaultSet.maxDetourBeta); + double maxDetour = Math.max(defaultSet.minimumAllowedDetour, unsharedRideTime * (defaultSet.maxDetourAlpha -1) + defaultSet.maxDetourBeta); + double maxRideTime = unsharedRideTime + Math.min(defaultSet.maxAbsoluteDetour, maxDetour); double maxWaitTime = constraintsSet.maxWaitTime; return new DrtRouteConstraints(maxTravelTime, maxRideTime, maxWaitTime); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java index 7f43fd42d8b..cca630fcf0c 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java @@ -199,9 +199,9 @@ static Network createNetwork() { network.addNode(b); Link ab = network.getFactory().createLink(Id.createLinkId("link_1"), a, b); - Link bc = network.getFactory().createLink(Id.createLinkId("link_2"), b, a); + Link ba = network.getFactory().createLink(Id.createLinkId("link_2"), b, a); network.addLink(ab); - network.addLink(bc); + network.addLink(ba); return network; } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyTest.java new file mode 100644 index 00000000000..8aba7eefc00 --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/mincostflow/MinCostFlowRebalancingStrategyTest.java @@ -0,0 +1,279 @@ +package org.matsim.contrib.drt.optimizer.rebalancing.mincostflow; + +import com.google.common.collect.ImmutableMap; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.prep.PreparedPolygon; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.events.PersonDepartureEvent; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.common.zones.Zone; +import org.matsim.contrib.common.zones.ZoneImpl; +import org.matsim.contrib.common.zones.ZoneSystem; +import org.matsim.contrib.common.zones.ZoneSystemImpl; +import org.matsim.contrib.drt.analysis.zonal.MostCentralDrtZoneTargetLinkSelector; +import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingParams; +import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; +import org.matsim.contrib.drt.optimizer.rebalancing.demandestimator.PreviousIterationDrtDemandEstimator; +import org.matsim.contrib.drt.optimizer.rebalancing.targetcalculator.DemandEstimatorAsTargetCalculator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.*; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.utils.geometry.GeometryUtils; + +import java.util.*; + +public class MinCostFlowRebalancingStrategyTest { + + private static final int ESTIMATION_PERIOD = 1800; + + private final Network network = createNetwork(); + + private final Link link1 = network.getLinks().get(Id.createLinkId("link_1")); + private final Link link2 = network.getLinks().get(Id.createLinkId("link_2")); + + private final Zone zone1 = new ZoneImpl( + Id.create("zone_1", Zone.class), + new PreparedPolygon(GeometryUtils.createGeotoolsPolygon( + List.of( + new Coord(0, 0), + new Coord(0, 500), + new Coord(500, 500), + new Coord(500, 0), + new Coord(0, 0) + ))), "dummy"); + + private final Zone zone2 = new ZoneImpl( + Id.create("zone_2", Zone.class), + new PreparedPolygon(GeometryUtils.createGeotoolsPolygon( + List.of( + new Coord(500, 0), + new Coord(500, 500), + new Coord(1000, 500), + new Coord(1000, 0), + new Coord(500, 0) + ))), "dummy"); + + private final ZoneSystem zonalSystem = new ZoneSystemImpl(List.of(zone1, zone2), coord -> { + if (coord == link1.getToNode().getCoord()) { + return Optional.of(zone1); + } else if (coord == link2.getToNode().getCoord()) { + return Optional.of(zone2); + } else { + throw new RuntimeException(); + } + }, network); + + + @Test + void testEmptyDemandAndTarget() { + PreviousIterationDrtDemandEstimator estimator = createEstimator(); + DemandEstimatorAsTargetCalculator targetCalculator = new DemandEstimatorAsTargetCalculator(estimator, ESTIMATION_PERIOD); + + RebalancingParams rebalancingParams = new RebalancingParams(); + MinCostFlowRebalancingStrategyParams minCostFlowRebalancingStrategyParams = new MinCostFlowRebalancingStrategyParams(); + minCostFlowRebalancingStrategyParams.targetAlpha = 1.; + minCostFlowRebalancingStrategyParams.targetBeta = 0.; + rebalancingParams.addParameterSet(minCostFlowRebalancingStrategyParams); + + AggregatedMinCostRelocationCalculator relocationCalculator = new AggregatedMinCostRelocationCalculator(new MostCentralDrtZoneTargetLinkSelector(zonalSystem)); + MinCostFlowRebalancingStrategy strategy = new MinCostFlowRebalancingStrategy(targetCalculator, + zonalSystem, createEmptyFleet(), relocationCalculator, rebalancingParams); + + Map> rebalanceableVehicles = new HashMap<>(); + List relocations = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations.isEmpty()); + } + + @Test + void testDemandWithoutSurplus() { + PreviousIterationDrtDemandEstimator estimator = createEstimator(); + DemandEstimatorAsTargetCalculator targetCalculator = new DemandEstimatorAsTargetCalculator(estimator, ESTIMATION_PERIOD); + + RebalancingParams rebalancingParams = new RebalancingParams(); + MinCostFlowRebalancingStrategyParams minCostFlowRebalancingStrategyParams = new MinCostFlowRebalancingStrategyParams(); + minCostFlowRebalancingStrategyParams.targetAlpha = 1.; + minCostFlowRebalancingStrategyParams.targetBeta = 0.; + rebalancingParams.addParameterSet(minCostFlowRebalancingStrategyParams); + + AggregatedMinCostRelocationCalculator relocationCalculator = new AggregatedMinCostRelocationCalculator(new MostCentralDrtZoneTargetLinkSelector(zonalSystem)); + MinCostFlowRebalancingStrategy strategy = new MinCostFlowRebalancingStrategy(targetCalculator, + zonalSystem, createEmptyFleet(), relocationCalculator, rebalancingParams); + + //time bin 0-1800 + estimator.handleEvent(departureEvent(100, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(200, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(500, link2, TransportMode.drt)); + estimator.handleEvent(departureEvent(1500, link1, TransportMode.drt)); + estimator.reset(1); + + Map> rebalanceableVehicles = new HashMap<>(); + List relocations = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations.isEmpty()); + } + + @Test + void testDemandWithSurplus() { + PreviousIterationDrtDemandEstimator estimator = createEstimator(); + DemandEstimatorAsTargetCalculator targetCalculator = new DemandEstimatorAsTargetCalculator(estimator, ESTIMATION_PERIOD); + + RebalancingParams rebalancingParams = new RebalancingParams(); + MinCostFlowRebalancingStrategyParams minCostFlowRebalancingStrategyParams = new MinCostFlowRebalancingStrategyParams(); + minCostFlowRebalancingStrategyParams.targetAlpha = 1.; + minCostFlowRebalancingStrategyParams.targetBeta = 0.; + rebalancingParams.addParameterSet(minCostFlowRebalancingStrategyParams); + + AggregatedMinCostRelocationCalculator relocationCalculator = new AggregatedMinCostRelocationCalculator(new MostCentralDrtZoneTargetLinkSelector(zonalSystem)); + MinCostFlowRebalancingStrategy strategy = new MinCostFlowRebalancingStrategy(targetCalculator, + zonalSystem, createEmptyFleet(), relocationCalculator, rebalancingParams); + + // 3 expected trips in zone 1 + estimator.handleEvent(departureEvent(100, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(200, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(300, link1, TransportMode.drt)); + // 1 expected trip in zone 2 + estimator.handleEvent(departureEvent(100, link2, TransportMode.drt)); + estimator.reset(1); + + Map> rebalanceableVehicles = new HashMap<>(); + + // 4 vehicles in zone 1 (surplus = 1) + List rebalanceableVehiclesZone1 = new ArrayList<>(); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a1", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a2", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a3", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a4", DvrpVehicle.class), link1)); + rebalanceableVehicles.put(zone1, rebalanceableVehiclesZone1); + + List relocations = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations.size()).isEqualTo(1); + Assertions.assertThat(relocations.getFirst().link.getId()).isEqualTo(link2.getId()); + + rebalanceableVehicles.clear(); + + // 5 vehicles in zone 1 (surplus = 2) + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a1", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a2", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a3", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a4", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a5", DvrpVehicle.class), link1)); + rebalanceableVehicles.put(zone1, rebalanceableVehiclesZone1); + + //set alpha to 2 -> send two vehicles to zone 2 + minCostFlowRebalancingStrategyParams.targetAlpha = 2.; + List relocations2 = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations2.size()).isEqualTo(2); + Assertions.assertThat(relocations2.getFirst().link.getId()).isEqualTo(link2.getId()); + Assertions.assertThat(relocations2.getLast().link.getId()).isEqualTo(link2.getId()); + } + + @Test + void testDemandWithSurplusZoneBasedTargetRates() { + + // set attributes + zone1.getAttributes().putAttribute(MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_ALPHA, 0.); + zone1.getAttributes().putAttribute(MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_BETA, 0.); + zone2.getAttributes().putAttribute(MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_ALPHA, 1.); + zone2.getAttributes().putAttribute(MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_BETA, 0.); + + + PreviousIterationDrtDemandEstimator estimator = createEstimator(); + DemandEstimatorAsTargetCalculator targetCalculator = new DemandEstimatorAsTargetCalculator(estimator, ESTIMATION_PERIOD); + + RebalancingParams rebalancingParams = new RebalancingParams(); + MinCostFlowRebalancingStrategyParams minCostFlowRebalancingStrategyParams = new MinCostFlowRebalancingStrategyParams(); + minCostFlowRebalancingStrategyParams.targetCoefficientSource = MinCostFlowRebalancingStrategyParams.TargetCoefficientSource.FromZoneAttribute; + rebalancingParams.addParameterSet(minCostFlowRebalancingStrategyParams); + + AggregatedMinCostRelocationCalculator relocationCalculator = new AggregatedMinCostRelocationCalculator(new MostCentralDrtZoneTargetLinkSelector(zonalSystem)); + MinCostFlowRebalancingStrategy strategy = new MinCostFlowRebalancingStrategy(targetCalculator, + zonalSystem, createEmptyFleet(), relocationCalculator, rebalancingParams); + + // 3 expected trips in zone 1 + estimator.handleEvent(departureEvent(100, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(200, link1, TransportMode.drt)); + estimator.handleEvent(departureEvent(300, link1, TransportMode.drt)); + // 1 expected trip in zone 2 + estimator.handleEvent(departureEvent(100, link2, TransportMode.drt)); + estimator.reset(1); + + Map> rebalanceableVehicles = new HashMap<>(); + + // 4 vehicles in zone 1 (surplus = 1) + List rebalanceableVehiclesZone1 = new ArrayList<>(); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a1", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a2", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a3", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a4", DvrpVehicle.class), link1)); + rebalanceableVehicles.put(zone1, rebalanceableVehiclesZone1); + + List relocations = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations.size()).isEqualTo(1); + Assertions.assertThat(relocations.getFirst().link.getId()).isEqualTo(link2.getId()); + + rebalanceableVehicles.clear(); + + // 5 vehicles in zone 1 (surplus = 2) + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a1", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a2", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a3", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a4", DvrpVehicle.class), link1)); + rebalanceableVehiclesZone1.add(getDvrpVehicle(Id.create("a5", DvrpVehicle.class), link1)); + rebalanceableVehicles.put(zone1, rebalanceableVehiclesZone1); + + //set alpha to 2 -> send two vehicles to zone 2 + zone2.getAttributes().putAttribute(MinCostFlowRebalancingStrategy.REBALANCING_ZONAL_TARGET_ALPHA, 2.); + List relocations2 = strategy.calculateMinCostRelocations(0, rebalanceableVehicles, Collections.emptyMap()); + Assertions.assertThat(relocations2.size()).isEqualTo(2); + Assertions.assertThat(relocations2.getFirst().link.getId()).isEqualTo(link2.getId()); + Assertions.assertThat(relocations2.getLast().link.getId()).isEqualTo(link2.getId()); + } + + private DvrpVehicleImpl getDvrpVehicle(Id id, Link link) { + return new DvrpVehicleImpl( + ImmutableDvrpVehicleSpecification.newBuilder() + .id(id) + .capacity(0) + .serviceBeginTime(0) + .serviceEndTime(0) + .startLinkId(link.getId()) + .build(), link); + } + + private static Fleet createEmptyFleet() { + return () -> ImmutableMap., DvrpVehicle>builder().build(); + } + + + private PreviousIterationDrtDemandEstimator createEstimator() { + RebalancingParams rebalancingParams = new RebalancingParams(); + rebalancingParams.interval = ESTIMATION_PERIOD; + + DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); + drtConfigGroup.addParameterSet(rebalancingParams); + + return new PreviousIterationDrtDemandEstimator(zonalSystem, drtConfigGroup, ESTIMATION_PERIOD); + } + + private PersonDepartureEvent departureEvent(double time, Link link, String mode) { + return new PersonDepartureEvent(time, null, link.getId(), mode, mode); + } + + static Network createNetwork() { + Network network = NetworkUtils.createNetwork(); + Node a = network.getFactory().createNode(Id.createNodeId("a"), new Coord(0,0)); + Node b = network.getFactory().createNode(Id.createNodeId("b"), new Coord(500,0)); + network.addNode(a); + network.addNode(b); + + Link ab = network.getFactory().createLink(Id.createLinkId("link_1"), a, b); + Link ba = network.getFactory().createLink(Id.createLinkId("link_2"), b, a); + network.addLink(ab); + network.addLink(ba); + return network; + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java index 0c527bbfb8d..fcdb7ab7d7a 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java @@ -283,13 +283,13 @@ private void buildPopulation(Scenario scenario) { plan.addLeg(firstLeg); if (!Double.isNaN(request.submissionTime)) { - firstActivity.getAttributes().putAttribute(AttributeBasedPrebookingLogic.getSubmissionAttribute("drt"), + firstActivity.getAttributes().putAttribute(AttributeBasedPrebookingLogic.getSubmissionTimeAttribute("drt"), request.submissionTime); } if (!Double.isNaN(request.plannedDepartureTime)) { firstActivity.getAttributes().putAttribute( - AttributeBasedPrebookingLogic.getPlannedDepartureAttribute("drt"), + AttributeBasedPrebookingLogic.getPlannedDepartureTimeAttribute("drt"), request.plannedDepartureTime); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/DynAgent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/DynAgent.java index 8915326d992..d7c15d7552f 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/DynAgent.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/DynAgent.java @@ -19,8 +19,6 @@ package org.matsim.contrib.dynagent; -import java.util.List; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.ActivityEndEvent; import org.matsim.api.core.v01.events.ActivityStartEvent; @@ -40,6 +38,8 @@ import org.matsim.pt.transitSchedule.api.TransitStopFacility; import org.matsim.vehicles.Vehicle; +import java.util.List; + public final class DynAgent implements MobsimDriverPassengerAgent { private final DynAgentLogic agentLogic; @@ -83,11 +83,11 @@ private void computeNextAction(DynAction oldDynAction, double now) { DynAction nextDynAction = agentLogic.computeNextAction(oldDynAction, now); if (nextDynAction instanceof DynActivity) { - dynActivity = (DynActivity)nextDynAction; + dynActivity = (DynActivity) nextDynAction; state = MobsimAgent.State.ACTIVITY; events.processEvent(new ActivityStartEvent(now, id, currentLinkId, null, dynActivity.getActivityType())); } else { - dynLeg = (DynLeg)nextDynAction; + dynLeg = (DynLeg) nextDynAction; state = MobsimAgent.State.LEG; } } @@ -145,7 +145,7 @@ public String getMode() { // VehicleUsingAgent @Override public final Id getPlannedVehicleId() { - Id vehId = ((DriverDynLeg)dynLeg).getPlannedVehicleId(); + Id vehId = ((DriverDynLeg) dynLeg).getPlannedVehicleId(); // according to BasicPlanAgentImpl return vehId != null ? vehId : Id.create(id, Vehicle.class); } @@ -177,13 +177,13 @@ public Id getDestinationLinkId() { // DriverAgent @Override public Id chooseNextLinkId() { - return ((DriverDynLeg)dynLeg).getNextLinkId(); + return ((DriverDynLeg) dynLeg).getNextLinkId(); } // DriverAgent @Override public void notifyMoveOverNode(Id newLinkId) { - ((DriverDynLeg)dynLeg).movedOverNode(newLinkId); + ((DriverDynLeg) dynLeg).movedOverNode(newLinkId); currentLinkId = newLinkId; } @@ -226,26 +226,28 @@ public boolean isWantingToArriveOnCurrentLink() { // PTPassengerAgent @Override public boolean getEnterTransitRoute(TransitLine line, TransitRoute transitRoute, List stopsToCome, - TransitVehicle transitVehicle) { - return ((PTPassengerDynLeg)dynLeg).getEnterTransitRoute(line, transitRoute, stopsToCome, transitVehicle); + TransitVehicle transitVehicle) { + return ((PTPassengerDynLeg) dynLeg).getEnterTransitRoute(line, transitRoute, stopsToCome, transitVehicle); } // PTPassengerAgent + // yyyy seems a bit odd, that this and the following methods are implemented for DynAgent as not every DynAgent is a PTPassengerAgent. paul, + // nov'24 @Override public boolean getExitAtStop(TransitStopFacility stop) { - return ((PTPassengerDynLeg)dynLeg).getExitAtStop(stop); + return ((PTPassengerDynLeg) dynLeg).getExitAtStop(stop); } // PTPassengerAgent @Override public Id getDesiredAccessStopId() { - return ((PTPassengerDynLeg)dynLeg).getDesiredAccessStopId(); + return ((PTPassengerDynLeg) dynLeg).getDesiredAccessStopId(); } // PTPassengerAgent @Override public Id getDesiredDestinationStopId() { - return ((PTPassengerDynLeg)dynLeg).getDesiredDestinationStopId(); + return ((PTPassengerDynLeg) dynLeg).getDesiredDestinationStopId(); } // PTPassengerAgent diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingModule.java index 430484e4943..1f81bac495c 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingModule.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingModule.java @@ -54,15 +54,18 @@ public void install() { // this.addMobsimListenerBinding().to( ChargingHandler.class ).in( Singleton.class ); // does not work since ChargingInfrastructure is not available. + + // standard charging priority for all chargers + bind(ChargingPriority.Factory.class).toInstance(ChargingPriority.FIFO); } @Provides @Singleton - ChargingWithQueueingLogic.Factory provideChargingWithQueueingLogicFactory(EventsManager eventsManager) { - return new ChargingWithQueueingLogic.Factory(eventsManager); + ChargingWithQueueingLogic.Factory provideChargingWithQueueingLogicFactory(EventsManager eventsManager, ChargingPriority.Factory chargingPriorityFactory) { + return new ChargingWithQueueingLogic.Factory(eventsManager, chargingPriorityFactory); } @Provides @Singleton - ChargingWithQueueingAndAssignmentLogic.Factory provideChargingWithQueueingAndAssignmentLogicFactory(EventsManager eventsManager) { - return new ChargingWithQueueingAndAssignmentLogic.Factory(eventsManager); + ChargingWithQueueingAndAssignmentLogic.Factory provideChargingWithQueueingAndAssignmentLogicFactory(EventsManager eventsManager, ChargingPriority.Factory chargingPriorityFactory) { + return new ChargingWithQueueingAndAssignmentLogic.Factory(eventsManager, chargingPriorityFactory); } } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingPriority.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingPriority.java new file mode 100644 index 00000000000..83087a37f79 --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingPriority.java @@ -0,0 +1,29 @@ +package org.matsim.contrib.ev.charging; + +import org.matsim.contrib.ev.charging.ChargingLogic.ChargingVehicle; +import org.matsim.contrib.ev.infrastructure.ChargerSpecification; + +/** + * This interface is supposed to decide if a vehicle can be plugged right now or + * if it needs to go to / remain in the queue. While the condition whether + * enough of empty plugs are available is *always* checked, the presented method + * allows to define a more complex logic beyond that. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public interface ChargingPriority { + /** + * The vehicle can start charging if the method returns true, otherwise it stays + * in the queue. + */ + boolean requestPlugNext(ChargingVehicle cv, double now); + + public interface Factory { + ChargingPriority create(ChargerSpecification charger); + } + + /** + * The default charging priority: first-in first-out. + */ + static public final Factory FIFO = charger -> (ev, now) -> true; +} \ No newline at end of file diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingAndAssignmentLogic.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingAndAssignmentLogic.java index a21fde69f40..1a0aa853af0 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingAndAssignmentLogic.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingAndAssignmentLogic.java @@ -34,8 +34,8 @@ public class ChargingWithQueueingAndAssignmentLogic extends ChargingWithQueueing implements ChargingWithAssignmentLogic { private final Map, ChargingVehicle> assignedVehicles = new LinkedHashMap<>(); - public ChargingWithQueueingAndAssignmentLogic(ChargerSpecification charger, EventsManager eventsManager) { - super(charger, eventsManager); + public ChargingWithQueueingAndAssignmentLogic(ChargerSpecification charger, EventsManager eventsManager, ChargingPriority priority) { + super(charger, eventsManager, priority); } @Override @@ -68,14 +68,16 @@ public Collection getAssignedVehicles() { static public class Factory implements ChargingLogic.Factory { private final EventsManager eventsManager; + private final ChargingPriority.Factory priorityFactory; - public Factory(EventsManager eventsManager) { + public Factory(EventsManager eventsManager, ChargingPriority.Factory priorityFactory) { this.eventsManager = eventsManager; + this.priorityFactory = priorityFactory; } @Override public ChargingLogic create(ChargerSpecification charger) { - return new ChargingWithQueueingAndAssignmentLogic(charger, eventsManager); + return new ChargingWithQueueingAndAssignmentLogic(charger, eventsManager, priorityFactory.create(charger)); } } } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java index 515a586a4c2..0e0de973ffe 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java @@ -40,15 +40,17 @@ public class ChargingWithQueueingLogic implements ChargingLogic { protected final ChargerSpecification charger; private final EventsManager eventsManager; + private final ChargingPriority priority; private final Map, ChargingVehicle> pluggedVehicles = new LinkedHashMap<>(); private final Queue queuedVehicles = new LinkedList<>(); private final Queue arrivingVehicles = new LinkedBlockingQueue<>(); private final Map, ChargingListener> listeners = new LinkedHashMap<>(); - public ChargingWithQueueingLogic(ChargerSpecification charger, EventsManager eventsManager) { + public ChargingWithQueueingLogic(ChargerSpecification charger, EventsManager eventsManager, ChargingPriority priority) { this.charger = Objects.requireNonNull(charger); this.eventsManager = Objects.requireNonNull(eventsManager); + this.priority = priority; } @Override @@ -71,21 +73,22 @@ public void chargeVehicles(double chargePeriod, double now) { } } - int queuedToPluggedCount = Math.min(queuedVehicles.size(), charger.getPlugCount() - pluggedVehicles.size()); - for (int i = 0; i < queuedToPluggedCount; i++) { - plugVehicle(queuedVehicles.poll(), now); + var queuedVehiclesIter = queuedVehicles.iterator(); + while (queuedVehiclesIter.hasNext() && pluggedVehicles.size() < charger.getPlugCount()) { + var cv = queuedVehiclesIter.next(); + if (plugVehicle(cv, now)) { + queuedVehiclesIter.remove(); + } } var arrivingVehiclesIter = arrivingVehicles.iterator(); while (arrivingVehiclesIter.hasNext()) { var cv = arrivingVehiclesIter.next(); - if (pluggedVehicles.size() < charger.getPlugCount()) { - plugVehicle(cv, now); - } else { + if (pluggedVehicles.size() >= charger.getPlugCount() || !plugVehicle(cv, now)) { queueVehicle(cv, now); } - arrivingVehiclesIter.remove(); } + arrivingVehicles.clear(); } @Override @@ -106,14 +109,28 @@ public void removeVehicle(ElectricVehicle ev, double now) { eventsManager.processEvent(new ChargingEndEvent(now, charger.getId(), ev.getId(), ev.getBattery().getCharge())); listeners.remove(ev.getId()).notifyChargingEnded(ev, now); - if (!queuedVehicles.isEmpty()) { - plugVehicle(queuedVehicles.poll(), now); + var queuedVehiclesIter = queuedVehicles.iterator(); + while (queuedVehiclesIter.hasNext()) { + var queuedVehicle = queuedVehiclesIter.next(); + if (plugVehicle(queuedVehicle, now)) { + queuedVehiclesIter.remove(); + break; + } } } else { - // make sure ev was in the queue - Preconditions.checkState(queuedVehicles.remove(ev), "Vehicle (%s) is neither queued nor plugged at charger (%s)", ev.getId(), - charger.getId()); - eventsManager.processEvent(new QuitQueueAtChargerEvent(now, charger.getId(), ev.getId())); + var queuedVehiclesIter = queuedVehicles.iterator(); + while (queuedVehiclesIter.hasNext()) { + var queuedVehicle = queuedVehiclesIter.next(); + + if (queuedVehicle.ev() == ev) { + queuedVehiclesIter.remove(); + eventsManager.processEvent(new QuitQueueAtChargerEvent(now, charger.getId(), ev.getId())); + return; // found the vehicle + } + } + + throw new IllegalStateException(String.format("Vehicle (%s) is neither queued nor plugged at charger (%s)", ev.getId(), + charger.getId())); } } @@ -123,12 +140,20 @@ private void queueVehicle(ChargingVehicle cv, double now) { listeners.get(cv.ev().getId()).notifyVehicleQueued(cv.ev(), now); } - private void plugVehicle(ChargingVehicle cv, double now) { + private boolean plugVehicle(ChargingVehicle cv, double now) { + assert pluggedVehicles.size() < charger.getPlugCount(); + + if (!priority.requestPlugNext(cv, now)) { + return false; + } + if (pluggedVehicles.put(cv.ev().getId(), cv) != null) { throw new IllegalArgumentException(); } eventsManager.processEvent(new ChargingStartEvent(now, charger.getId(), cv.ev().getId(), cv.ev().getBattery().getCharge())); listeners.get(cv.ev().getId()).notifyChargingStarted(cv.ev(), now); + + return true; } private final Collection unmodifiablePluggedVehicles = Collections.unmodifiableCollection(pluggedVehicles.values()); @@ -147,14 +172,16 @@ public Collection getQueuedVehicles() { static public class Factory implements ChargingLogic.Factory { private final EventsManager eventsManager; + private final ChargingPriority.Factory chargingPriorityFactory; - public Factory(EventsManager eventsManager) { + public Factory(EventsManager eventsManager, ChargingPriority.Factory chargingPriorityFactory) { this.eventsManager = eventsManager; + this.chargingPriorityFactory = chargingPriorityFactory; } @Override public ChargingLogic create(ChargerSpecification charger) { - return new ChargingWithQueueingLogic(charger, eventsManager); + return new ChargingWithQueueingLogic(charger, eventsManager, chargingPriorityFactory.create(charger)); } } } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java index b24583feb13..6b9b30e8cfd 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java @@ -30,7 +30,7 @@ /** * @author Michal Maciejewski (michalm) */ -final class ElectricFleetSpecificationDefaultImpl implements ElectricFleetSpecification { +public final class ElectricFleetSpecificationDefaultImpl implements ElectricFleetSpecification { private final Map, ElectricVehicleSpecification> specifications = new LinkedHashMap<>(); @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java index ef18ae6cce6..e3a4caca03e 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java @@ -33,7 +33,7 @@ /** * @author Michal Maciejewski (michalm) */ -final class ElectricVehicleSpecificationDefaultImpl implements ElectricVehicleSpecification { +public final class ElectricVehicleSpecificationDefaultImpl implements ElectricVehicleSpecification { private final Vehicle matsimVehicle; diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java index 48a27563616..763a2cd70e1 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java @@ -28,7 +28,7 @@ /** * @author Michal Maciejewski (michalm) */ -final class ChargingInfrastructureSpecificationDefaultImpl implements ChargingInfrastructureSpecification { +public final class ChargingInfrastructureSpecificationDefaultImpl implements ChargingInfrastructureSpecification { private final SpecificationContainer container = new SpecificationContainer<>(); @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationManager.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationManager.java new file mode 100644 index 00000000000..6e6fa1e77c9 --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationManager.java @@ -0,0 +1,106 @@ +package org.matsim.contrib.ev.reservation; + +import java.util.LinkedList; +import java.util.List; + +import org.matsim.api.core.v01.IdMap; +import org.matsim.contrib.ev.fleet.ElectricVehicle; +import org.matsim.contrib.ev.infrastructure.Charger; +import org.matsim.contrib.ev.infrastructure.ChargerSpecification; +import org.matsim.core.controler.events.IterationStartsEvent; +import org.matsim.core.controler.listener.IterationStartsListener; + +/** + * This class is a singleton service that keeps a list of reservations for + * chargers. It can be used in combination with the + * ReservationBasedChargingPriority to let vehicle pass on to charging only if + * they have a proper reservation. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class ChargerReservationManager implements IterationStartsListener { + private final IdMap> reservations = new IdMap<>(Charger.class); + + public boolean isAvailable(ChargerSpecification charger, ElectricVehicle vehicle, double startTile, + double endTime) { + if (charger.getPlugCount() == 0) { + return false; + } + + if (!reservations.containsKey(charger.getId())) { + return true; + } + + int remaining = charger.getPlugCount(); + for (Reservation reservation : reservations.get(charger.getId())) { + if (reservation.vehicle != vehicle && isOverlapping(reservation, startTile, endTime)) { + remaining--; + } + } + + return remaining > 0; + } + + private boolean isOverlapping(Reservation reservation, double startTime, double endTime) { + if (startTime >= reservation.startTime && startTime <= reservation.endTime) { + return true; // start time within existing range + } else if (endTime >= reservation.startTime && endTime <= reservation.endTime) { + return true; // end time within existing range + } else if (startTime <= reservation.startTime && endTime >= reservation.endTime) { + return true; // new range covers existing range + } else { + return false; + } + } + + public Reservation addReservation(ChargerSpecification charger, ElectricVehicle vehicle, double startTime, + double endTime) { + if (isAvailable(charger, vehicle, startTime, endTime)) { + List chargerReservations = reservations.get(charger.getId()); + + if (chargerReservations == null) { + chargerReservations = new LinkedList<>(); + reservations.put(charger.getId(), chargerReservations); + } + + Reservation reservation = new Reservation(charger, vehicle, startTime, endTime); + chargerReservations.add(reservation); + + return reservation; + } + + return null; + } + + public boolean removeReservation(Reservation reservation) { + List chargerReservations = reservations.get(reservation.charger.getId()); + + if (chargerReservations != null) { + return chargerReservations.remove(reservation); + } + + return false; + } + + public Reservation findReservation(ChargerSpecification charger, ElectricVehicle vehicle, double now) { + List chargerReservations = reservations.get(charger.getId()); + + if (chargerReservations != null) { + for (Reservation reservation : chargerReservations) { + if (reservation.vehicle == vehicle && now >= reservation.startTime && now <= reservation.endTime) { + return reservation; + } + } + } + + return null; + } + + public record Reservation(ChargerSpecification charger, ElectricVehicle vehicle, double startTime, double endTime) { + } + + @Override + public void notifyIterationStarts(IterationStartsEvent event) { + reservations.clear(); + } +} \ No newline at end of file diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationModule.java new file mode 100644 index 00000000000..9a17f208055 --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ChargerReservationModule.java @@ -0,0 +1,35 @@ +package org.matsim.contrib.ev.reservation; + +import org.matsim.contrib.ev.charging.ChargingPriority; +import org.matsim.core.controler.AbstractModule; + +import com.google.inject.Provides; +import com.google.inject.Singleton; + +/** + * This module enables the reservation-based charging logic that requires + * vehicles to have or make a reservation when attempting to charge at a + * charger. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class ChargerReservationModule extends AbstractModule { + @Override + public void install() { + addControlerListenerBinding().to(ChargerReservationManager.class); + bind(ChargingPriority.Factory.class).to(ReservationBasedChargingPriority.Factory.class); + } + + @Provides + @Singleton + ReservationBasedChargingPriority.Factory provideReservationBasedChargingPriorityFactory( + ChargerReservationManager reservationManager) { + return new ReservationBasedChargingPriority.Factory(reservationManager); + } + + @Provides + @Singleton + ChargerReservationManager provideChargerReservationManager() { + return new ChargerReservationManager(); + } +} \ No newline at end of file diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ReservationBasedChargingPriority.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ReservationBasedChargingPriority.java new file mode 100644 index 00000000000..8ac5a79a8ad --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/reservation/ReservationBasedChargingPriority.java @@ -0,0 +1,64 @@ +package org.matsim.contrib.ev.reservation; + +import org.matsim.contrib.ev.charging.ChargingLogic.ChargingVehicle; +import org.matsim.contrib.ev.charging.ChargingPriority; +import org.matsim.contrib.ev.infrastructure.ChargerSpecification; +import org.matsim.contrib.ev.reservation.ChargerReservationManager.Reservation; + +/** + * This is an implementation of a charging priority which is backed by the + * ReservationManager: When a vehicle arrives, it is checked whether a + * reservation for this vehicle exists for the respective charger and the + * current time. In that case, the vehicle can be plugged if it is on top of the + * queue. If not, the ChargingPriority will try to make a reservation and if it + * is successful, the vehicle can start charging. In all other cases, the + * vehicle will stay in the queue until it is removed manually or a successful + * reservation can be made at a future time. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class ReservationBasedChargingPriority implements ChargingPriority { + private final ChargerReservationManager manager; + private final ChargerSpecification charger; + + public ReservationBasedChargingPriority(ChargerReservationManager manager, ChargerSpecification charger) { + this.charger = charger; + this.manager = manager; + } + + @Override + public boolean requestPlugNext(ChargingVehicle cv, double now) { + Reservation reservation = manager.findReservation(charger, cv.ev(), now); + + if (reservation != null) { + // vehicle has a reservation, can be plugged right away, consume reservation + manager.removeReservation(reservation); + return true; + } + + double endTime = cv.strategy().calcRemainingTimeToCharge() + now; + reservation = manager.addReservation(charger, cv.ev(), now, endTime); + + if (reservation != null) { + // vehicle did not have a reservation, but managed to create one on the fly, + // consume it directly + manager.removeReservation(reservation); + return true; + } + + return false; + } + + static public class Factory implements ChargingPriority.Factory { + private final ChargerReservationManager reservationManager; + + public Factory(ChargerReservationManager reservationManager) { + this.reservationManager = reservationManager; + } + + @Override + public ChargingPriority create(ChargerSpecification charger) { + return new ReservationBasedChargingPriority(reservationManager, charger); + } + } +} \ No newline at end of file diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargingProceduresCSVWriter.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargingProceduresCSVWriter.java index ae1c9d0c013..4cef65da81b 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargingProceduresCSVWriter.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargingProceduresCSVWriter.java @@ -83,8 +83,12 @@ private void proccessChargingEventSequences(CSVPrinter csvPrinter, Collection() { - @Inject - private ChargerPowerTimeProfileCalculator calculator; - @Inject - private MatsimServices matsimServices; + }); + bind(ChargerPowerTimeProfileCalculator.class).asEagerSingleton(); + addEventHandlerBinding().to(ChargerPowerTimeProfileCalculator.class); + addControlerListenerBinding().toProvider(new Provider<>() { + @Inject + private ChargerPowerTimeProfileCalculator calculator; + @Inject + private MatsimServices matsimServices; - @Override - public ControlerListener get() { - var profileView = new ChargerPowerTimeProfileView(calculator); - return new ProfileWriter(matsimServices,"ev",profileView,"charger_power_time_profiles"); + @Override + public ControlerListener get() { + var profileView = new ChargerPowerTimeProfileView(calculator); + return new ProfileWriter(matsimServices, "ev", profileView, "charger_power_time_profiles"); - } - }); + } + }); + } } } diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java index 760ce513035..652d0740975 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java @@ -27,10 +27,8 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.file.Path; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; @@ -54,6 +52,7 @@ public class CarrierLoadAnalysis implements CarrierShipmentPickupStartEventHandl final Carriers carriers; private final Map, LinkedList> vehicle2Load = new LinkedHashMap<>(); + private final Map, Integer> vehicle2DemandPerTour = new HashMap<>(); public CarrierLoadAnalysis(String delimiter, Carriers carriers) { this.delimiter = delimiter; @@ -69,9 +68,11 @@ public void handleEvent(CarrierShipmentPickupStartEvent event) { if (! vehicle2Load.containsKey(vehicleId)){ list = new LinkedList<>(); list.add(demand); + vehicle2DemandPerTour.put(vehicleId, demand); } else { list = vehicle2Load.get(vehicleId); list.add(list.getLast() + demand); + vehicle2DemandPerTour.put(vehicleId, vehicle2DemandPerTour.get(vehicleId) + demand); } vehicle2Load.put(vehicleId, list); } @@ -98,6 +99,8 @@ void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) thro "vehicleTypeId", "capacity", "maxLoad", + "maxLoadPercentage", + "handledDemand", "load state during tour")); bw1.newLine(); @@ -109,10 +112,15 @@ void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) thro final VehicleType vehicleType = VehicleUtils.findVehicle(vehicleId, scenario).getType(); final Double capacity = vehicleType.getCapacity().getOther(); + final Integer demand = vehicle2DemandPerTour.get(vehicleId); + final double maxLoadPercentage = Math.round(maxLoad / capacity * 10000)/100.0;; + bw1.write(vehicleId.toString()); bw1.write(delimiter + vehicleType.getId().toString()); bw1.write(delimiter + capacity); bw1.write(delimiter + maxLoad); + bw1.write(delimiter + maxLoadPercentage); + bw1.write(delimiter + demand); bw1.write(delimiter + load); bw1.newLine(); } diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java index 0502ae2e1c4..00c1f1dea61 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java @@ -124,6 +124,8 @@ public RunFreightAnalysisEventBased(Carriers carriers, String analysisOutputPath private void createScenarioForFreightAnalysis(String vehiclesPath, String networkPath, String carriersPath, String carriersVehicleTypesPath, String globalCrs) { + log.info("########## Starting Freight Analysis ##########"); + Config config = ConfigUtils.createConfig(); config.vehicles().setVehiclesFile(vehiclesPath); config.network().setInputFile(networkPath); diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java index 8615e0b3d75..8265dca2666 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java @@ -23,10 +23,7 @@ import com.graphhopper.jsprit.core.problem.constraint.HardActivityConstraint; import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext; -import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; -import com.graphhopper.jsprit.core.problem.solution.route.activity.DeliverShipment; -import com.graphhopper.jsprit.core.problem.solution.route.activity.PickupShipment; -import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; +import com.graphhopper.jsprit.core.problem.solution.route.activity.*; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -64,124 +61,81 @@ public DistanceConstraint(CarrierVehicleTypes vehicleTypes, } /** - * When adding a TourActivity to the tour and the new vehicle has an - * energyCapacity (fuel or electricity etc.) the algorithm always checks the - * fulfilled method if all conditions (constraints) are fulfilled or not. - * Because every activity is added separately and the pickup before the delivery - * of a shipment, it will investigate which additional distance is necessary for - * the pickup and which minimal additional distance of the associated Delivery - * is needed. This is also important for the fulfilled decision of this - * function. At the end the conditions checks if the consumption of the tour - * including the additional shipment is possible with the possible - * energyCapacity. + * When adding a TourActivity to the tour and the new vehicle has an energyCapacity (fuel or electricity etc.) the algorithm always checks the fulfilled method if all conditions (constraints) are fulfilled or not. + * If a delivery is added, it also accounts for the necessary consumption if the pickup is added at the given position of the tour. This is also important for the fulfilled decision of this + * function. In the end, the conditions check if the consumption of the tour including the additional shipment is possible with the possible energyCapacity. */ //TODO add the time dependencies of the distance calculation because the route choice can be different for different times @Override public ConstraintsStatus fulfilled(JobInsertionContext context, TourActivity prevAct, TourActivity newAct, - TourActivity nextAct, double departureTime) { - double additionalDistance; + TourActivity nextAct, double prevActDepTime) { +// double additionalDistance; + Vehicle newVehicle = context.getNewVehicle(); VehicleType vehicleTypeOfNewVehicle = vehicleTypes.getVehicleTypes() - .get(Id.create(context.getNewVehicle().getType().getTypeId(), VehicleType.class)); - if (VehicleUtils.getEnergyCapacity(vehicleTypeOfNewVehicle.getEngineInformation()) != null) { - - Vehicle newVehicle = context.getNewVehicle(); - - Double energyCapacityInKWhOrLiters = VehicleUtils - .getEnergyCapacity(vehicleTypeOfNewVehicle.getEngineInformation()); - Double consumptionPerMeter; - if (VehicleUtils.getHbefaTechnology(vehicleTypeOfNewVehicle.getEngineInformation()).equals("electricity")) - consumptionPerMeter = VehicleUtils - .getEnergyConsumptionKWhPerMeter(vehicleTypeOfNewVehicle.getEngineInformation()); + .get(Id.create(newVehicle.getType().getTypeId(), VehicleType.class)); + if (VehicleUtils.getEnergyCapacity(vehicleTypeOfNewVehicle.getEngineInformation()) == null) return ConstraintsStatus.FULFILLED; + + Double energyCapacityInKWhOrLiters = VehicleUtils + .getEnergyCapacity(vehicleTypeOfNewVehicle.getEngineInformation()); + Double consumptionPerMeter; + if (VehicleUtils.getHbefaTechnology(vehicleTypeOfNewVehicle.getEngineInformation()).equals("electricity")) + consumptionPerMeter = VehicleUtils + .getEnergyConsumptionKWhPerMeter(vehicleTypeOfNewVehicle.getEngineInformation()); + else + consumptionPerMeter = VehicleUtils.getFuelConsumptionLitersPerMeter(vehicleTypeOfNewVehicle.getEngineInformation()); + + double currentDistance = calculateRouteDistance(context, newVehicle); + double currentRouteConsumption = currentDistance * (consumptionPerMeter); + if (currentRouteConsumption > energyCapacityInKWhOrLiters) return ConstraintsStatus.NOT_FULFILLED_BREAK; + + double distancePrevAct2NewAct = getDistance(prevAct, newAct, newVehicle, prevActDepTime); + double distanceNewAct2nextAct = getDistance(newAct, nextAct, newVehicle, prevActDepTime); + double distancePrevAct2NextAct = getDistance(prevAct, nextAct, newVehicle, prevActDepTime); + if (prevAct instanceof Start && nextAct instanceof End) distancePrevAct2NextAct = 0; + if (nextAct instanceof End && !context.getNewVehicle().isReturnToDepot()) { + distanceNewAct2nextAct = 0; + distancePrevAct2NextAct = 0; + } + double additionalDistance = distancePrevAct2NewAct + distanceNewAct2nextAct - distancePrevAct2NextAct; + double additionalConsumption = additionalDistance * (consumptionPerMeter); + if (currentRouteConsumption + additionalConsumption > energyCapacityInKWhOrLiters) return ConstraintsStatus.NOT_FULFILLED; + + + double additionalDistanceOfPickup; + double additionalConsumptionOfPickup = 0; + if (newAct instanceof DeliverShipment) { + int iIndexOfPickup = context.getRelatedActivityContext().getInsertionIndex(); + TourActivity pickup = context.getAssociatedActivities().getFirst(); + TourActivity actBeforePickup; + if (iIndexOfPickup > 0) actBeforePickup = context.getRoute().getActivities().get(iIndexOfPickup - 1); + else actBeforePickup = new Start(context.getNewVehicle().getStartLocation(), 0, Double.MAX_VALUE); + TourActivity actAfterPickup; + if (iIndexOfPickup < context.getRoute().getActivities().size()) + actAfterPickup = context.getRoute().getActivities().get(iIndexOfPickup); else - consumptionPerMeter = VehicleUtils.getFuelConsumptionLitersPerMeter(vehicleTypeOfNewVehicle.getEngineInformation()); - - double routeDistance = calculateRouteDistance(context, newVehicle); - double routeConsumption = routeDistance * (consumptionPerMeter); - - if (newAct instanceof PickupShipment) { - // calculates the additional distance for adding a pickup and checks the shortest possibility for adding the associated delivery - additionalDistance = getDistance(prevAct, newAct, newVehicle) + getDistance(newAct, nextAct, newVehicle) - - getDistance(prevAct, nextAct, newVehicle)+ findMinimalAdditionalDistance(context, newAct, newAct); - - } else if (newAct instanceof DeliverShipment) { - // calculates the distance new for integrating the associated pickup - routeDistance = calculateRouteDistanceWithAssociatedPickup(context); - routeConsumption = routeDistance * (consumptionPerMeter); - - additionalDistance = getDistance(prevAct, newAct, newVehicle) + getDistance(newAct, nextAct, newVehicle) - - getDistance(prevAct, nextAct, newVehicle); - - } else { - additionalDistance = getDistance(prevAct, newAct, newVehicle) + getDistance(newAct, nextAct, newVehicle) - - getDistance(prevAct, nextAct, newVehicle); + actAfterPickup = nextAct; + double distanceActBeforePickup2Pickup = getDistance(actBeforePickup, pickup, newVehicle, actBeforePickup.getEndTime()); + double distancePickup2ActAfterPickup = getDistance(pickup, actAfterPickup, newVehicle, context.getRelatedActivityContext().getEndTime()); + double distanceBeforePickup2AfterPickup = getDistance(actBeforePickup, actAfterPickup,newVehicle, actBeforePickup.getEndTime()); + if (context.getRoute().isEmpty()) distanceBeforePickup2AfterPickup = 0; + if (actAfterPickup instanceof End && !context.getNewVehicle().isReturnToDepot()) { + distancePickup2ActAfterPickup = 0; + distanceBeforePickup2AfterPickup = 0; } - double additionalConsumption = additionalDistance * (consumptionPerMeter); - double newRouteConsumption = routeConsumption + additionalConsumption; - - if (newRouteConsumption > energyCapacityInKWhOrLiters) { - return ConstraintsStatus.NOT_FULFILLED_BREAK; - } else { - return ConstraintsStatus.FULFILLED; - } - } else { - return ConstraintsStatus.FULFILLED; + additionalDistanceOfPickup = distanceActBeforePickup2Pickup + distancePickup2ActAfterPickup - distanceBeforePickup2AfterPickup; + additionalConsumptionOfPickup = additionalDistanceOfPickup * (consumptionPerMeter); } - } - /** - * Calculates the distance based on the route-based distances between every tour - * activities. The method also integrates the associated pickup in the tour. - */ - private double calculateRouteDistanceWithAssociatedPickup(JobInsertionContext context) { - double routeDistance; - int positionOfRelatedPickup = context.getRelatedActivityContext().getInsertionIndex(); - int nextRouteActivity = 0; + if (currentRouteConsumption + additionalConsumption + additionalConsumptionOfPickup > energyCapacityInKWhOrLiters) + return ConstraintsStatus.NOT_FULFILLED; - // checks if the associated pickup is on first position - if (positionOfRelatedPickup == 0 && context.getRoute().getActivities().isEmpty()) { - context.getRoute().getStart().setLocation(context.getNewVehicle().getStartLocation()); - context.getRoute().getEnd().setLocation(context.getNewVehicle().getEndLocation()); - routeDistance = getDistance(context.getAssociatedActivities().getFirst(), context.getRoute().getEnd(), - context.getNewVehicle(), context.getNewDepTime()); - return routeDistance; - } else if (positionOfRelatedPickup == 0 && !context.getRoute().getActivities().isEmpty()) { - routeDistance = getDistance(context.getAssociatedActivities().getFirst(), - context.getRoute().getActivities().getFirst(), context.getNewVehicle(), context.getNewDepTime()); - } else { - routeDistance = getDistance(context.getRoute().getStart(), context.getRoute().getActivities().getFirst(), - context.getNewVehicle(), context.getNewDepTime()); - } - // adds distances between every tour activity and adds the associated pickup on - // the correct position of the tour - while (context.getRoute().getTourActivities().getActivities().size() > (nextRouteActivity + 1)) { - if (positionOfRelatedPickup == (nextRouteActivity + 1) && positionOfRelatedPickup != 0) { - routeDistance = routeDistance + getDistance(context.getRoute().getActivities().get(nextRouteActivity), - context.getAssociatedActivities().getFirst(), context.getNewVehicle()); - routeDistance = routeDistance + getDistance(context.getAssociatedActivities().getFirst(), - context.getRoute().getActivities().get(nextRouteActivity), context.getNewVehicle()); - } else { - routeDistance = routeDistance + getDistance(context.getRoute().getActivities().get(nextRouteActivity), - context.getRoute().getActivities().get(nextRouteActivity + 1), context.getNewVehicle()); - } - nextRouteActivity++; - } - if (positionOfRelatedPickup == context.getRoute().getActivities().size()) { - routeDistance = routeDistance + getDistance(context.getRoute().getActivities().get(nextRouteActivity), - context.getAssociatedActivities().getFirst(), context.getNewVehicle()); - routeDistance = routeDistance + getDistance(context.getAssociatedActivities().getFirst(), - context.getRoute().getEnd(), context.getNewVehicle()); - } else - routeDistance = routeDistance + getDistance(context.getRoute().getActivities().get(nextRouteActivity), - context.getRoute().getEnd(), context.getNewVehicle()); + return ConstraintsStatus.FULFILLED; - return routeDistance; } /** - * Calculates the distance based on the route-based distances between every tour - * activities. - * + * Calculates the distance based on the route-based distances between every tour activity. */ private double calculateRouteDistance(JobInsertionContext context, Vehicle newVehicle) { double realRouteDistance = 0; @@ -189,121 +143,20 @@ private double calculateRouteDistance(JobInsertionContext context, Vehicle newVe return realRouteDistance; int n = 0; realRouteDistance = getDistance(context.getRoute().getStart(), - context.getRoute().getTourActivities().getActivities().getFirst(), newVehicle); + context.getRoute().getTourActivities().getActivities().getFirst(), newVehicle, context.getRoute().getStart().getEndTime()); while (context.getRoute().getTourActivities().getActivities().size() > (n + 1)) { + + TourActivity from = context.getRoute().getTourActivities().getActivities().get(n); realRouteDistance = realRouteDistance - + getDistance(context.getRoute().getTourActivities().getActivities().get(n), - context.getRoute().getTourActivities().getActivities().get(n + 1), newVehicle); + + getDistance(from, context.getRoute().getTourActivities().getActivities().get(n + 1), newVehicle, from.getEndTime()); n++; } + TourActivity from = context.getRoute().getTourActivities().getActivities().get(n); realRouteDistance = realRouteDistance + getDistance( - context.getRoute().getTourActivities().getActivities().get(n), context.getRoute().getEnd(), newVehicle); + context.getRoute().getTourActivities().getActivities().get(n), context.getRoute().getEnd(), newVehicle, from.getEndTime()); return realRouteDistance; } - /** - * Finds a minimal additional distance for the tour, when a pickup is added to - * the plan. The AssociatedActivities contains both activities of a job which - * should be added to the existing tour. The TourActivities which are already in - * the tour are found in context.getRoute().getTourActivities. In this method - * the position of the new pickup is fixed and three options of the location of - * the delivery activity will be checked: delivery between every other activity - * after the pickup, delivery as the last activity before the end and delivery - * directly behind the new pickup. This method gives back the minimal distance - * of this three options. - * - * @param context the context of the job insertion - * @param newInvestigatedPickup the new pickup which should be added to the tour - * @param nextAct the next activity after the new pickup - * @return minimal distance of the associated delivery - */ - private double findMinimalAdditionalDistance(JobInsertionContext context, TourActivity newInvestigatedPickup, - TourActivity nextAct) { - double minimalAdditionalDistance = 0; - - if (context.getAssociatedActivities().get(1) instanceof DeliverShipment) { - TourActivity assignedDelivery = context.getAssociatedActivities().get(1); - minimalAdditionalDistance = 0; - int indexNextActivity = nextAct.getIndex(); - int tourPositionOfActivityBehindNewPickup = 0; - int countIndex = 0; - Vehicle newVehicle = context.getNewVehicle(); - VehicleRoute route = context.getRoute(); - - // search the index of the activity behind the pickup activity which should be - // added to the tour - a: for (TourActivity tourActivity : route.getTourActivities().getActivities()) { - if (tourActivity.getIndex() == indexNextActivity) { - while (countIndex < route.getTourActivities().getActivities().size()) { - if (route.getTourActivities().getActivities().get(countIndex).getIndex() == indexNextActivity) { - tourPositionOfActivityBehindNewPickup = countIndex; - break a; - } - countIndex++; - } - } - } - - // search the minimal distance between every exiting TourActivity - while ((tourPositionOfActivityBehindNewPickup + 1) < route.getTourActivities().getActivities().size()) { - TourActivity activityBefore = route.getTourActivities().getActivities() - .get(tourPositionOfActivityBehindNewPickup); - TourActivity activityAfter = route.getTourActivities().getActivities() - .get(tourPositionOfActivityBehindNewPickup + 1); - double possibleAdditionalDistance = getDistance(activityBefore, assignedDelivery, newVehicle) - + getDistance(assignedDelivery, activityAfter, newVehicle) - - getDistance(activityBefore, activityAfter, newVehicle); - minimalAdditionalDistance = findMinimalDistance(minimalAdditionalDistance, possibleAdditionalDistance); - tourPositionOfActivityBehindNewPickup++; - } - // checks the distance if the delivery is the last activity before the end of - // the tour - if (!route.getTourActivities().getActivities().isEmpty()) { - TourActivity activityLastDelivery = route.getTourActivities().getActivities() - .getLast(); - TourActivity activityEnd = route.getEnd(); - double possibleAdditionalDistance = getDistance(activityLastDelivery, assignedDelivery, newVehicle) - + getDistance(assignedDelivery, activityEnd, newVehicle) - - getDistance(activityLastDelivery, activityEnd, newVehicle); - minimalAdditionalDistance = findMinimalDistance(minimalAdditionalDistance, possibleAdditionalDistance); - - // Checks the distance if the delivery will be added directly behind the pickup - TourActivity activityAfter = route.getTourActivities().getActivities() - .get(tourPositionOfActivityBehindNewPickup); - possibleAdditionalDistance = getDistance(newInvestigatedPickup, assignedDelivery, newVehicle) - + getDistance(assignedDelivery, activityAfter, newVehicle) - - getDistance(newInvestigatedPickup, activityAfter, newVehicle); - minimalAdditionalDistance = findMinimalDistance(minimalAdditionalDistance, possibleAdditionalDistance); - } - - } - return minimalAdditionalDistance; - } - - /** - * Checks if the find possible distance is the minimal one. - * - * @param minimalAdditionalDistance the minimal additional distance - * @param possibleAdditionalDistance the possible additional distance - * @return the minimal transport distance - */ - private double findMinimalDistance(double minimalAdditionalDistance, double possibleAdditionalDistance) { - if (minimalAdditionalDistance == 0) - minimalAdditionalDistance = possibleAdditionalDistance; - else if (possibleAdditionalDistance < minimalAdditionalDistance) - minimalAdditionalDistance = possibleAdditionalDistance; - return minimalAdditionalDistance; - } - - private double getDistance(TourActivity from, TourActivity to, Vehicle vehicle) { - double distance = netBasedCosts.getDistance(from.getLocation(), to.getLocation(), from.getEndTime(), - vehicle); - if (!(distance >= 0.)) - throw new AssertionError("Distance must not be negative! From, to" + from + ", " + to - + " distance " + distance); - return distance; - } - private double getDistance(TourActivity from, TourActivity to, Vehicle vehicle, double departureTime) { double distance = netBasedCosts.getDistance(from.getLocation(), to.getLocation(), departureTime, vehicle); diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv index a1e0058ce5b..3d861e42d95 100644 --- a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv @@ -1 +1 @@ -vehicleId vehicleTypeId capacity maxLoad load state during tour +vehicleId vehicleTypeId capacity maxLoad maxLoadPercentage handledDemand load state during tour diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv index d61ddd36308..4216eeed0f3 100644 --- a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv @@ -1,2 +1,2 @@ -vehicleId vehicleTypeId capacity maxLoad load state during tour -freight_carrier1_veh_freight_carrier1_veh_heavyVehicle_1_1 heavy 50.0 26 [3, 8, 18, 25, 26, 23, 13, 12, 7, 0] +vehicleId vehicleTypeId capacity maxLoad maxLoadPercentage handledDemand load state during tour +freight_carrier1_veh_freight_carrier1_veh_heavyVehicle_1_1 heavy 50.0 26 52.0 26 [3, 8, 18, 25, 26, 23, 13, 12, 7, 0] diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceConfigGroup.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceConfigGroup.java index 709de1e45ba..76c9e429e0a 100644 --- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceConfigGroup.java +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceConfigGroup.java @@ -43,7 +43,7 @@ public class InformedModeChoiceConfigGroup extends ReflectiveConfigGroup { @Parameter @Comment("Require that new plan modes are always different from the current one.") - private boolean requireDifferentModes = true; + private boolean requireDifferentModes = false; @Parameter @Comment("Defines how constraint violations are handled.") diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java index e681025ef92..6c422644a14 100644 --- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java @@ -6,6 +6,8 @@ import com.google.inject.TypeLiteral; import com.google.inject.multibindings.MapBinder; import com.google.inject.multibindings.Multibinder; +import org.matsim.core.config.Config; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.listener.ControlerListener; import org.matsim.core.router.PlanRouter; @@ -13,20 +15,14 @@ import org.matsim.core.utils.timing.TimeInterpretation; import org.matsim.facilities.ActivityFacilities; import org.matsim.modechoice.constraints.TripConstraint; -import org.matsim.modechoice.estimators.ActivityEstimator; -import org.matsim.modechoice.estimators.FixedCostsEstimator; -import org.matsim.modechoice.estimators.LegEstimator; -import org.matsim.modechoice.estimators.TripEstimator; +import org.matsim.modechoice.estimators.*; import org.matsim.modechoice.pruning.CandidatePruner; import org.matsim.modechoice.replanning.*; import org.matsim.modechoice.search.BestChoiceGenerator; import org.matsim.modechoice.search.SingleTripChoicesGenerator; import org.matsim.modechoice.search.TopKChoicesGenerator; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * The main and only module needed to install to use informed mode choice functionality. @@ -35,12 +31,12 @@ */ public final class InformedModeChoiceModule extends AbstractModule { - public static String SELECT_BEST_K_PLAN_MODES_STRATEGY = "SelectBestKPlanModes"; + public final static String SELECT_BEST_K_PLAN_MODES_STRATEGY = "SelectBestKPlanModes"; - public static String SELECT_SINGLE_TRIP_MODE_STRATEGY = "SelectSingleTripMode"; + public final static String SELECT_SINGLE_TRIP_MODE_STRATEGY = "SelectSingleTripMode"; - public static String SELECT_SUBTOUR_MODE_STRATEGY = "SelectSubtourMode"; - public static String RANDOM_SUBTOUR_MODE_STRATEGY = "RandomSubtourMode"; + public final static String SELECT_SUBTOUR_MODE_STRATEGY = "SelectSubtourMode"; + public final static String RANDOM_SUBTOUR_MODE_STRATEGY = "RandomSubtourMode"; private final Builder builder; @@ -49,6 +45,33 @@ private InformedModeChoiceModule(Builder builder) { this.builder = builder; } + /** + * Replaces a strategy in the config. Can be used to enable one of the strategies in this module programmatically. + */ + public static void replaceReplanningStrategy(Config config, String subpopulation, + String existing, String replacement) { + + // Copy list because it is unmodifiable + List strategies = new ArrayList<>(config.replanning().getStrategySettings()); + List found = strategies.stream() + .filter(s -> s.getSubpopulation().equals(subpopulation)) + .filter(s -> s.getStrategyName().equals(existing)) + .toList(); + + if (found.isEmpty()) + throw new IllegalArgumentException("No strategy %s found for subpopulation %s".formatted(existing, subpopulation)); + + if (found.size() > 1) + throw new IllegalArgumentException("Multiple strategies %s found for subpopulation %s".formatted(existing, subpopulation)); + + ReplanningConfigGroup.StrategySettings old = found.getFirst(); + old.setStrategyName(replacement); + + // reset und set new strategies + config.replanning().clearStrategySettings(); + strategies.forEach(s -> config.replanning().addStrategySettings(s)); + } + public static Builder newBuilder() { return new Builder(); } @@ -56,14 +79,10 @@ public static Builder newBuilder() { @Override public void install() { - bindAllModes(builder.fixedCosts, new TypeLiteral<>() { - }); - bindAllModes(builder.legEstimators, new TypeLiteral<>() { - }); - bindAllModes(builder.tripEstimators, new TypeLiteral<>() { - }); - bindAllModes(builder.options, new TypeLiteral<>() { - }); + bindAllModes(builder.fixedCosts, new TypeLiteral<>() {}); + bindAllModes(builder.legEstimators, new TypeLiteral<>() {}); + bindAllModes(builder.tripEstimators, new TypeLiteral<>() {}); + bindAllModes(builder.options, new TypeLiteral<>() {}); bind(ActivityEstimator.class).to(builder.activityEstimator).in(Singleton.class); @@ -77,12 +96,16 @@ public void install() { bind(PlanModelService.class).asEagerSingleton(); addControlerListenerBinding().to(PlanModelService.class).asEagerSingleton(); - Multibinder> tcBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<>() { - }); + Multibinder> tcBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<>() {}); for (Class> c : builder.constraints) { tcBinder.addBinding().to(c).in(Singleton.class); } + Multibinder tripScores = Multibinder.newSetBinder(binder(), new TypeLiteral<>() {}); + for (Class c : builder.tripScoreEstimators) { + tripScores.addBinding().to(c).in(Singleton.class); + } + MapBinder pBinder = MapBinder.newMapBinder(binder(), String.class, CandidatePruner.class); for (Map.Entry e : builder.pruner.entrySet()) { CandidatePruner instance = e.getValue(); @@ -133,8 +156,7 @@ public PlanRouter planRouter(Provider tripRouter, ActivityFacilities private void bindAllModes(Map> map, TypeLiteral value) { // Ensure to bind to internal strings - MapBinder mapBinder = MapBinder.newMapBinder(binder(), new TypeLiteral<>() { - }, value); + MapBinder mapBinder = MapBinder.newMapBinder(binder(), new TypeLiteral<>() {}, value); for (Map.Entry> e : map.entrySet()) { Class clazz = e.getValue(); mapBinder.addBinding(e.getKey().intern()).to(clazz).in(Singleton.class); @@ -153,6 +175,7 @@ public static final class Builder { private final Map> options = new HashMap<>(); private final Set>> constraints = new LinkedHashSet<>(); + private final Set> tripScoreEstimators = new LinkedHashSet<>(); private final Map pruner = new HashMap<>(); @@ -230,6 +253,14 @@ public Builder withActivityEstimator(Class activity return this; } + /** + * Add general score estimator that is applied to all trips. + */ + public Builder withTripScoreEstimator(Class tripScoreEstimator) { + tripScoreEstimators.add(tripScoreEstimator); + return this; + } + /** * Builds the module, which can then be used with {@link #install()} */ diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java index 85f80664279..93e0fb86c67 100644 --- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java @@ -12,10 +12,7 @@ import org.matsim.core.router.TripStructureUtils; import org.matsim.core.utils.timing.TimeInterpretation; import org.matsim.modechoice.constraints.TripConstraint; -import org.matsim.modechoice.estimators.ActivityEstimator; -import org.matsim.modechoice.estimators.LegEstimator; -import org.matsim.modechoice.estimators.MinMaxEstimate; -import org.matsim.modechoice.estimators.TripEstimator; +import org.matsim.modechoice.estimators.*; import java.util.*; import java.util.function.Predicate; @@ -33,6 +30,9 @@ public final class PlanModelService implements StartupListener { @Inject private Map tripEstimator; + @Inject + private Set tripScores; + @Inject private Set> constraints; @@ -223,6 +223,10 @@ public void calculateEstimates(EstimatorContext context, PlanModel planModel) { // early or late arrival can also have an effect on the activity scores which is potentially considered here estimate += actEstimator.estimate(context, planModel.getStartTimes()[i] + tt, trip.getDestinationActivity()); + for (TripScoreEstimator tripScore : tripScores) { + estimate += tripScore.estimate(context, c.getMode(), trip); + } + values[i] = estimate; } } diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/commands/StrategyOptions.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/commands/StrategyOptions.java index 532c0995236..0b10695df86 100644 --- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/commands/StrategyOptions.java +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/commands/StrategyOptions.java @@ -154,8 +154,7 @@ public Module applyModule(Binder binder, Config config, Consumer config.replanning().addStrategySettings(s)); if (group.forceInnovation > 0) - binder.bind(new TypeLiteral>() { - }).toInstance(new ForceInnovationStrategyChooser<>(group.forceInnovation, ForceInnovationStrategyChooser.Permute.yes)); + binder.bind(new TypeLiteral>() {}).toInstance(new ForceInnovationStrategyChooser<>(group.forceInnovation, ForceInnovationStrategyChooser.Permute.yes)); InformedModeChoiceModule.Builder builder = InformedModeChoiceModule.newBuilder(); diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/estimators/TripScoreEstimator.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/estimators/TripScoreEstimator.java new file mode 100644 index 00000000000..d3105ce4514 --- /dev/null +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/estimators/TripScoreEstimator.java @@ -0,0 +1,18 @@ +package org.matsim.modechoice.estimators; + +import org.matsim.core.router.TripStructureUtils; +import org.matsim.modechoice.EstimatorContext; + +/** + * This class can be used to estimate additional scores for a trip. + * These score are added to the existing estimates and might be independent of the mode. + */ +public interface TripScoreEstimator { + + /** + * Compute a score estimate for a trip. + */ + double estimate(EstimatorContext context, String mainMode, TripStructureUtils.Trip trip); + + +} diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/pruning/PlanScoreThresholdPruner.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/pruning/PlanScoreThresholdPruner.java new file mode 100644 index 00000000000..e3446686715 --- /dev/null +++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/pruning/PlanScoreThresholdPruner.java @@ -0,0 +1,23 @@ +package org.matsim.modechoice.pruning; + +import org.matsim.modechoice.PlanModel; + +/** + * Removes plans by a fixed utility threshold. + */ +public class PlanScoreThresholdPruner implements CandidatePruner { + + private final double threshold; + + /** + * Threshold to be applied on the best known plan estimate. Candidates with a larger difference to the best, than this threshold are discarded. + */ + public PlanScoreThresholdPruner(double threshold) { + this.threshold = threshold; + } + + @Override + public double planThreshold(PlanModel planModel) { + return threshold; + } +} diff --git a/contribs/informed-mode-choice/src/test/java/org/matsim/modechoice/search/TopKMinMaxTest.java b/contribs/informed-mode-choice/src/test/java/org/matsim/modechoice/search/TopKMinMaxTest.java index 04cfe9860e2..5490b076de8 100644 --- a/contribs/informed-mode-choice/src/test/java/org/matsim/modechoice/search/TopKMinMaxTest.java +++ b/contribs/informed-mode-choice/src/test/java/org/matsim/modechoice/search/TopKMinMaxTest.java @@ -217,6 +217,9 @@ else if (invocationOnMock.getArgument(0).equals(TransportMode.walk)) { Multibinder> tcBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<>() { }); + Multibinder tEstBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<>() { + }); + MapBinder fcBinder = MapBinder.newMapBinder(binder(), new TypeLiteral<>() { }, new TypeLiteral<>() { }); diff --git a/contribs/parking/README.md b/contribs/parking/README.md index a9e090515c3..1285c0d5f86 100644 --- a/contribs/parking/README.md +++ b/contribs/parking/README.md @@ -12,4 +12,34 @@ approaches as to how parking can be handled in MATSim, depending on the use case . This was designed for large scenarios where it's not feasable to fully simulate parking agents. Rather, the additional time needed for parking is estimated - Parking Costs, developed by Marcel Rieser and Joschka Bischoff at SBB. This modules allows the integration of parking - costs based on link attribute data. \ No newline at end of file + costs based on link attribute data. + +## Implementations + +### Parking Search + +Model parking search, including walking segments and parking search traffic. + +Different Parking Search Logics: + +1. **Random:** + 1. Drive to the destination. + 2. The next link is chosen randomly. +2. **DistanceMemoryParkingSearch:** + 1. Drive to the destination. + 2. Select the next link: + 1. Choose an unknown link with the shortest straight-line distance to the destination. + 2. If all links are known, choose randomly. +3. **NearestParkingSpotSearchLogic:** + 1. Drive to the destination (??). + 2. Search for the facility with the shortest distance to the current location, considering the expected driving time and parking duration (and + possibly parking time restrictions). + 3. If no suitable facility is found ? +4. **BenensonParkingSearchLogic:** A more sophisticated strategy based on the Benenson + model: https://www.sciencedirect.com/science/article/pii/S0198971508000689 + +### Parking Proxy + +### Parking Costs + +### Parking Choice diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/BenensonDynLeg.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/BenensonDynLeg.java index 5bd6ca248bb..c7b041ba21a 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/BenensonDynLeg.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/BenensonDynLeg.java @@ -21,30 +21,30 @@ /** * @author schlenther *

- * Benenson et al defined 3 phases of parking search + * Benenson et al. defined 3 phases of parking search * OBSERVING: observation of parking situation while driving towards destination * SEARCH_WHILE_APPROACH: estimating the amount of free parking lots on the way to destination * and if applicable parking before arriving * SEARCH_FOR_NEXT: taking the next free parking space if it isn't too far away from destination */ enum ParkingMode { - DRIVING, OBSERVING, SEARCH_WHILE_APPROACH, SEARCH_FOR_NEXT + DRIVING, OBSERVING, SEARCH_WHILE_APPROACH, SEARCH_FOR_NEXT } -public class BenensonDynLeg extends ParkingDynLeg{ +public class BenensonDynLeg extends ParkingDynLeg { private static final Logger logger = LogManager.getLogger(BenensonDynLeg.class); private static final boolean logForDebug = false; private double totalObservedParkingSpaces = 0.0; private double observedFreeParkingSpaces = 0.0; - private double firstDestinationLinkEnterTime = 0; - private ParkingMode legStage = ParkingMode.DRIVING; + private double firstDestinationLinkEnterTime = 0; + private ParkingMode legStage = ParkingMode.DRIVING; public BenensonDynLeg(String mode, NetworkRoute route, ParkingSearchLogic logic, - ParkingSearchManager parkingManager, Id vehicleId, MobsimTimer timer, EventsManager events) { + ParkingSearchManager parkingManager, Id vehicleId, MobsimTimer timer, EventsManager events) { super(mode, route, logic, parkingManager, vehicleId, timer, events); - if (!(logic instanceof BenensonParkingSearchLogic)){ + if (!(logic instanceof BenensonParkingSearchLogic)) { throw new RuntimeException(); } } @@ -55,56 +55,68 @@ public void movedOverNode(Id newLinkId) { currentLinkId = newLinkId; if (this.legStage == ParkingMode.DRIVING) { - if (((BenensonParkingSearchLogic) this.logic).transitionToObservingBehaviour(currentLinkId, this.route.getEndLinkId())) { - this.legStage = ParkingMode.OBSERVING; + if (((BenensonParkingSearchLogic) this.logic).transitionToObservingBehaviour(currentLinkId, this.route.getEndLinkId())) { + this.legStage = ParkingMode.OBSERVING; this.events.processEvent(new StartParkingSearchEvent(timer.getTimeOfDay(), vehicleId, currentLinkId)); - if(logForDebug)logger.error("vehicle " + this.vehicleId + " goes into observing on link " + this.currentLinkId); + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " goes into observing on link " + this.currentLinkId); + } } } - if(this.legStage == ParkingMode.OBSERVING ){ + if (this.legStage == ParkingMode.OBSERVING) { memorizeParkingSituationAndIsSomethingFree(); - if (((BenensonParkingSearchLogic) this.logic).transitionToParkingBehaviour(currentLinkId, this.route.getEndLinkId())) { - this.legStage = ParkingMode.SEARCH_WHILE_APPROACH; - if(logForDebug)logger.error("vehicle " + this.vehicleId + " goes into parking on link " + this.currentLinkId); + if (((BenensonParkingSearchLogic) this.logic).transitionToParkingBehaviour(currentLinkId, this.route.getEndLinkId())) { + this.legStage = ParkingMode.SEARCH_WHILE_APPROACH; + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " goes into parking on link " + this.currentLinkId); + } } } - if(this.legStage == ParkingMode.SEARCH_WHILE_APPROACH){ - if(currentLinkId.equals(route.getEndLinkId())){ + if (this.legStage == ParkingMode.SEARCH_WHILE_APPROACH) { + if (currentLinkId.equals(route.getEndLinkId())) { this.legStage = ParkingMode.SEARCH_FOR_NEXT; - this.firstDestinationLinkEnterTime = timer.getTimeOfDay(); - } - else{ - if(memorizeParkingSituationAndIsSomethingFree()){ + this.firstDestinationLinkEnterTime = timer.getTimeOfDay(); + } else { + if (memorizeParkingSituationAndIsSomethingFree()) { double pUnoccupied = 0; - if(this.totalObservedParkingSpaces > 0){ + if (this.totalObservedParkingSpaces > 0) { pUnoccupied = this.observedFreeParkingSpaces / this.totalObservedParkingSpaces; } - if ( ((BenensonParkingSearchLogic)this.logic).wantToParkHere(pUnoccupied, currentLinkId, route.getEndLinkId())){ - if (logForDebug) logger.error("vehicle " + this.vehicleId + " would like to park on link" + currentLinkId - + "\n \t pUnoccupied = " + pUnoccupied + "\n\t totalObservedParkingSpaces = " + totalObservedParkingSpaces + "\n\t observedFreeSpaces = " + this.observedFreeParkingSpaces); - hasFoundParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, currentLinkId); - } - } - else{ - if(logForDebug)logger.error("nothing free for vehicle " + vehicleId + " on link " + currentLinkId); + if (((BenensonParkingSearchLogic) this.logic).wantToParkHere(pUnoccupied, currentLinkId, route.getEndLinkId())) { + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " would like to park on link" + currentLinkId + + "\n \t pUnoccupied = " + pUnoccupied + "\n\t totalObservedParkingSpaces = " + totalObservedParkingSpaces + "\n\t " + + "observedFreeSpaces = " + this.observedFreeParkingSpaces); + } + hasFoundParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, currentLinkId); + } + } else { + if (logForDebug) { + logger.error("nothing free for vehicle " + vehicleId + " on link " + currentLinkId); + } } } } - if (this.legStage == ParkingMode.SEARCH_FOR_NEXT){ - if (logForDebug) logger.error("vehicle " + this.vehicleId + " is in PHASE3 on link " + this.currentLinkId); - //if( ((BenensonParkingSearchLogic)this.logic).isDriverInAcceptableDistance(currentLinkId, route.getEndLinkId(), this.firstDestLinkEnterTimer, timer.getTimeOfDay()) ){ + if (this.legStage == ParkingMode.SEARCH_FOR_NEXT) { + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " is in PHASE3 on link " + this.currentLinkId); + } + //if( ((BenensonParkingSearchLogic)this.logic).isDriverInAcceptableDistance(currentLinkId, route.getEndLinkId(), this + // .firstDestLinkEnterTimer, timer.getTimeOfDay()) ){ - hasFoundParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, currentLinkId); + hasFoundParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, currentLinkId); - if (logForDebug) logger.error("vehicle " + this.vehicleId + " tries in PHASE3 to park on link " + this.currentLinkId + ", " + - (int) (timer.getTimeOfDay() - this.firstDestinationLinkEnterTime) / 60 + ":" + (int) (timer.getTimeOfDay() - this.firstDestinationLinkEnterTime) % 60 - + " min after passing destination. Result: " + hasFoundParking); - //} - } - } + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " tries in PHASE3 to park on link " + this.currentLinkId + ", " + + (int) (timer.getTimeOfDay() - this.firstDestinationLinkEnterTime) / 60 + ":" + (int) (timer.getTimeOfDay() - this.firstDestinationLinkEnterTime) % 60 + + " min after passing destination. Result: " + hasFoundParking); + } + //} + } + } - /** + /** * returns true if there is at least one empty slot on the current link */ private boolean memorizeParkingSituationAndIsSomethingFree() { @@ -124,13 +136,14 @@ public Id getNextLinkId() { return route.getEndLinkId(); } return linkIds.get(currentLinkIdx + 1); - } - else { + } else { if (hasFoundParking) { - if(logForDebug)logger.error("vehicle " + this.vehicleId + " has found a parking on link " + this.currentLinkId + " after passing " + Math.abs((this.route.getLinkIds().size() - this.currentLinkIdx - 3)) + " links"); + if (logForDebug) { + logger.error("vehicle " + this.vehicleId + " has found a parking on link " + this.currentLinkId + " after passing " + Math.abs((this.route.getLinkIds() + .size() - this.currentLinkIdx - 3)) + " links"); + } return null; - } - else { + } else { if (this.currentAndNextParkLink != null) { if (currentAndNextParkLink.getFirst().equals(currentLinkId)) { // we already calculated this @@ -139,15 +152,15 @@ public Id getNextLinkId() { } Id nextLinkId; - if(this.legStage == ParkingMode.SEARCH_FOR_NEXT){ - nextLinkId = ((BenensonParkingSearchLogic) this.logic).getNextLinkRandomInAcceptableDistance(currentLinkId, this.route.getEndLinkId(), - vehicleId, firstDestinationLinkEnterTime, this.timer.getTimeOfDay(), mode); - } - else{ + if (this.legStage == ParkingMode.SEARCH_FOR_NEXT) { + nextLinkId = ((BenensonParkingSearchLogic) this.logic).getNextLinkRandomInAcceptableDistance(currentLinkId, + this.route.getEndLinkId(), + vehicleId, firstDestinationLinkEnterTime, this.timer.getTimeOfDay(), mode); + } else { nextLinkId = ((BenensonParkingSearchLogic) (this.logic)).getNextLinkBenensonRouting(currentLinkId, route.getEndLinkId(), mode); - } - currentAndNextParkLink = new Tuple<>(currentLinkId, nextLinkId); - return nextLinkId; + } + currentAndNextParkLink = new Tuple<>(currentLinkId, nextLinkId); + return nextLinkId; } } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java index a5f4cdcf143..ba81ede9c1d 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java @@ -45,10 +45,12 @@ public NearestParkingDynLeg(Leg currentPlannedLeg, NetworkRoute route, Plan plan this.currentPlannedLeg = currentPlannedLeg; this.plan = plan; this.planIndexNextActivity = planIndexNextActivity; - if (ParkingUtils.checkIfActivityHasNoParking(followingActivity)) + if (ParkingUtils.checkIfActivityHasNoParking(followingActivity)) { parkingAtEndOfLeg = false; - if (ParkingUtils.checkIfActivityHasPassengerInteraction(followingActivity)) + } + if (ParkingUtils.checkIfActivityHasPassengerInteraction(followingActivity)) { passangerInteractionAtParkingFacilityAtEndOfLeg = true; + } } @Override @@ -67,20 +69,22 @@ public void movedOverNode(Id newLinkId) { if (hasFoundParking) { this.events.processEvent(new ReserveParkingLocationEvent(timer.getTimeOfDay(), vehicleId, currentLinkId, currentLinkId)); nextSelectedParkingLink = currentLinkId; - } else + } else { ((FacilityBasedParkingManager) parkingManager).registerRejectedReservation(timer.getTimeOfDay()); + } } } } else if (followingActivity.getLinkId().equals(newLinkId)) { - if (alreadyReservedParking) + if (alreadyReservedParking) { hasFoundParking = true; - else { + } else { hasFoundParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, currentLinkId); if (hasFoundParking) { this.events.processEvent(new ReserveParkingLocationEvent(timer.getTimeOfDay(), vehicleId, currentLinkId, currentLinkId)); nextSelectedParkingLink = currentLinkId; - } else + } else { ((FacilityBasedParkingManager) parkingManager).registerRejectedReservation(timer.getTimeOfDay()); + } } } } @@ -138,11 +142,10 @@ public Id getNextLinkId() { // need to find the next link double nextPickupTime; double maxParkingDuration; - if (passangerInteractionAtParkingFacilityAtEndOfLeg){ + if (passangerInteractionAtParkingFacilityAtEndOfLeg) { nextPickupTime = 0.; maxParkingDuration = followingActivity.getMaximumDuration().seconds(); - } - else { + } else { nextPickupTime = currentPlannedLeg.getDepartureTime().seconds() + followingActivity.getMaximumDuration().seconds(); maxParkingDuration = nextPickupTime - timer.getTimeOfDay(); } @@ -163,11 +166,12 @@ public Id getNextLinkId() { nextSelectedParkingLink = nextPlanedParkingLink; if (((NearestParkingSpotSearchLogic) this.logic).canReserveParkingSlot()) { alreadyReservedParking = parkingManager.reserveSpaceIfVehicleCanParkHere(vehicleId, nextSelectedParkingLink); - if (alreadyReservedParking) + if (alreadyReservedParking) { this.events.processEvent( new ReserveParkingLocationEvent(timer.getTimeOfDay(), vehicleId, currentLinkId, nextSelectedParkingLink)); - else + } else { ((FacilityBasedParkingManager) parkingManager).registerRejectedReservation(timer.getTimeOfDay()); + } } else { this.events.processEvent( new SelectNewParkingLocationEvent(timer.getTimeOfDay(), vehicleId, currentLinkId, nextSelectedParkingLink)); @@ -176,13 +180,16 @@ public Id getNextLinkId() { } } currentAndNextParkLink = new Tuple<>(currentLinkId, nextLinkId); - if (((NearestParkingSpotSearchLogic) this.logic).getNextRoute() != null) + if (((NearestParkingSpotSearchLogic) this.logic).getNextRoute() != null) { currentPlannedLeg.setRoute(((NearestParkingSpotSearchLogic) this.logic).getNextRoute()); + } return nextLinkId; } } } + //yyyy I assume, the vehicle is removed from the link's queue and thus waiting for parking does not influence the behaviour of the mobsim? + // Does this make sense? paul, nov'24 private void createWaitingActivityUntilPassengerInteractionIsPossible(Id newLinkId, Id vehicleId, double now) { Activity waitingActivity = PopulationUtils.createActivityFromLinkId(ParkingUtils.WaitingForParkingActivityType, newLinkId); ParkingUtils.setNoParkingForActivity(waitingActivity); @@ -195,7 +202,8 @@ private void removeNextActivityAndFollowingLeg() { plan.getPlanElements().remove(planIndexNextActivity); plan.getPlanElements().remove(planIndexNextActivity); // log.info( -// plan.getPerson().getId().toString() + ": Parking activity after getOff point '" + ((Activity)plan.getPlanElements().get(planIndexNextActivity - 2)).getType() + "' is removed, because no parking facility was found."); +// plan.getPerson().getId().toString() + ": Parking activity after getOff point '" + ((Activity)plan.getPlanElements().get +// (planIndexNextActivity - 2)).getType() + "' is removed, because no parking facility was found."); } public boolean driveToBaseWithoutParking() { diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java index f3a7e671b14..b0095eb5cf7 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java @@ -52,19 +52,20 @@ public DynAction computeNextAction(DynAction oldAction, double now) { // unpark activity: find the way to the next route & start leg //if a parking activity was skipped we need no change the nexParkActionState - if (lastParkActionState.equals(LastParkActionState.CARTRIP) && ((NearestParkingDynLeg) oldAction).driveToBaseWithoutParking()) + if (lastParkActionState.equals(LastParkActionState.CARTRIP) && ((NearestParkingDynLeg) oldAction).driveToBaseWithoutParking()) { this.lastParkActionState = LastParkActionState.WALKFROMPARK; + } - return switch (lastParkActionState) { - case ACTIVITY -> nextStateAfterActivity(oldAction, now); - case CARTRIP -> nextStateAfterCarTrip(oldAction, now); - case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now); - case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now); - case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now); - case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now); - case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now); - }; - } + return switch (lastParkActionState) { + case ACTIVITY -> nextStateAfterActivity(oldAction, now); + case CARTRIP -> nextStateAfterCarTrip(oldAction, now); + case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now); + case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now); + case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now); + case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now); + case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now); + }; + } @Override protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) { @@ -75,20 +76,24 @@ protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now Route plannedRoute = currentPlannedLeg.getRoute(); NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId()); actualRoute.setVehicleId(currentlyAssignedVehicleId); - if (!plannedRoute.getStartLinkId().equals(actualRoute.getStartLinkId())) + if (!plannedRoute.getStartLinkId().equals(actualRoute.getStartLinkId())) { currentPlannedLeg.setRoute(actualRoute); + } if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isInitialLocation)) { this.lastParkActionState = LastParkActionState.CARTRIP; isInitialLocation = false; // Leg currentLeg = (Leg) this.currentPlanElement; int planIndexNextActivity = planIndex + 1; Activity nextPlanElement = (Activity) plan.getPlanElements().get(planIndexNextActivity); - if (ParkingUtils.checkIfActivityHasNoParking(nextPlanElement)) + if (ParkingUtils.checkIfActivityHasNoParking(nextPlanElement)) { this.lastParkActionState = LastParkActionState.WALKFROMPARK; + } //this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this. return new NearestParkingDynLeg(currentPlannedLeg, actualRoute, plan, planIndexNextActivity, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events); - } else throw new RuntimeException("parking location mismatch"); + } else { + throw new RuntimeException("parking location mismatch"); + } } @@ -101,17 +106,19 @@ protected DynAction nextStateAfterParkActivity(DynAction oldAction, double now) List walkTrip = walkRouter.calcRoute( DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson())); if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg)) { - String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!"; + String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to " + + "access the network. Not implemented in parking yet!"; log.error(message); throw new RuntimeException(message); } Leg walkLeg = (Leg) walkTrip.get(0); this.lastParkActionState = LastParkActionState.WALKFROMPARK; this.stageInteractionType = null; - if (!walkLeg.getTravelTime().equals(OptionalTime.defined(0.))) + if (!walkLeg.getTravelTime().equals(OptionalTime.defined(0.))) { return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode()); - else + } else { return nextStateAfterWalkFromPark(oldAction, now); + } } @Override @@ -125,15 +132,20 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now); return nextStateAfterNonCarTrip(oldAction, now); } - if (plan.getPlanElements().get(planIndex + 1) instanceof Activity) + if (plan.getPlanElements().get(planIndex + 1) instanceof Activity) { return nextStateAfterNonCarTrip(oldAction, now); - if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType().contains("_GetOff")) { + } + if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType() + .contains("_GetOff")) { ((Activity) plan.getPlanElements().get(planIndex)).setEndTime(now); - ((Activity) plan.getPlanElements().get(planIndex + 4)).setStartTime(now + ((Activity) plan.getPlanElements().get(planIndex + 2)).getMaximumDuration().seconds()); + ((Activity) plan.getPlanElements().get(planIndex + 4)).setStartTime(now + ((Activity) plan.getPlanElements() + .get(planIndex + 2)).getMaximumDuration() + .seconds()); // checks if it is possible to stay from getOff until getIn - boolean possibleToStay = checkIfParkingIsPossibleUntilNextActivities(this.planIndex,this.planIndex + 2); - if (possibleToStay) + boolean possibleToStay = checkIfParkingIsPossibleUntilNextActivities(this.planIndex, this.planIndex + 2); + if (possibleToStay) { return nextStateAfterNonCarTrip(oldAction, now); + } } planIndex++; this.currentPlanElement = plan.getPlanElements().get(planIndex); @@ -143,7 +155,8 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { Id parkLink = this.parkingManager.getVehicleParkingLocation(vehicleId); if (parkLink == null) { - //this is the first activity of a day and our parking manager does not provide information about initial stages. We suppose the car is parked where we are + //this is the first activity of a day and our parking manager does not provide information about initial stages. We suppose the + // car is parked where we are parkLink = agent.getCurrentLinkId(); } @@ -154,7 +167,8 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { List walkTrip = walkRouter.calcRoute( DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson())); if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) { - String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!"; + String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk" + + " to access the network. Not implemented in parking yet!"; log.error(message); throw new RuntimeException(message); } @@ -180,9 +194,12 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { return new StaticPassengerDynLeg(currentLeg.getRoute(), currentLeg.getMode()); } - } else throw new RuntimeException( - "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime( - now)); + } else { + throw new RuntimeException( + "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + + "\nTime: " + Time.writeTime( + now)); + } } @Override @@ -190,8 +207,9 @@ protected DynAction nextStateAfterWalkToPark(DynAction oldAction, double now) { //walk2park is complete, we can unpark. this.lastParkActionState = LastParkActionState.UNPARKACTIVITY; Activity beforePlanElement = (Activity) plan.getPlanElements().get(planIndex - 1); - if (ParkingUtils.checkIfActivityHasNoParking(beforePlanElement)) + if (ParkingUtils.checkIfActivityHasNoParking(beforePlanElement)) { return nextStateAfterUnParkActivity(oldAction, now); // wenn kein Parken dann einfach weiter + } return new IdleDynActivity(this.stageInteractionType, now + configGroup.getUnparkduration()); } @@ -211,7 +229,9 @@ protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) { this.currentlyAssignedVehicleId = null; this.parkingLogic.reset(); return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration()); - } else throw new RuntimeException("No parking possible"); + } else { + throw new RuntimeException("No parking possible"); + } } @Override @@ -221,7 +241,7 @@ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) { Activity nextPlannedActivity = (Activity) this.currentPlanElement; // checks if you can extend parking here until getIn if (nextPlannedActivity.getType().equals(ParkingUtils.ParkingActivityType) && plan.getPlanElements().get(planIndex + 2) instanceof Leg) { - checkIfParkingIsPossibleUntilNextActivities(planIndex + 1,planIndex + 1); + checkIfParkingIsPossibleUntilNextActivities(planIndex + 1, planIndex + 1); } // switch back to activity planIndex++; @@ -249,11 +269,11 @@ private boolean checkIfParkingIsPossibleUntilNextActivities(int indexOfCurrentAc Activity currentActivity = ((Activity) plan.getPlanElements().get(this.planIndex)); Activity activityAfterFollowing = ((Activity) plan.getPlanElements().get(this.planIndex + 4)); if (agent.getCurrentLinkId().equals(activityAfterFollowing.getLinkId()) && !ParkingUtils.checkIfActivityHasNoParking( - (Activity) currentPlanElement)) { + (Activity) currentPlanElement)) { boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd( agent.getCurrentLinkId(), - followingActivity.getMaximumDuration().seconds(), currentActivity.getMaximumDuration().seconds(), - activityAfterFollowing.getMaximumDuration().seconds(), timer.getTimeOfDay()); + timer.getTimeOfDay(), currentActivity.getMaximumDuration().seconds(), followingActivity.getMaximumDuration().seconds(), + activityAfterFollowing.getMaximumDuration().seconds()); if (canParkAtFacilityUntilGetIn) { plan.getPlanElements().remove(this.planIndex + 3); plan.getPlanElements().remove(this.planIndex + 1); @@ -269,8 +289,8 @@ else if (indexOfCurrentActivity == indexOfParkingActivity) { followingActivity)) { boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd( agent.getCurrentLinkId(), - currentActivity.getMaximumDuration().seconds(), 0., - followingActivity.getMaximumDuration().seconds(), timer.getTimeOfDay()); + timer.getTimeOfDay(), 0., currentActivity.getMaximumDuration().seconds(), + followingActivity.getMaximumDuration().seconds()); if (canParkAtFacilityUntilGetIn) { plan.getPlanElements().remove(indexOfParkingActivity + 1); currentActivity.setEndTime(followingActivity.getStartTime().seconds()); diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java index dd2fb4fa74b..31e175a3d30 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java @@ -19,25 +19,14 @@ package org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic; -import java.util.List; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.population.Activity; -import org.matsim.api.core.v01.population.Leg; -import org.matsim.api.core.v01.population.Plan; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.api.core.v01.population.Route; -import org.matsim.contrib.dynagent.DynAction; -import org.matsim.contrib.dynagent.DynActivity; -import org.matsim.contrib.dynagent.DynAgent; -import org.matsim.contrib.dynagent.DynAgentLogic; -import org.matsim.contrib.dynagent.IdleDynActivity; -import org.matsim.contrib.dynagent.StaticPassengerDynLeg; +import org.matsim.api.core.v01.population.*; +import org.matsim.contrib.dynagent.*; import org.matsim.contrib.parking.parkingsearch.DynAgent.ParkingDynLeg; import org.matsim.contrib.parking.parkingsearch.ParkingUtils; import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager; @@ -56,8 +45,12 @@ import org.matsim.pt.routes.TransitPassengerRoute; import org.matsim.vehicles.Vehicle; +import java.util.List; + /** + * This class represents the logic for a {@link DynAgent}. It can only handle car legs for parking. + * * @author jbischoff */ public class ParkingAgentLogic implements DynAgentLogic { @@ -139,17 +132,17 @@ public DynAction computeNextAction(DynAction oldAction, double now) { // ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode // walk-leg to car: add unpark activity // unpark activity: find the way to the next route & start leg - return switch (lastParkActionState) { - case ACTIVITY -> nextStateAfterActivity(oldAction, now); - case CARTRIP -> nextStateAfterCarTrip(oldAction, now); - case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now); - case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now); - case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now); - case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now); - case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now); - }; + return switch (lastParkActionState) { + case ACTIVITY -> nextStateAfterActivity(oldAction, now); + case CARTRIP -> nextStateAfterCarTrip(oldAction, now); + case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now); + case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now); + case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now); + case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now); + case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now); + }; - } + } protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) { // we have unparked, now we need to get going by car again. @@ -164,7 +157,9 @@ protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now //this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this. return new ParkingDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events); - } else throw new RuntimeException("parking location mismatch"); + } else { + throw new RuntimeException("parking location mismatch"); + } } @@ -175,19 +170,25 @@ protected DynAction nextStateAfterWalkToPark(DynAction oldAction, double now) { } protected DynAction nextStateAfterWalkFromPark(DynAction oldAction, double now) { - //walkleg complete, time to get the next activity from the plan Elements and start it, this is basically the same as arriving on any other mode + //walkleg complete, time to get the next activity from the plan Elements and start it, this is basically the same as arriving on any other + // mode return nextStateAfterNonCarTrip(oldAction, now); } protected DynAction nextStateAfterParkActivity(DynAction oldAction, double now) { // add a walk leg after parking Leg currentPlannedLeg = (Leg) currentPlanElement; + + // yyyy I think we don't want LinkWrapperFacilities but the actual facilities. Right now, only calculates the teleportation from link to + // link, but if the parking happens on the same link as the activity, then it does not consider the coordinates. Thus, it produces a + // degenerated (0m and 0s) walk leg. paul, nov'24 Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId())); Facility toFacility = new LinkWrapperFacility(network.getLinks().get(currentPlannedLeg.getRoute().getEndLinkId())); List walkTrip = walkRouter.calcRoute( DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson())); if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) { - String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!"; + String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to " + + "access the network. Not implemented in parking yet!"; log.error(message); throw new RuntimeException(message); } @@ -224,7 +225,9 @@ protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) { this.currentlyAssignedVehicleId = null; this.parkingLogic.reset(); return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration()); - } else throw new RuntimeException("No parking possible"); + } else { + throw new RuntimeException("No parking possible"); + } } protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { @@ -233,15 +236,22 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { planIndex++; this.currentPlanElement = plan.getPlanElements().get(planIndex); Leg currentLeg = (Leg) currentPlanElement; + + // yyyy can only handle car legs for parking :-( paul, nov'24 if (currentLeg.getMode().equals(TransportMode.car)) { Id vehicleId = Id.create(this.agent.getId(), Vehicle.class); Id parkLink = this.parkingManager.getVehicleParkingLocation(vehicleId); if (parkLink == null) { - //this is the first activity of a day and our parking manager does not provide informations about initial stages. We suppose the car is parked where we are + //this is the first activity of a day and our parking manager does not provide information about initial stages. We suppose the + // car is parked where we are parkLink = agent.getCurrentLinkId(); } + // yyyy I think we don't want LinkWrapperFacilities but the actual facilities. Right now, only calculates the teleportation from + // link to + // link, but if the parking happens on the same link as the activity, then it does not consider the coordinates. Thus, it produces a + // degenerated (0m and 0s) walk leg. paul, nov'24 Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId())); Id teleportedParkLink = this.teleportationLogic.getVehicleLocation(agent.getCurrentLinkId(), vehicleId, parkLink, now, currentLeg.getMode()); @@ -249,7 +259,8 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { List walkTrip = walkRouter.calcRoute( DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson())); if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) { - String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!"; + String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with " + + "non_network_walk to access the network. Not implemented in parking yet!"; log.error(message); throw new RuntimeException(message); } @@ -271,9 +282,11 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) { return new StaticPassengerDynLeg(currentLeg.getRoute(), currentLeg.getMode()); } - } else throw new RuntimeException( - "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime( - now)); + } else { + throw new RuntimeException( + "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + + "\nTime: " + Time.writeTime(now)); + } } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java deleted file mode 100644 index 41e370c8065..00000000000 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java +++ /dev/null @@ -1,117 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2016 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.contrib.parking.parkingsearch.evaluation; - - -import com.google.inject.Inject; -import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager; -import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager; -import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.controler.events.IterationEndsEvent; -import org.matsim.core.controler.listener.IterationEndsListener; -import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; -import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; -import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; -import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; -import org.matsim.core.mobsim.qsim.QSim; -import org.matsim.core.utils.io.IOUtils; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.util.List; - -/** - * @author jbischoff - * - */ - -public class ParkingListener implements IterationEndsListener, MobsimBeforeSimStepListener, MobsimInitializedListener { - - @Inject - ParkingSearchManager manager; - @Inject - OutputDirectoryHierarchy output; - - /* (non-Javadoc) - * @see org.matsim.core.controler.listener.IterationEndsListener#notifyIterationEnds(org.matsim.core.controler.events.IterationEndsEvent) - */ - @Override - public void notifyIterationEnds(IterationEndsEvent event) { - writeStats(manager.produceStatistics(), event.getIteration()); - writeStatsByTimesteps(((FacilityBasedParkingManager)manager).produceTimestepsStatistics(), event.getIteration()); - manager.reset(event.getIteration()); - } - - private void writeStatsByTimesteps(List produceBeneStatistics, int iteration) { - BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStatsPerTimeSteps.csv")); - try { - - String header = "time;rejectedParkingRequest;foundParking;unpark"; - bw.write(header); - bw.newLine(); - for (String s : produceBeneStatistics){ - bw.write(s); - bw.newLine(); - } - bw.flush(); - bw.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - - /** - * @param produceStatistics - */ - private void writeStats(List produceStatistics, int iteration) { - BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStats.csv")); - try { - - String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn"; - bw.write(header); - bw.newLine(); - for (String s : produceStatistics){ - bw.write(s); - bw.newLine(); - } - bw.flush(); - bw.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - - } - - @Override - public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent event) { - ((FacilityBasedParkingManager) manager).checkFreeCapacitiesForWaitingVehicles((QSim) event.getQueueSimulation(), event.getSimulationTime()); - } - - @Override - public void notifyMobsimInitialized(final MobsimInitializedEvent e) { - QSim qSim = (QSim) e.getQueueSimulation(); - ((FacilityBasedParkingManager) manager).setQSim(qSim); - - } -} diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java index 9b3b8eff107..8c8491381c3 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java @@ -22,231 +22,232 @@ import com.google.inject.Inject; import org.apache.commons.lang3.mutable.MutableLong; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.dynagent.DynAgent; import org.matsim.contrib.parking.parkingsearch.ParkingUtils; import org.matsim.contrib.parking.parkingsearch.sim.ParkingSearchConfigGroup; +import org.matsim.core.controler.events.IterationEndsEvent; +import org.matsim.core.gbl.Gbl; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; import org.matsim.core.mobsim.qsim.QSim; import org.matsim.core.utils.misc.Time; import org.matsim.facilities.ActivityFacility; import org.matsim.facilities.ActivityOption; +import org.matsim.facilities.OpeningTime; import org.matsim.vehicles.Vehicle; import java.util.*; import java.util.Map.Entry; /** + * Manages vehicles parking actions at facilities or freely on the street. I.e. keeps track of the capacity of the facilities. This class has + * additional functionality: + * - It can handle parking reservations. + * - It triggers reporting of parking statistics. + * - It can handle vehicles waiting for a parking space. * + * * @author jbischoff, schlenther, Ricardo Ewert */ public class FacilityBasedParkingManager implements ParkingSearchManager { + private static final Logger logger = LogManager.getLogger(FacilityBasedParkingManager.class); + private static final int REPORTING_TIME_BIN_SIZE = 15 * 60; + + protected Map, ParkingFacilityInfo> infoByFacilityId = new HashMap<>(); + + protected Map, TreeMap>> waitingVehiclesByLinkId = new HashMap<>(); + protected Map, ActivityFacility> parkingFacilitiesById; + protected Map, Id> parkingFacilityLocationByVehicleId = new HashMap<>(); + protected Map, Id> parkingReservationByVehicleId = new HashMap<>(); + //stores the parking location of vehicles that are parked outside of facilities (e.g. at the side of a link. therefore, there are no capacity + // checks) + protected Map, Id> freeParkingLinkByVehicleId = new HashMap<>(); + protected Map, Set>> parkingFacilitiesByLink = new HashMap<>(); + protected ParkingSearchConfigGroup psConfigGroup; + private QSim qsim; - protected Map, Integer> capacity = new HashMap<>(); - protected Map, MutableLong> occupation = new HashMap<>(); - protected Map, MutableLong> reservationsRequests = new HashMap<>(); - protected Map, MutableLong> rejectedParkingRequest = new HashMap<>(); - protected Map, MutableLong> numberOfParkedVehicles = new HashMap<>(); - protected Map, MutableLong> numberOfWaitingActivities = new HashMap<>(); - protected Map, MutableLong> numberOfStaysFromGetOffUntilGetIn = new HashMap<>(); - protected Map, MutableLong> numberOfParkingBeforeGetIn = new HashMap<>(); - protected Map, TreeMap>> waitingVehicles = new HashMap<>(); + //The following maps are used for reporting + @Inject + private ParkingStatsWriter writer; protected TreeMap rejectedReservationsByTime = new TreeMap<>(); protected TreeMap foundParkingByTime = new TreeMap<>(); protected TreeMap unparkByTime = new TreeMap<>(); - protected Map, ActivityFacility> parkingFacilities; - protected Map, Id> parkingLocations = new HashMap<>(); - protected Map, Id> parkingReservation = new HashMap<>(); - protected Map, Id> parkingLocationsOutsideFacilities = new HashMap<>(); - protected Map, Set>> facilitiesPerLink = new HashMap<>(); - protected Network network; - protected ParkingSearchConfigGroup psConfigGroup; - protected boolean canParkOnlyAtFacilities; - private QSim qsim; - private final int maxSlotIndex; - private final int maxTime; - private final int timeBinSize; - private final int startTime; + private int reportingMaxSlotIndex; + private int reportingMaxTime; @Inject public FacilityBasedParkingManager(Scenario scenario) { - psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get( - ParkingSearchConfigGroup.GROUP_NAME); - canParkOnlyAtFacilities = psConfigGroup.getCanParkOnlyAtFacilities(); - this.network = scenario.getNetwork(); - parkingFacilities = scenario.getActivityFacilities() - .getFacilitiesForActivityType(ParkingUtils.ParkingStageInteractionType); - LogManager.getLogger(getClass()).info(parkingFacilities.toString()); - this.timeBinSize = 15 * 60; - this.maxTime = 24 * 3600 - 1; - this.maxSlotIndex = (this.maxTime / this.timeBinSize) + 1; - this.startTime = 9 * 3600; - - for (ActivityFacility fac : this.parkingFacilities.values()) { - Id linkId = fac.getLinkId(); - Set> parkingOnLink = new HashSet<>(); - if (this.facilitiesPerLink.containsKey(linkId)) { - parkingOnLink = this.facilitiesPerLink.get(linkId); - } - parkingOnLink.add(fac.getId()); - this.facilitiesPerLink.put(linkId, parkingOnLink); - this.waitingVehicles.computeIfAbsent(linkId, (k) -> new TreeMap<>()); - this.occupation.put(fac.getId(), new MutableLong(0)); - this.reservationsRequests.put(fac.getId(), new MutableLong(0)); - this.rejectedParkingRequest.put(fac.getId(), new MutableLong(0)); - this.numberOfParkedVehicles.put(fac.getId(), new MutableLong(0)); - this.numberOfWaitingActivities.put(fac.getId(), new MutableLong(0)); - this.numberOfStaysFromGetOffUntilGetIn.put(fac.getId(), new MutableLong(0)); - this.numberOfParkingBeforeGetIn.put(fac.getId(), new MutableLong(0)); - } - int slotIndex = getTimeSlotIndex(startTime); - while (slotIndex <= maxSlotIndex) { - rejectedReservationsByTime.put(slotIndex * timeBinSize, new MutableLong(0)); - foundParkingByTime.put(slotIndex * timeBinSize, new MutableLong(0)); - unparkByTime.put(slotIndex * timeBinSize, new MutableLong(0)); - slotIndex++; + psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get(ParkingSearchConfigGroup.GROUP_NAME); + parkingFacilitiesById = scenario.getActivityFacilities().getFacilitiesForActivityType(ParkingUtils.ParkingStageInteractionType); + + logger.info(parkingFacilitiesById.toString()); + + for (ActivityFacility fac : this.parkingFacilitiesById.values()) { + initParkingFacility(fac); } + + initReporting(scenario); } - @Override - public boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id linkId) { - boolean canPark = false; + private void initReporting(Scenario scenario) { + this.reportingMaxTime = (int) scenario.getConfig().qsim().getEndTime().seconds(); + this.reportingMaxSlotIndex = (this.reportingMaxTime / REPORTING_TIME_BIN_SIZE) + 1; + } - if (linkIdHasAvailableParkingForVehicle(linkId, vehicleId)) { - canPark = true; - // LogManager.getLogger(getClass()).info("veh: "+vehicleId+" link - // "+linkId + " can park "+canPark); - } + private void initParkingFacility(ActivityFacility fac) { + Id linkId = fac.getLinkId(); + Set> parkingOnLink = parkingFacilitiesByLink.getOrDefault(linkId, new HashSet<>()); + parkingOnLink.add(fac.getId()); + this.parkingFacilitiesByLink.put(linkId, parkingOnLink); + this.waitingVehiclesByLinkId.put(linkId, new TreeMap<>()); - return canPark; + ActivityOption activityOption = fac.getActivityOptions().get(ParkingUtils.ParkingStageInteractionType); + this.infoByFacilityId.put(fac.getId(), new ParkingFacilityInfo(activityOption)); + } + + @Override + public boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id linkId) { + return linkIdHasAvailableParkingForVehicle(linkId, vehicleId); } /** * Checks if it is possible if you can park at this link for the complete time. - * - * @param linkId - * @param stopDuration - * @param getOffDuration - * @param pickUpDuration - * @param now - * @return */ - public boolean canParkAtThisFacilityUntilEnd(Id linkId, double stopDuration, double getOffDuration, double pickUpDuration, double now) { - Set> facilities = this.facilitiesPerLink.get(linkId); - if (facilities != null) { - double totalNeededParkingDuration = getOffDuration + stopDuration + pickUpDuration; - for (Id facility : facilities) { - double maxParkingDurationAtFacilityInHours = Double.MAX_VALUE; - if (this.parkingFacilities.get(facility).getAttributes().getAsMap().containsKey("maxParkingDurationInHours")) - maxParkingDurationAtFacilityInHours = 3600 * (double) this.parkingFacilities.get(facility).getAttributes().getAsMap().get( - "maxParkingDurationInHours"); - if (maxParkingDurationAtFacilityInHours > totalNeededParkingDuration) { - ActivityOption parkingOptions = this.parkingFacilities.get(facility).getActivityOptions().get("parking"); - if (!parkingOptions.getOpeningTimes().isEmpty()) { - if ((parkingOptions.getOpeningTimes().first().getStartTime() == 0 && parkingOptions.getOpeningTimes().first().getEndTime() == 24 * 3600)) - if (parkingOptions.getOpeningTimes().first().getStartTime() <= now && parkingOptions.getOpeningTimes().first().getEndTime() >= now + totalNeededParkingDuration) - return true; - } else - return true; + public boolean canParkAtThisFacilityUntilEnd(Id linkId, double now, double getOffDuration, double stopDuration, double pickUpDuration) { + Set> facilities = this.parkingFacilitiesByLink.get(linkId); + if (facilities == null) { + //TODO really? if there is no facility we assume free parking with no time constraint. + return false; + } + double totalDuration = getOffDuration + stopDuration + pickUpDuration; + for (Id facility : facilities) { + double maxParkingDurationAtFacilityInSeconds = + Optional.ofNullable(this.parkingFacilitiesById.get(facility).getAttributes().getAsMap().get("maxParkingDurationInHours")) + .map(attribute -> 3600 * (double) attribute).orElse(Double.MAX_VALUE); + + if (maxParkingDurationAtFacilityInSeconds < totalDuration) { + //Parking duration is limited, so we can't park here. + return false; + } + + ActivityOption parkingOptions = this.infoByFacilityId.get(facility).activityOption; + if (parkingOptions.getOpeningTimes().isEmpty()) { + //No opening times defined, so we can park here. + return true; + } + + OpeningTime firstOpeningTimes = parkingOptions.getOpeningTimes().first(); + //TODO do we really want this constraint? if parking facility has other opening times than 0-24, we can't park here. + if ((firstOpeningTimes.getStartTime() == 0 && firstOpeningTimes.getEndTime() == 24 * 3600)) { + if (firstOpeningTimes.getStartTime() <= now && firstOpeningTimes.getEndTime() >= now + totalDuration) { + //Parking facility is open for the complete duration, so we can park here. + return true; } } + } + //No parking facility is open for the complete duration, so we can't park here. return false; } + /** + * Either parks the vehicle at a link freely (no capacity constraint) or at a facility (capacity constraint). + */ private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id vid) { - // LogManager.getLogger(getClass()).info("link "+linkId+" vehicle "+vid); - if (!this.facilitiesPerLink.containsKey(linkId) && !canParkOnlyAtFacilities) { - // this implies: If no parking facility is present, we suppose that - // we can park freely (i.e. the matsim standard approach) - // it also means: a link without any parking spaces should have a - // parking facility with 0 capacity. - // LogManager.getLogger(getClass()).info("link not listed as parking - // space, we will say yes "+linkId); - - return true; - } else if (!this.facilitiesPerLink.containsKey(linkId)) { - return false; + if (!this.parkingFacilitiesByLink.containsKey(linkId)) { + // No parking facility at this link. Either parking is allowed only at facilities or not. + // If not, we can park freely, so link has available parking. (MATSim standard approach) + // If yes, we can't park here. + return !psConfigGroup.getCanParkOnlyAtFacilities(); } - Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId); + Set> parkingFacilitiesAtLink = this.parkingFacilitiesByLink.get(linkId); for (Id fac : parkingFacilitiesAtLink) { - double cap = this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType) - .getCapacity(); - this.reservationsRequests.get(fac).increment(); - if (this.occupation.get(fac).doubleValue() < cap) { - // LogManager.getLogger(getClass()).info("occ: - // "+this.occupation.get(fac).toString()+" cap: "+cap); - this.occupation.get(fac).increment(); - this.parkingReservation.put(vid, fac); - + if (this.infoByFacilityId.get(fac).park()) { + this.parkingReservationByVehicleId.put(vid, fac); return true; } - this.rejectedParkingRequest.get(fac).increment(); } return false; } @Override public Id getVehicleParkingLocation(Id vehicleId) { - if (this.parkingLocations.containsKey(vehicleId)) { - return this.parkingFacilities.get(this.parkingLocations.get(vehicleId)).getLinkId(); - } else return this.parkingLocationsOutsideFacilities.getOrDefault(vehicleId, null); + if (this.parkingFacilityLocationByVehicleId.containsKey(vehicleId)) { + //parked at facility + return this.parkingFacilitiesById.get(this.parkingFacilityLocationByVehicleId.get(vehicleId)).getLinkId(); + } else { + //parked freely + return this.freeParkingLinkByVehicleId.getOrDefault(vehicleId, null); + } } + /** + * Parks a vehicle at a link. Either freely outside a facility or at a facility. + */ @Override public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) { return parkVehicleAtLink(vehicleId, linkId, time); } protected boolean parkVehicleAtLink(Id vehicleId, Id linkId, double time) { - Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId); + Set> parkingFacilitiesAtLink = this.parkingFacilitiesByLink.get(linkId); if (parkingFacilitiesAtLink == null) { - this.parkingLocationsOutsideFacilities.put(vehicleId, linkId); + //park freely + this.freeParkingLinkByVehicleId.put(vehicleId, linkId); return true; - } else { - Id fac = this.parkingReservation.remove(vehicleId); - if (fac != null) { - this.parkingLocations.put(vehicleId, fac); - this.numberOfParkedVehicles.get(fac).increment(); - foundParkingByTime.get(getTimeSlotIndex(time) * timeBinSize).increment(); - return true; - } else { - throw new RuntimeException("no parking reservation found for vehicle " + vehicleId.toString() - + " arrival on link " + linkId + " with parking restriction"); - } } + //park at facility + return parkVehicleInReservedFacility(vehicleId, linkId, time); + } + + private boolean parkVehicleInReservedFacility(Id vehicleId, Id linkId, double time) { + Id fac = this.parkingReservationByVehicleId.remove(vehicleId); + if (fac == null) { + throw new RuntimeException("no parking reservation found for vehicle " + vehicleId.toString() + + " arrival on link " + linkId + " with parking restriction"); + } + + Gbl.assertIf(parkingFacilitiesById.get(fac).getLinkId().equals(linkId)); + + this.parkingFacilityLocationByVehicleId.put(vehicleId, fac); + reportParking(time, fac); + return true; } + /** + * Unparks vehicle from a link. Either freely outside a facility or at a facility. + */ @Override public boolean unParkVehicleHere(Id vehicleId, Id linkId, double time) { - if (!this.parkingLocations.containsKey(vehicleId)) { - this.parkingLocationsOutsideFacilities.remove(vehicleId); - return true; - - // we assume the person parks somewhere else + if (!this.parkingFacilityLocationByVehicleId.containsKey(vehicleId)) { + //unpark freely + this.freeParkingLinkByVehicleId.remove(vehicleId); } else { - Id fac = this.parkingLocations.remove(vehicleId); - this.occupation.get(fac).decrement(); - unparkByTime.get(getTimeSlotIndex(time) * timeBinSize).increment(); - return true; + //unpark at facility + Id fac = this.parkingFacilityLocationByVehicleId.remove(vehicleId); + reportUnParking(time, fac); } + return true; } - @Override - public List produceStatistics() { + private List produceStatistics() { List stats = new ArrayList<>(); - for (Entry, MutableLong> e : this.occupation.entrySet()) { - Id linkId = this.parkingFacilities.get(e.getKey()).getLinkId(); - double capacity = this.parkingFacilities.get(e.getKey()).getActivityOptions() - .get(ParkingUtils.ParkingStageInteractionType).getCapacity(); - double x = this.parkingFacilities.get(e.getKey()).getCoord().getX(); - double y = this.parkingFacilities.get(e.getKey()).getCoord().getY(); - - String s = linkId.toString() + ";" + x + ";" + y + ";" + e.getKey().toString() + ";" + capacity + ";" + e.getValue().toString() + ";" + this.reservationsRequests.get( - e.getKey()).toString() + ";" + this.numberOfParkedVehicles.get(e.getKey()).toString() + ";" + this.rejectedParkingRequest.get( - e.getKey()).toString() + ";" + this.numberOfWaitingActivities.get( - e.getKey()).toString() + ";" + this.numberOfStaysFromGetOffUntilGetIn.get(e.getKey()).intValue() + ";" + this.numberOfParkingBeforeGetIn.get(e.getKey()).intValue(); + for (Entry, ParkingFacilityInfo> e : this.infoByFacilityId.entrySet()) { + Id linkId = this.parkingFacilitiesById.get(e.getKey()).getLinkId(); + double capacity = this.parkingFacilitiesById.get(e.getKey()).getActivityOptions() + .get(ParkingUtils.ParkingStageInteractionType).getCapacity(); + double x = this.parkingFacilitiesById.get(e.getKey()).getCoord().getX(); + double y = this.parkingFacilitiesById.get(e.getKey()).getCoord().getY(); + + String facilityId = e.getKey().toString(); + ParkingFacilityInfo info = e.getValue(); + String s = + linkId.toString() + ";" + x + ";" + y + ";" + facilityId + ";" + capacity + ";" + info.occupation + ";" + info.reservationRequests + + ";" + info.parkedVehiclesCount + ";" + info.rejectedParkingRequests + ";" + info.waitingActivitiesCount + ";" + + info.staysFromGetOffUntilGetIn + ";" + info.parkingBeforeGetInCount; stats.add(s); } return stats; @@ -266,10 +267,10 @@ public List produceTimestepsStatistics() { public double getNrOfAllParkingSpacesOnLink(Id linkId) { double allSpaces = 0; - Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId); + Set> parkingFacilitiesAtLink = this.parkingFacilitiesByLink.get(linkId); if (!(parkingFacilitiesAtLink == null)) { for (Id fac : parkingFacilitiesAtLink) { - allSpaces += this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity(); + allSpaces += this.parkingFacilitiesById.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity(); } } return allSpaces; @@ -277,97 +278,89 @@ public double getNrOfAllParkingSpacesOnLink(Id linkId) { public double getNrOfFreeParkingSpacesOnLink(Id linkId) { double allFreeSpaces = 0; - Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId); + Set> parkingFacilitiesAtLink = this.parkingFacilitiesByLink.get(linkId); if (parkingFacilitiesAtLink == null) { return 0; } else { for (Id fac : parkingFacilitiesAtLink) { - int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity(); - allFreeSpaces += (cap - this.occupation.get(fac).intValue()); + int cap = (int) this.parkingFacilitiesById.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity(); + allFreeSpaces += (cap - this.infoByFacilityId.get(fac).occupation); } } return allFreeSpaces; } - public Map, ActivityFacility> getParkingFacilities() { - return this.parkingFacilities; + public Map, ActivityFacility> getParkingFacilitiesById() { + return this.parkingFacilitiesById; } public void registerRejectedReservation(double now) { - rejectedReservationsByTime.get(getTimeSlotIndex(now) * timeBinSize).increment(); - } - - public TreeSet getTimeSteps() { - TreeSet timeSteps = new TreeSet<>(); - int slotIndex = 0; - while (slotIndex <= maxSlotIndex) { - timeSteps.add(slotIndex * timeBinSize); - slotIndex++; - } - return timeSteps; + rejectedReservationsByTime.putIfAbsent(getTimeSlotIndex(now) * REPORTING_TIME_BIN_SIZE, new MutableLong(0)); + rejectedReservationsByTime.get(getTimeSlotIndex(now) * REPORTING_TIME_BIN_SIZE).increment(); } private int getTimeSlotIndex(final double time) { - if (time > this.maxTime) { - return this.maxSlotIndex; + if (time > this.reportingMaxTime) { + return this.reportingMaxSlotIndex; } - return ((int) time / this.timeBinSize); + return ((int) time / REPORTING_TIME_BIN_SIZE); } /** - * Gives the duration of the staging activity of parking - * - * @return + * Returns the duration of the staging activity of parking */ public double getParkStageActivityDuration() { return psConfigGroup.getParkduration(); } - /** - * Gives the duration of the staging activity of unparking - * - * @return - */ - public double getUnParkStageActivityDuration() { - return psConfigGroup.getUnparkduration(); - } - @Override public void reset(int iteration) { - for (Id fac : this.rejectedParkingRequest.keySet()) { - this.rejectedParkingRequest.get(fac).setValue(0); - this.reservationsRequests.get(fac).setValue(0); - this.numberOfParkedVehicles.get(fac).setValue(0); - this.numberOfWaitingActivities.get(fac).setValue(0); - } - waitingVehicles.clear(); + infoByFacilityId.replaceAll((k, v) -> new ParkingFacilityInfo(v.activityOption)); + waitingVehiclesByLinkId.clear(); } public void addVehicleForWaitingForParking(Id linkId, Id vehicleId, double now) { // System.out.println(now + ": vehicle " +vehicleId.toString() + " starts waiting here: " + linkId.toString()); - waitingVehicles.get(linkId).put(now + getParkStageActivityDuration() + 1, vehicleId); - for (Id fac : this.facilitiesPerLink.get(linkId)) { - this.numberOfWaitingActivities.get(fac).increment(); + waitingVehiclesByLinkId.get(linkId).put(now + getParkStageActivityDuration() + 1, vehicleId); + for (Id fac : this.parkingFacilitiesByLink.get(linkId)) { + this.infoByFacilityId.get(fac).waitingActivitiesCount++; break; } } + //@formatter:off + /** + * For all links l with waiting vehicles: + * For all facilities f located at l: + * While there is a free capacity at f and there are waiting vehicles: + * Remove the first waiting vehicle from the list of waiting vehicles. + * Reserve a parking space for this vehicle. + * End the activity of the vehicle. + * Reschedule the activity end of the vehicle. + * + */ + //@formatter:on public void checkFreeCapacitiesForWaitingVehicles(QSim qSim, double now) { - for (Id linkId : waitingVehicles.keySet()) { - if (!waitingVehicles.get(linkId).isEmpty()) { - for (Id fac : this.facilitiesPerLink.get(linkId)) { - int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity(); - while (this.occupation.get(fac).intValue() < cap && !waitingVehicles.get(linkId).isEmpty()) { - double startWaitingTime = waitingVehicles.get(linkId).firstKey(); - if (startWaitingTime > now) - break; - Id vehcileId = waitingVehicles.get(linkId).remove(startWaitingTime); - DynAgent agent = (DynAgent) qSim.getAgents().get(Id.createPersonId(vehcileId.toString())); - reserveSpaceIfVehicleCanParkHere(vehcileId, linkId); - agent.endActivityAndComputeNextState(now); - qsim.rescheduleActivityEnd(agent); + for (Id linkId : waitingVehiclesByLinkId.keySet()) { + TreeMap> vehicleIdByTime = waitingVehiclesByLinkId.get(linkId); + if (vehicleIdByTime.isEmpty()) { + break; + } + for (Id fac : this.parkingFacilitiesByLink.get(linkId)) { + int capacity = (int) this.parkingFacilitiesById.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType) + .getCapacity(); + + while (this.infoByFacilityId.get(fac).occupation < capacity && !vehicleIdByTime.isEmpty()) { + double startWaitingTime = vehicleIdByTime.firstKey(); + if (startWaitingTime > now) { + break; } + Id vehcileId = vehicleIdByTime.remove(startWaitingTime); + DynAgent agent = (DynAgent) qSim.getAgents().get(Id.createPersonId(vehcileId.toString())); + reserveSpaceIfVehicleCanParkHere(vehcileId, linkId); + agent.endActivityAndComputeNextState(now); + qsim.rescheduleActivityEnd(agent); } } } @@ -378,10 +371,69 @@ public void setQSim(QSim qSim) { } public void registerStayFromGetOffUntilGetIn(Id vehcileId) { - this.numberOfStaysFromGetOffUntilGetIn.get(parkingLocations.get(vehcileId)).increment(); + infoByFacilityId.get(parkingFacilityLocationByVehicleId.get(vehcileId)).staysFromGetOffUntilGetIn++; } public void registerParkingBeforeGetIn(Id vehcileId) { - this.numberOfParkingBeforeGetIn.get(parkingLocations.get(vehcileId)).increment(); + this.infoByFacilityId.get(parkingFacilityLocationByVehicleId.get(vehcileId)).parkingBeforeGetInCount++; + } + + private void reportParking(double time, Id fac) { + this.infoByFacilityId.get(fac).parkedVehiclesCount++; + int timeSlot = getTimeSlotIndex(time) * REPORTING_TIME_BIN_SIZE; + foundParkingByTime.putIfAbsent(timeSlot, new MutableLong(0)); + foundParkingByTime.get(timeSlot).increment(); + } + + private void reportUnParking(double time, Id fac) { + this.infoByFacilityId.get(fac).occupation--; + int timeSlot = getTimeSlotIndex(time) * REPORTING_TIME_BIN_SIZE; + unparkByTime.putIfAbsent(timeSlot, new MutableLong(0)); + unparkByTime.get(timeSlot).increment(); + } + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + writer.writeStatsByFacility(produceStatistics(), event.getIteration()); + writer.writeStatsByTimesteps(produceTimestepsStatistics(), event.getIteration()); + reset(event.getIteration()); + } + + + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent event) { + checkFreeCapacitiesForWaitingVehicles((QSim) event.getQueueSimulation(), event.getSimulationTime()); + } + + @Override + public void notifyMobsimInitialized(final MobsimInitializedEvent e) { + QSim qSim = (QSim) e.getQueueSimulation(); + setQSim(qSim); + } + + protected static class ParkingFacilityInfo { + protected long occupation = 0; + protected final ActivityOption activityOption; + protected long reservationRequests = 0; + protected long rejectedParkingRequests = 0; + protected long parkedVehiclesCount = 0; + protected long waitingActivitiesCount = 0; + protected long staysFromGetOffUntilGetIn = 0; + protected long parkingBeforeGetInCount = 0; + + ParkingFacilityInfo(ActivityOption activityOption) { + this.activityOption = activityOption; + } + + protected boolean park() { + reservationRequests++; + //TODO check double vs long + if (occupation >= activityOption.getCapacity()) { + rejectedParkingRequests++; + return false; + } + occupation++; + return true; + } } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/LinkLengthBasedParkingManagerWithRandomInitialUtilisation.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/LinkLengthBasedParkingManagerWithRandomInitialUtilisation.java index 5600260ec7a..56f75d97d14 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/LinkLengthBasedParkingManagerWithRandomInitialUtilisation.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/LinkLengthBasedParkingManagerWithRandomInitialUtilisation.java @@ -19,42 +19,43 @@ package org.matsim.contrib.parking.parkingsearch.manager; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - import jakarta.inject.Inject; - import org.apache.commons.lang3.mutable.MutableLong; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.core.config.Config; +import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.gbl.MatsimRandom; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; import org.matsim.vehicles.Vehicle; +import java.util.*; + /** - * @author jbischoff - * + * @author jbischoff */ public class LinkLengthBasedParkingManagerWithRandomInitialUtilisation implements ParkingSearchManager { - Map,Integer> capacity = new HashMap<>(); - Map,MutableLong> occupation = new HashMap<>(); - Map,Id> parkingPosition = new HashMap<>(); + Map, Integer> capacity = new HashMap<>(); + Map, MutableLong> occupation = new HashMap<>(); + Map, Id> parkingPosition = new HashMap<>(); Random rand = MatsimRandom.getLocalInstance(); int parkedVehicles = 0; int unparkedVehicles = 0; + + @Inject + private ParkingStatsWriter writer; + @Inject public LinkLengthBasedParkingManagerWithRandomInitialUtilisation(Network network, Config config) { - double assumedParkedVehicleLength = 4.0; - double shareOfLinkLengthUsedForParking = 0.7; + double assumedParkedVehicleLength = 4.0; + double shareOfLinkLengthUsedForParking = 0.7; - //TODO: Make this configurable - for (Link link : network.getLinks().values()){ - int maxCapacity = (int) (link.getLength()*shareOfLinkLengthUsedForParking / assumedParkedVehicleLength); + //TODO: Make this configurable + for (Link link : network.getLinks().values()) { + int maxCapacity = (int) (link.getLength() * shareOfLinkLengthUsedForParking / assumedParkedVehicleLength); this.capacity.put(link.getId(), maxCapacity); this.occupation.put(link.getId(), new MutableLong(rand.nextInt(maxCapacity))); @@ -63,7 +64,7 @@ public LinkLengthBasedParkingManagerWithRandomInitialUtilisation(Network network @Override public boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id linkId) { - return (this.occupation.get(linkId).intValue() getVehicleParkingLocation(Id vehicleId) { @Override public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) { - if (this.occupation.get(linkId).intValue() vehicleId, Id linkId, double time) { - if (!linkId.equals(this.parkingPosition.get(vehicleId))) return false; - else { + if (!linkId.equals(this.parkingPosition.get(vehicleId))) { + return false; + } else { this.parkingPosition.remove(vehicleId); this.occupation.get(linkId).decrement(); unparkedVehicles++; @@ -95,11 +99,10 @@ public boolean unParkVehicleHere(Id vehicleId, Id linkId, double } - @Override public List produceStatistics() { List stats = new ArrayList<>(); - stats.add("parking occurences: "+ parkedVehicles); - stats.add("unparking occurences: "+ unparkedVehicles); + stats.add("parking occurences: " + parkedVehicles); + stats.add("unparking occurences: " + unparkedVehicles); return stats; } @@ -107,6 +110,18 @@ public List produceStatistics() { public void reset(int iteration) { } + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + writer.writePlainStats(produceStatistics(), event.getIteration()); + } + + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + } + + @Override + public void notifyMobsimInitialized(MobsimInitializedEvent e) { + } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingSearchManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingSearchManager.java index 7bdd6fb37c2..3cb029157f8 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingSearchManager.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingSearchManager.java @@ -19,25 +19,27 @@ package org.matsim.contrib.parking.parkingsearch.manager; -import java.util.List; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.core.controler.listener.IterationEndsListener; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; import org.matsim.vehicles.Vehicle; /** - * @author jbischoff - * + * @author jbischoff */ -public interface ParkingSearchManager { +public interface ParkingSearchManager extends IterationEndsListener, MobsimBeforeSimStepListener, MobsimInitializedListener { boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id linkId); + Id getVehicleParkingLocation(Id vehicleId); + boolean parkVehicleHere(Id vehicleId, Id linkId, double time); + boolean unParkVehicleHere(Id vehicleId, Id linkId, double time); - - List produceStatistics(); + void reset(int iteration); - - + + } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingStatsWriter.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingStatsWriter.java new file mode 100644 index 00000000000..9b929dc53c3 --- /dev/null +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ParkingStatsWriter.java @@ -0,0 +1,74 @@ +package org.matsim.contrib.parking.parkingsearch.manager; + +import com.google.inject.Inject; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.utils.io.IOUtils; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.List; + +//the functionality of this class is mainly copied from old ParkingListener and could be improved +public class ParkingStatsWriter { + @Inject + OutputDirectoryHierarchy output; + + public void writeStatsByTimesteps(List produceBeneStatistics, int iteration) { + BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStatsPerTimeSteps.csv")); + try { + + String header = "time;rejectedParkingRequest;foundParking;unpark"; + bw.write(header); + bw.newLine(); + for (String s : produceBeneStatistics) { + bw.write(s); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + /** + * @param produceStatistics + */ + public void writeStatsByFacility(List produceStatistics, int iteration) { + BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStats.csv")); + try { + + String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;" + + "numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn"; + bw.write(header); + bw.newLine(); + for (String s : produceStatistics) { + bw.write(s); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void writePlainStats(List produceStatistics, int iteration) { + BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStats.txt")); + try { + for (String s : produceStatistics) { + bw.write(s); + bw.newLine(); + } + bw.flush(); + bw.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java index b9fbebe4699..5dc503ac08a 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java @@ -19,13 +19,16 @@ import java.util.Set; /** + * Extends the facility based manager, thus parks vehicles at facilities but also keeps track of the occupancy of zones. A zone is defined by a set + * of links. + * * @author tschlenther */ public class ZoneParkingManager extends FacilityBasedParkingManager { - private HashMap>> linksOfZone; - private HashMap totalCapOfZone; - private HashMap occupationOfZone; + private final HashMap>> linksByZone; + private final HashMap totalCapByZone; + private final HashMap occupationByZone; /** * @param scenario @@ -34,17 +37,17 @@ public class ZoneParkingManager extends FacilityBasedParkingManager { public ZoneParkingManager(Scenario scenario, String[] pathToZoneTxtFiles) { super(scenario); - this.linksOfZone = new HashMap>>(); - this.totalCapOfZone = new HashMap(); - this.occupationOfZone = new HashMap(); + this.linksByZone = new HashMap>>(); + this.totalCapByZone = new HashMap(); + this.occupationByZone = new HashMap(); for (String zone : pathToZoneTxtFiles) { readZone(zone); } - for (String zone : this.linksOfZone.keySet()) { + for (String zone : this.linksByZone.keySet()) { calculateTotalZoneParkCapacity(zone); - this.occupationOfZone.put(zone, 0.0); + this.occupationByZone.put(zone, 0.0); } } @@ -52,6 +55,7 @@ public ZoneParkingManager(Scenario scenario, String[] pathToZoneTxtFiles) { /** * reads in a tabular file that declares which link id's are in the monitored zone * the part between the last '/' and the file type extension in the given path is considered to be the zone name + * * @param pathToZoneFile */ void readZone(String pathToZoneFile) { @@ -72,61 +76,64 @@ public void startRow(String[] row) { }); - this.linksOfZone.put(zone, links); + this.linksByZone.put(zone, links); } private void calculateTotalZoneParkCapacity(String zoneName) { double cap = 0.0; - for (Id link : this.linksOfZone.get(zoneName)) { + for (Id link : this.linksByZone.get(zoneName)) { cap += getNrOfAllParkingSpacesOnLink(link); } - this.totalCapOfZone.put(zoneName, cap); + this.totalCapByZone.put(zoneName, cap); } @Override public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) { if (parkVehicleAtLink(vehicleId, linkId, time)) { - for (String zone : this.linksOfZone.keySet()) { - if (linksOfZone.get(zone).contains(linkId) && this.facilitiesPerLink.containsKey(linkId)) { - double newOcc = this.occupationOfZone.get(zone) + 1; - if (this.totalCapOfZone.get(zone) < newOcc) { - String s = "FacilityID: " + this.parkingLocations.get(vehicleId); - String t = "Occupied: " + this.occupation.get(this.parkingLocations.get(vehicleId)); - String u = "Capacity: " + this.parkingFacilities.get(this.parkingLocations.get(vehicleId)).getActivityOptions().get( - ParkingUtils.ParkingStageInteractionType).getCapacity(); + for (String zone : this.linksByZone.keySet()) { + if (linksByZone.get(zone).contains(linkId) && this.parkingFacilitiesByLink.containsKey(linkId)) { + double newOcc = this.occupationByZone.get(zone) + 1; + if (this.totalCapByZone.get(zone) < newOcc) { + String s = "FacilityID: " + this.parkingFacilityLocationByVehicleId.get(vehicleId); + String t = "Occupied: " + this.infoByFacilityId.get(this.parkingFacilityLocationByVehicleId.get(vehicleId)).occupation; + String u = + "Capacity: " + this.parkingFacilitiesById.get(this.parkingFacilityLocationByVehicleId.get(vehicleId)).getActivityOptions() + .get( + ParkingUtils.ParkingStageInteractionType).getCapacity(); String v = "TotalCapacityOnLink: " + getNrOfAllParkingSpacesOnLink(linkId); - throw new RuntimeException("occupancy of zone " + zone + " is higher than 100%. Capacity= " + this.totalCapOfZone.get( + throw new RuntimeException("occupancy of zone " + zone + " is higher than 100%. Capacity= " + this.totalCapByZone.get( zone) + " occupancy=" + newOcc + "time = " + time + "\n" + s + "\n" + t + "\n" + u + "\n" + v); } - this.occupationOfZone.put(zone, newOcc); + this.occupationByZone.put(zone, newOcc); return true; // assumes: link is only part of exactly 1 zone } } return true; - } else + } else { return false; + } } @Override public boolean unParkVehicleHere(Id vehicleId, Id linkId, double time) { - if (!this.parkingLocations.containsKey(vehicleId)) { + if (!this.parkingFacilityLocationByVehicleId.containsKey(vehicleId)) { return true; // we assume the person parks somewhere else } else { - Id fac = this.parkingLocations.remove(vehicleId); - this.occupation.get(fac).decrement(); + Id fac = this.parkingFacilityLocationByVehicleId.remove(vehicleId); + this.infoByFacilityId.get(fac).occupation--; - Id parkingLink = this.parkingFacilities.get(fac).getLinkId(); - for (String zone : this.linksOfZone.keySet()) { - if (linksOfZone.get(zone).contains(parkingLink)) { - double newOcc = this.occupationOfZone.get(zone) - 1; + Id parkingLink = this.parkingFacilitiesById.get(fac).getLinkId(); + for (String zone : this.linksByZone.keySet()) { + if (linksByZone.get(zone).contains(parkingLink)) { + double newOcc = this.occupationByZone.get(zone) - 1; if (newOcc < 0) { //in iteration 0 agents can "leave parking spaces" (get into traffic), but the manager didn't record them to be parked newOcc = 0; } - this.occupationOfZone.put(zone, newOcc); + this.occupationByZone.put(zone, newOcc); } } return true; @@ -135,18 +142,19 @@ public boolean unParkVehicleHere(Id vehicleId, Id linkId, double public double getOccupancyRatioOfZone(String zone) { - if (!(this.linksOfZone.keySet().contains(zone))) + if (!(this.linksByZone.keySet().contains(zone))) { throw new RuntimeException("zone " + zone + " was not defined. thus, could'nt calculate occupancy ratio."); + } - return (this.occupationOfZone.get(zone) / this.totalCapOfZone.get(zone)); + return (this.occupationByZone.get(zone) / this.totalCapByZone.get(zone)); } public Set getZones() { - return this.linksOfZone.keySet(); + return this.linksByZone.keySet(); } public double getTotalCapacityOfZone(String zone) { - return this.totalCapOfZone.get(zone); + return this.totalCapByZone.get(zone); } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/BenensonParkingSearchLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/BenensonParkingSearchLogic.java index 6b8d1f7bcff..adb5ee1dbb8 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/BenensonParkingSearchLogic.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/BenensonParkingSearchLogic.java @@ -19,58 +19,57 @@ /** * @author schlenther - * - *the matsim version of the parking strategy used in PARKAGENT. see the following paper for more information: - *doi: 10.1016/j.compenvurbsys.2008.09.011 - * + *

+ * the matsim version of the parking strategy used in PARKAGENT. see the following paper for more information: + * doi: 10.1016/j.compenvurbsys.2008.09.011 */ public class BenensonParkingSearchLogic implements ParkingSearchLogic { private static final Logger logger = LogManager.getLogger(BenensonDynLeg.class); private static final boolean logForDebug = false; - + private Network network; private static final double MIN_THRESHOLD_PROB_FUNCTION = 2; private static final double MAX_THRESHOLD_PROB_FUNCTION = 4; - //thresholds for phase transitions: 1->2 and 2->3 + //thresholds for phase transitions: 1->2 and 2->3 private static final double THRESHOLD_OBSERVING_METER = 1000; private static final double THRESHOLD_PARKING_METER = 500; - + private static final double ACCEPTED_DISTANCE_START = 100; private static final double ACCEPTED_DISTANCE_INCREASING_RATE_PER_MIN = 100; private static final double ACCEPTED_DISTANCE_MAX = 600; - + private final Random random = MatsimRandom.getLocalInstance(); - + private ParkingSearchConfigGroup configGroup; - + public BenensonParkingSearchLogic(Network network, ParkingSearchConfigGroup cfgGroup) { this.network = network; this.configGroup = cfgGroup; } - + @Override public void reset() { } - //----------------------------------------------------phase transitions---------------------------------------------------------------------------- + //----------------------------------------------------phase + // transitions---------------------------------------------------------------------------- - public boolean transitionToObservingBehaviour(Id currLinkId, Id endLinkId) { + public boolean transitionToObservingBehaviour(Id currLinkId, Id endLinkId) { double distToDest = NetworkUtils.getEuclideanDistance( - network.getLinks().get(currLinkId).getCoord(), network.getLinks().get(endLinkId).getCoord()); - return distToDest < THRESHOLD_OBSERVING_METER ; + network.getLinks().get(currLinkId).getCoord(), network.getLinks().get(endLinkId).getCoord()); + return distToDest < THRESHOLD_OBSERVING_METER; } - public boolean transitionToParkingBehaviour(Id currLinkId, Id endLinkId) { + public boolean transitionToParkingBehaviour(Id currLinkId, Id endLinkId) { double distToDest = NetworkUtils.getEuclideanDistance( - network.getLinks().get(currLinkId).getCoord(), network.getLinks().get(endLinkId).getCoord()); - return distToDest < THRESHOLD_PARKING_METER ; + network.getLinks().get(currLinkId).getCoord(), network.getLinks().get(endLinkId).getCoord()); + return distToDest < THRESHOLD_PARKING_METER; } - + //-------------------------------------------------------routing--------------------------------------------------------------------------- - + /** - * * @param currentLinkId * @param destinationLinkId * @return @@ -78,9 +77,9 @@ public boolean transitionToParkingBehaviour(Id currLinkId, Id endLin public Id getNextLinkBenensonRouting(Id currentLinkId, Id destinationLinkId, String mode) { Link currentLink = network.getLinks().get(currentLinkId); - //calculate the distance to fromNode of destination link instead of distance to activity + //calculate the distance to fromNode of destination link instead of distance to activity Node destination = network.getLinks().get(destinationLinkId).getFromNode(); - + double distanceToDest = Double.MAX_VALUE; Node nextNode; Id nextLinkId = null; @@ -91,13 +90,12 @@ public Id getNextLinkBenensonRouting(Id currentLinkId, Id dest return outLinkId; } nextNode = outLink.getToNode(); - double dd = NetworkUtils.getEuclideanDistance(destination.getCoord(),nextNode.getCoord()); - if( dd < distanceToDest){ + double dd = NetworkUtils.getEuclideanDistance(destination.getCoord(), nextNode.getCoord()); + if (dd < distanceToDest) { nextLinkId = outLinkId; distanceToDest = dd; - } - else if(dd == distanceToDest){ - if (Math.random() > 0.5){ + } else if (dd == distanceToDest) { + if (random.nextBoolean()) { nextLinkId = outLinkId; } } @@ -105,7 +103,8 @@ else if(dd == distanceToDest){ return nextLinkId; } - public Id getNextLinkRandomInAcceptableDistance(Id currentLinkId, Id endLinkId, Id vehicleId, double firstDestLinkEnterTime, double timeOfDay, String mode) { + public Id getNextLinkRandomInAcceptableDistance(Id currentLinkId, Id endLinkId, Id vehicleId, + double firstDestLinkEnterTime, double timeOfDay, String mode) { Link nextLink; Link currentLink = network.getLinks().get(currentLinkId); @@ -114,10 +113,14 @@ public Id getNextLinkRandomInAcceptableDistance(Id currentLinkId, Id int nrOfOutGoingLinks = outGoingLinks.size(); for (int i = 1; i <= nrOfOutGoingLinks; i++) { nextLink = outGoingLinks.get(random.nextInt(outGoingLinks.size())); - if (isDriverInAcceptableDistance(nextLink.getId(), endLinkId, firstDestLinkEnterTime, timeOfDay)) return nextLink.getId(); + if (isDriverInAcceptableDistance(nextLink.getId(), endLinkId, firstDestLinkEnterTime, timeOfDay)) { + return nextLink.getId(); + } outGoingLinks.remove(nextLink); - } - logger.error("vehicle " + vehicleId + " finds no outlink in acceptable distance going out from link " + currentLinkId + ". it just takes a random next link"); + } + logger.error("vehicle " + vehicleId + " finds no outlink in acceptable distance going out from link " + currentLinkId + ". it just takes a" + + " " + + "random next link"); return outGoingLinksCopy.get(random.nextInt(outGoingLinksCopy.size())).getId(); } @@ -125,63 +128,70 @@ public Id getNextLinkRandomInAcceptableDistance(Id currentLinkId, Id //---------------------------------------------------park decision----------------------------------------------------------------------- /** - * * estimate amount of free parking spaces on the way to destination Link and decide whether to park on currentLink - * + * * @param pUnoccupied * @param currentLinkId * @param endLinkId - * @return whether vehicle should be parked here + * @return whether vehicle should be parked here */ - public boolean wantToParkHere (double pUnoccupied, Id currentLinkId, Id endLinkId) { - - //if pUnoccupied = 0, no free slot has been detected, so it is realistic to accept the very next free slot + public boolean wantToParkHere(double pUnoccupied, Id currentLinkId, Id endLinkId) { + + //if pUnoccupied = 0, no free slot has been detected, so it is realistic to accept the very next free slot double distToDest = NetworkUtils.getEuclideanDistance( - network.getLinks().get(currentLinkId).getToNode().getCoord(), network.getLinks().get(endLinkId).getToNode().getCoord()); - double expectedFreeSlots = (pUnoccupied*distToDest/configGroup.getAvgparkingslotlength()); - double rnd = Math.random(); - if (logForDebug) - logger.error("\n current link: " + currentLinkId + "\n expected slots: " + expectedFreeSlots + "\n probabilty to continue driving: " + getProbabilityOfContinuingToDrive(expectedFreeSlots) + "\n rnd: " + rnd); - return rnd >= getProbabilityOfContinuingToDrive(expectedFreeSlots); + network.getLinks().get(currentLinkId).getToNode().getCoord(), network.getLinks().get(endLinkId).getToNode().getCoord()); + double expectedFreeSlots = (pUnoccupied * distToDest / configGroup.getAvgparkingslotlength()); + double rnd = random.nextDouble(); + if (logForDebug) { + logger.error("\n current link: " + currentLinkId + "\n expected slots: " + expectedFreeSlots + "\n probabilty to continue driving: " + getProbabilityOfContinuingToDrive(expectedFreeSlots) + "\n rnd: " + rnd); + } + return rnd >= getProbabilityOfContinuingToDrive(expectedFreeSlots); } - + /** - * linear probability function, depending on maximum and minimum threshold + * linear probability function, depending on maximum and minimum threshold */ - private double getProbabilityOfContinuingToDrive(double expectedFreeSlots) { - - if (expectedFreeSlots < MIN_THRESHOLD_PROB_FUNCTION) return 0.0; - else if(expectedFreeSlots > MAX_THRESHOLD_PROB_FUNCTION) return 1.0; - - return (expectedFreeSlots-MIN_THRESHOLD_PROB_FUNCTION)/(MAX_THRESHOLD_PROB_FUNCTION-MIN_THRESHOLD_PROB_FUNCTION); + private double getProbabilityOfContinuingToDrive(double expectedFreeSlots) { + + if (expectedFreeSlots < MIN_THRESHOLD_PROB_FUNCTION) { + return 0.0; + } else if (expectedFreeSlots > MAX_THRESHOLD_PROB_FUNCTION) { + return 1.0; + } + + return (expectedFreeSlots - MIN_THRESHOLD_PROB_FUNCTION) / (MAX_THRESHOLD_PROB_FUNCTION - MIN_THRESHOLD_PROB_FUNCTION); } /** - * * @param currentLinkId * @param endLinkId - * @param firstDestLinkEnterTime + * @param firstDestLinkEnterTime * @param timeOfDay * @return */ - private boolean isDriverInAcceptableDistance(Id currentLinkId, Id endLinkId, double firstDestLinkEnterTime, double timeOfDay) { + private boolean isDriverInAcceptableDistance(Id currentLinkId, Id endLinkId, double firstDestLinkEnterTime, double timeOfDay) { // if we're on the destinationLink, we always want to park - if(currentLinkId.equals(endLinkId)) return true; - - double distToDest = NetworkUtils.getEuclideanDistance(network.getLinks().get(currentLinkId).getCoord(), network.getLinks().get(endLinkId).getCoord()); + if (currentLinkId.equals(endLinkId)) { + return true; + } + + double distToDest = NetworkUtils.getEuclideanDistance(network.getLinks().get(currentLinkId).getCoord(), network.getLinks().get(endLinkId) + .getCoord()); double timeSpent = timeOfDay - firstDestLinkEnterTime; double acceptedDistance = ACCEPTED_DISTANCE_START + ACCEPTED_DISTANCE_INCREASING_RATE_PER_MIN * (timeSpent / 60); - - if (acceptedDistance > ACCEPTED_DISTANCE_MAX) acceptedDistance = ACCEPTED_DISTANCE_MAX; - - if (distToDest <= acceptedDistance){ - if(logForDebug){ + + if (acceptedDistance > ACCEPTED_DISTANCE_MAX) { + acceptedDistance = ACCEPTED_DISTANCE_MAX; + } + + if (distToDest <= acceptedDistance) { + if (logForDebug) { logger.error(" distance between link " + currentLinkId + " and destLink " + endLinkId + ": " + distToDest); logger.error("accepted : " + acceptedDistance); logger.error("time spent: " + timeSpent); } - return true; + return true; } return false; } @@ -190,5 +200,5 @@ private boolean isDriverInAcceptableDistance(Id currentLinkId, Id en public Id getNextLink(Id currentLinkId, Id vehicleId, String mode) { throw new RuntimeException("this should not happen!"); } - + } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/DistanceMemoryParkingSearchLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/DistanceMemoryParkingSearchLogic.java index c4616c7df1e..5529e5b3c0a 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/DistanceMemoryParkingSearchLogic.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/DistanceMemoryParkingSearchLogic.java @@ -1,5 +1,5 @@ /** - * + * */ package org.matsim.contrib.parking.parkingsearch.search; @@ -19,24 +19,24 @@ /** * @author tschlenther - * - *Agents drive to destination first. Knowledge about surrounding streets is assumed. If no parking slot is available, they always look - *for a slot on the one outgoing link that has the shortest distance to their destination and is unknown to them so far. If every outlink - *is known they choose the next link to search on randomly. - * + *

+ * Agents drive to destination first. Knowledge about surrounding streets is assumed. If no parking slot is available, they always look + * for a slot on the one outgoing link that has the shortest distance to their destination and is unknown to them so far. If every outlink + * is known they choose the next link to search on randomly. */ public class DistanceMemoryParkingSearchLogic implements ParkingSearchLogic { private static final Logger logger = LogManager.getLogger(DistanceMemoryParkingSearchLogic.class); - private static final boolean doLogging = false; - +// static { +// Configurator.setRootLevel(org.apache.logging.log4j.Level.DEBUG); +// } + private Network network; - private HashSet> knownLinks; - + private HashSet> knownLinks; + /** - * @param network - * + * @param network */ public DistanceMemoryParkingSearchLogic(Network network) { this.network = network; @@ -49,49 +49,50 @@ public Id getNextLink(Id currentLinkId, Id destLinkId, Id nextLink = null; - - if(doLogging) logger.info("number of outlinks of link " + currentLinkId + ": " + outLinks.size()); + + logger.debug("number of outlinks of link {}: {}", currentLinkId, outLinks.size()); for (Link outLink : outLinks) { Id outLinkId = outLink.getId(); - if (this.knownLinks.contains(outLinkId)) nrKnownLinks++; - else{ + if (this.knownLinks.contains(outLinkId)) { + nrKnownLinks++; + } else { double distToDest = NetworkUtils.getEuclideanDistance(outLink.getCoord(), network.getLinks().get(destLinkId).getCoord()); - if (distToDest < shortestDistance){ + if (distToDest < shortestDistance) { nextLink = outLinkId; shortestDistance = distToDest; - if(doLogging) logger.info("currently chosen link: " + nextLink + " distToDest: " + shortestDistance); - } - else if(distToDest == shortestDistance){ + logger.debug("currently chosen link: {} distToDest: {}", nextLink, shortestDistance); + } else if (distToDest == shortestDistance) { String message = "link " + nextLink + " and link " + outLinkId + " both are " + distToDest + "m away from destination."; - if (Math.random() > 0.5) - nextLink = outLinkId; - if(doLogging) logger.info(message + " link " + nextLink + " is chosen."); - } - else{ - if (doLogging){ - logger.info("link " + outLinkId + " was not chosen because it is " + distToDest + "m away whereas shortest distance is " + shortestDistance); + if (MatsimRandom.getRandom().nextBoolean()) { + nextLink = outLinkId; } + logger.debug("{} link {} is chosen.", message, nextLink); + } else { + logger.debug("link {} was not chosen because it is {}m away whereas shortest distance is {}", outLinkId, distToDest, + shortestDistance); } } } - if(doLogging)logger.error("vehicle " + vehicleId + " knew " + nrKnownLinks + " out of " + outLinks.size() + " outlinks of link " + currentLinkId); - if(outLinks.size() == nrKnownLinks ){ - if(doLogging)logger.error("vehicle " + vehicleId + " knows all outlinks of link " + currentLinkId); - + logger.debug("vehicle {} knew {} out of {} outlinks of link {}", vehicleId, nrKnownLinks, outLinks.size(), currentLinkId); + if (outLinks.size() == nrKnownLinks) { + logger.debug("vehicle {} knows all outlinks of link {}", vehicleId, currentLinkId); + //return random Link int index = MatsimRandom.getRandom().nextInt(outLinks.size()); Iterator iter = outLinks.iterator(); for (int i = 0; i < index; i++) { - iter.next(); + iter.next(); } nextLink = iter.next().getId(); - } - - if(nextLink == null){ - throw new RuntimeException("the next Link Id for vehicle " + vehicleId + " on current link " + currentLinkId + " couldn't be calculated."); } - if(doLogging)logger.error("vehicle " + vehicleId + " takes link " + nextLink + " as next link"); + + if (nextLink == null) { + throw new RuntimeException("the next Link Id for vehicle " + vehicleId + " on current link " + currentLinkId + " couldn't be " + + "calculated" + + "."); + } + logger.debug("vehicle {} takes link {} as next link", vehicleId, nextLink); this.knownLinks.add(nextLink); return nextLink; } @@ -105,8 +106,8 @@ public Id getNextLink(Id currentLinkId, Id vehicleId, Strin throw new RuntimeException("shouldn't happen - method not implemented"); } - public void addToKnownLinks(Id linkId){ + public void addToKnownLinks(Id linkId) { this.knownLinks.add(linkId); } - + } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java index d87bf0408fe..de4be67c97f 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java @@ -69,7 +69,7 @@ public NearestParkingSpotSearchLogic(Network network, ParkingRouter parkingRoute this.parkingManager = parkingManager; this.canReserveParkingSlot = canReserveParkingSlot; this.canCheckParkingCapacitiesInAdvanced = canCheckParkingCapacitiesInAdvanced; - activityFacilities = ((FacilityBasedParkingManager) parkingManager).getParkingFacilities(); + activityFacilities = ((FacilityBasedParkingManager) parkingManager).getParkingFacilitiesById(); currentLinkIdx = 0; triedParking = new HashSet<>(); nextLink = null; @@ -83,26 +83,30 @@ public Id getNextLink(Id currentLinkId, Id baseLinkId, Id getNextLink(Id currentLinkId, Id baseLinkId, Id baseLinkId, Coord coordOfAttraction) { for (ActivityFacility activityFacility : activityFacilities.values()) { - if (activityFacility.getLinkId().equals(baseLinkId)) + if (activityFacility.getLinkId().equals(baseLinkId)) { distanceFromBaseToAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(), coordOfAttraction); + } } } /** - * Checks if it is possible to drive to the new parking facility and to drive back to the base without extending the startTime of the following activity. + * Checks if it is possible to drive to the new parking facility and to drive back to the base without extending the startTime of the following + * activity. * If the resulting parking time at the new facility is less then 5 minutes the vehicle will drive directly to the next activity location. * * @param currentLinkId @@ -148,17 +154,20 @@ private void findDistanceBetweenBaseLinkAndAttraction(Id baseLinkId, Coord private void checkIfDrivingToNextParkingLocationIsPossible(Id currentLinkId, Id baseLinkId, double now, double nextPickupTime) { double expectedTravelTimeFromParkingToBase; - if (actualRoute == null) + if (actualRoute == null) { expectedTravelTimeFromParkingToBase = this.parkingRouter.getRouteFromParkingToDestination(baseLinkId, now, currentLinkId).getTravelTime().seconds(); //TODO better: use the nextLink for the check - else + } else { expectedTravelTimeFromParkingToBase = this.parkingRouter.getRouteFromParkingToDestination(baseLinkId, now, actualRoute.getEndLinkId()).getTravelTime().seconds(); + } double minimumExpectedParkingDuration = 5 * 60; double travelTimeNextPart; - if (actualRoute == null) + if (actualRoute == null) { travelTimeNextPart = 0.; - else travelTimeNextPart = actualRoute.getTravelTime().seconds(); + } else { + travelTimeNextPart = actualRoute.getTravelTime().seconds(); + } if ((nextPickupTime - now - travelTimeNextPart - expectedTravelTimeFromParkingToBase) < minimumExpectedParkingDuration) { actualRoute = this.parkingRouter.getRouteFromParkingToDestination(baseLinkId, now, @@ -168,8 +177,9 @@ private void checkIfDrivingToNextParkingLocationIsPossible(Id currentLinkI } public Id getNextParkingLocation() { - if (actualRoute == null) + if (actualRoute == null) { return null; + } return actualRoute.getEndLinkId(); } @@ -208,34 +218,42 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id now && parkingOptions.getOpeningTimes().first().getEndTime() < latestEndOfParking) + if (parkingOptions.getOpeningTimes().first().getStartTime() > now && parkingOptions.getOpeningTimes().first() + .getEndTime() < latestEndOfParking) { continue; + } } //check if approx. the max parking time at facility will not exceed, assumption: "parking duration - 30 minutes" is parking Time. if (activityFacility.getAttributes().getAsMap().containsKey("maxParkingDurationInHours")) { //TODO vielleicht etwas sparsamer machen double maxParkingDurationAtFacility = 3600 * (double) activityFacility.getAttributes().getAsMap().get("maxParkingDurationInHours"); - if (maxParkingDuration - 30*60 > maxParkingDurationAtFacility) + if (maxParkingDuration - 30 * 60 > maxParkingDurationAtFacility) { continue; + } } //TODO beschreiben was passiert if (passangerInteractionAtParkingFacilityAtEndOfLeg) { double distanceBetweenThisParkingFacilityAndTheAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(), coordOfAttraction); - if (distanceBetweenThisParkingFacilityAndTheAttraction - distanceFromBaseToAttraction > maxDistanceFromBase) + if (distanceBetweenThisParkingFacilityAndTheAttraction - distanceFromBaseToAttraction > maxDistanceFromBase) { continue; + } } // create Euclidean distances to the parking activities to find routes only to the nearest facilities in the next step Coord coordBaseLink = network.getLinks().get(baseLinkId).getCoord(); @@ -243,10 +261,11 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id baseLinkId, Id maxParkingDurationAtFacility) + if (expectedParkingTime > maxParkingDurationAtFacility) { continue; + } } counter++; - if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() > triedParking.size()) - if (triedParking.contains(activityFacility.getId())) + if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() > triedParking.size()) { + if (triedParking.contains(activityFacility.getId())) { continue; - if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() == triedParking.size()) + } + } + if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() == triedParking.size()) { triedParking.clear(); + } NetworkRoute possibleRoute = this.parkingRouter.getRouteFromParkingToDestination(activityFacility.getLinkId(), now, currentLinkId); // reason is that we expect that the driver will always take the nearest possible getOff point to reduce the walk distance for the guests - if (passangerInteractionAtParkingFacilityAtEndOfLeg){ + if (passangerInteractionAtParkingFacilityAtEndOfLeg) { selectedRoute = possibleRoute; nearstActivityFacility = activityFacility; break; @@ -292,8 +315,9 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id getComments() { - Map map = super.getComments(); + Map map = super.getComments(); map.put(UNPARKDURATION, "Duration to unpark a vehicle"); map.put(PARKDURATION, "Duration to park a vehicle"); - map.put(PARKINGSEARCH_STRATEGY, "The strategy to find a parking slot. Possible strategies: " + Arrays.toString(ParkingSearchStrategy.values())); + map.put(PARKINGSEARCH_STRATEGY, + "The strategy to find a parking slot. Possible strategies: " + Arrays.toString(ParkingSearchStrategy.values())); map.put(PARKINGSEARCH_MANAGER, "The type of the ParkingManager, may have the values: " + Arrays.toString(ParkingSearchManagerType.values())); - map.put(FRACTION_CAN_CHECK_FREE_CAPACITIES_IN_ADVANCED, "Fraction of agents who can check free capacities in advanced. This is currently developed for the FacilityBasedParkingManager"); - map.put(FRACTION_CAN_RESERVE_PARKING_IN_ADVANCED, "Fraction of agents who can reserve free capacities in advanced. This is currently developed for the FacilityBasedParkingManager\""); - map.put(CAN_PARK_ONLY_AT_FACILITIES, "Set if a vehicle can park only at given parking facilities or it can park freely at a link without a facility."); + map.put(FRACTION_CAN_CHECK_FREE_CAPACITIES_IN_ADVANCED, "Fraction of agents who can check free capacities in advanced. This is currently " + + "developed for the FacilityBasedParkingManager"); + map.put(FRACTION_CAN_RESERVE_PARKING_IN_ADVANCED, "Fraction of agents who can reserve free capacities in advanced. This is currently " + + "developed for the FacilityBasedParkingManager\""); + map.put(CAN_PARK_ONLY_AT_FACILITIES, "Set if a vehicle can park only at given parking facilities or it can park freely at a link without a" + + " " + + "facility."); return map; } @@ -162,11 +170,16 @@ protected void checkConsistency(Config config) { super.checkConsistency(config); - if (getFractionCanCheckFreeCapacitiesInAdvanced() != 0. && !getParkingSearchManagerType().equals(ParkingSearchManagerType.FacilityBasedParkingManager)) - log.warn("Fraction of agents who can check free capacities in advanced has no impact on your selected ParkingSearchManagerType, because it is only implemented for the FacilityBasedParkingManager."); + if (getFractionCanCheckFreeCapacitiesInAdvanced() != 0. && !getParkingSearchManagerType().equals(ParkingSearchManagerType.FacilityBasedParkingManager)) { + log.warn("Fraction of agents who can check free capacities in advanced has no impact on your selected ParkingSearchManagerType, " + + "because" + + " " + + "it is only implemented for the FacilityBasedParkingManager."); + } - if (getFractionCanCheckFreeCapacitiesInAdvanced() + getFractionCanReserveParkingInAdvanced() > 1.0) - throw new RuntimeException( "The sum of " + FRACTION_CAN_RESERVE_PARKING_IN_ADVANCED + " and " + FRACTION_CAN_CHECK_FREE_CAPACITIES_IN_ADVANCED + " is > 1.0. This should not happen."); + if (getFractionCanCheckFreeCapacitiesInAdvanced() + getFractionCanReserveParkingInAdvanced() > 1.0) { + throw new RuntimeException("The sum of " + FRACTION_CAN_RESERVE_PARKING_IN_ADVANCED + " and " + FRACTION_CAN_CHECK_FREE_CAPACITIES_IN_ADVANCED + " is > 1.0. This should not happen."); + } } diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/sim/SetupParking.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/sim/SetupParking.java index 5d8c657d9bb..288434518b1 100644 --- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/sim/SetupParking.java +++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/sim/SetupParking.java @@ -22,6 +22,8 @@ */ package org.matsim.contrib.parking.parkingsearch.sim; +import com.google.inject.Key; +import com.google.inject.name.Names; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.dvrp.router.DvrpGlobalRoutingNetworkProvider; @@ -30,15 +32,15 @@ import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModes; import org.matsim.contrib.dvrp.trafficmonitoring.DvrpTravelTimeModule; -import org.matsim.contrib.parking.parkingsearch.evaluation.ParkingListener; import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager; import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager; +import org.matsim.contrib.parking.parkingsearch.manager.ParkingStatsWriter; import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationLogic; import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationToNearbyParking; import org.matsim.contrib.parking.parkingsearch.routing.ParkingRouter; import org.matsim.contrib.parking.parkingsearch.routing.WithinDayParkingRouter; import org.matsim.core.controler.AbstractModule; -import org.matsim.core.controler.Controler; +import org.matsim.core.controler.Controller; import org.matsim.core.mobsim.qsim.PopulationModule; import org.matsim.core.mobsim.qsim.components.QSimComponentsConfig; import org.matsim.core.mobsim.qsim.components.StandardQSimComponentConfigurator; @@ -46,9 +48,6 @@ import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.TravelTime; -import com.google.inject.Key; -import com.google.inject.name.Names; - /** * @author jbischoff */ @@ -56,41 +55,42 @@ public class SetupParking { // TODO: create config group and make this all configurable? - static public void installParkingModules(Controler controler) { + static public void installParkingModules(Controller controller) { // No need to route car routes in Routing module in advance, as they are // calculated on the fly - if (!controler.getConfig().getModules().containsKey(DvrpConfigGroup.GROUP_NAME)) { - controler.getConfig().addModule(new DvrpConfigGroup()); + if (!controller.getConfig().getModules().containsKey(DvrpConfigGroup.GROUP_NAME)) { + controller.getConfig().addModule(new DvrpConfigGroup()); } - controler.addOverridingModule(new DvrpTravelTimeModule()); - controler.addOverridingModule(new AbstractModule() { + controller.addOverridingModule(new DvrpTravelTimeModule()); + controller.addOverridingModule(new AbstractModule() { @Override public void install() { bind(TravelTime.class).annotatedWith(DvrpModes.mode(TransportMode.car)) - .to(Key.get(TravelTime.class, Names.named(DvrpTravelTimeModule.DVRP_ESTIMATED))); + .to(Key.get(TravelTime.class, Names.named(DvrpTravelTimeModule.DVRP_ESTIMATED))); bind(TravelDisutilityFactory.class).annotatedWith(DvrpModes.mode(TransportMode.car)) - .toInstance(TimeAsTravelDisutility::new); + .toInstance(TimeAsTravelDisutility::new); bind(Network.class).annotatedWith(DvrpModes.mode(TransportMode.car)) - .to(Key.get(Network.class, Names.named(DvrpGlobalRoutingNetworkProvider.DVRP_ROUTING))); + .to(Key.get(Network.class, Names.named(DvrpGlobalRoutingNetworkProvider.DVRP_ROUTING))); install(new DvrpModeRoutingModule(TransportMode.car, new SpeedyALTFactory())); bind(Network.class).annotatedWith(Names.named(DvrpGlobalRoutingNetworkProvider.DVRP_ROUTING)) - .to(Network.class) - .asEagerSingleton(); + .to(Network.class) + .asEagerSingleton(); bind(ParkingSearchManager.class).to(FacilityBasedParkingManager.class).asEagerSingleton(); + bind(ParkingStatsWriter.class); this.install(new ParkingSearchQSimModule()); - addControlerListenerBinding().to(ParkingListener.class); + addControlerListenerBinding().to(ParkingSearchManager.class); bind(ParkingRouter.class).to(WithinDayParkingRouter.class); bind(VehicleTeleportationLogic.class).to(VehicleTeleportationToNearbyParking.class); } }); - controler.addOverridingModule(new AbstractModule() { + controller.addOverridingModule(new AbstractModule() { @Override public void install() { QSimComponentsConfig components = new QSimComponentsConfig(); - new StandardQSimComponentConfigurator(controler.getConfig()).configure(components); + new StandardQSimComponentConfigurator(controller.getConfig()).configure(components); components.removeNamedComponent(PopulationModule.COMPONENT_NAME); components.addNamedComponent(ParkingSearchPopulationModule.COMPONENT_NAME); diff --git a/contribs/parking/src/main/resources/parkingsearch/parkingFacilities.xml b/contribs/parking/src/main/resources/parkingsearch/parkingFacilities.xml index 95ecbfd1cc2..8f2228dcb5b 100644 --- a/contribs/parking/src/main/resources/parkingsearch/parkingFacilities.xml +++ b/contribs/parking/src/main/resources/parkingsearch/parkingFacilities.xml @@ -2,36 +2,36 @@ - + - - + + - - + + - + - - + + - - + + - + diff --git a/contribs/parking/src/main/resources/parkingsearch/population1.xml b/contribs/parking/src/main/resources/parkingsearch/population1.xml new file mode 100644 index 00000000000..4bace31f8e2 --- /dev/null +++ b/contribs/parking/src/main/resources/parkingsearch/population1.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/parking/src/main/resources/parkingsearch/population10.xml b/contribs/parking/src/main/resources/parkingsearch/population10.xml new file mode 100644 index 00000000000..059d8165658 --- /dev/null +++ b/contribs/parking/src/main/resources/parkingsearch/population10.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT.java deleted file mode 100644 index e3959961195..00000000000 --- a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT.java +++ /dev/null @@ -1,157 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2017 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.contrib.parking.parkingchoice.run; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Population; -import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; -import org.matsim.contrib.parking.parkingsearch.RunParkingSearchExample; -import org.matsim.contrib.parking.parkingsearch.sim.ParkingSearchConfigGroup; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.events.EventsUtils; -import org.matsim.core.population.PopulationUtils; -import org.matsim.testcases.MatsimTestUtils; -import org.matsim.utils.eventsfilecomparison.ComparisonResult; - -/** - * @author jbischoff - */ -public class RunParkingSearchScenarioIT { - @RegisterExtension - private MatsimTestUtils utils = new MatsimTestUtils(); - - @Test - void testRunParkingBenesonStrategy() { - try { - String configFile = "./src/main/resources/parkingsearch/config.xml"; - Config config = ConfigUtils.loadConfig(configFile, new ParkingSearchConfigGroup()); - config.controller().setLastIteration(0); - config.controller().setOutputDirectory(utils.getOutputDirectory()); - - ParkingSearchConfigGroup configGroup = (ParkingSearchConfigGroup) config.getModules().get(ParkingSearchConfigGroup.GROUP_NAME); - configGroup.setParkingSearchStrategy(ParkingSearchStrategy.Benenson); - - new RunParkingSearchExample().run(config, false); - - } catch (Exception e) { - e.printStackTrace(); - Assertions.fail("something went wrong"); - } - } - - @Test - void testRunParkingRandomStrategy() { - String configFile = "./src/main/resources/parkingsearch/config.xml"; - Config config = ConfigUtils.loadConfig(configFile, new ParkingSearchConfigGroup()); - config.controller().setLastIteration(0); - config.controller().setOutputDirectory(utils.getOutputDirectory()); - - ParkingSearchConfigGroup configGroup = (ParkingSearchConfigGroup) config.getModules().get(ParkingSearchConfigGroup.GROUP_NAME); - configGroup.setParkingSearchStrategy(ParkingSearchStrategy.Random); - - try { - new RunParkingSearchExample().run(config, false); - } catch (Exception e) { - e.printStackTrace(); - Assertions.fail("something went wrong"); - } - } - - @Test - void testRunParkingDistanceMemoryStrategy() { - try { - String configFile = "./src/main/resources/parkingsearch/config.xml"; - Config config = ConfigUtils.loadConfig(configFile, new ParkingSearchConfigGroup()); - config.controller().setLastIteration(0); - config.controller().setOutputDirectory(utils.getOutputDirectory()); - - ParkingSearchConfigGroup configGroup = (ParkingSearchConfigGroup) config.getModules().get(ParkingSearchConfigGroup.GROUP_NAME); - configGroup.setParkingSearchStrategy(ParkingSearchStrategy.DistanceMemory); - - new RunParkingSearchExample().run(config, false); - { - Population expected = PopulationUtils.createPopulation(ConfigUtils.createConfig()); - PopulationUtils.readPopulation(expected, utils.getInputDirectory() + "/output_plans.xml.gz"); - - Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig()); - PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz"); - - for (Id personId : expected.getPersons().keySet()) { - double scoreReference = expected.getPersons().get(personId).getSelectedPlan().getScore(); - double scoreCurrent = actual.getPersons().get(personId).getSelectedPlan().getScore(); - Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of person=" + personId + " are different"); - } - - } - { - String expected = utils.getInputDirectory() + "/output_events.xml.gz"; - String actual = utils.getOutputDirectory() + "/output_events.xml.gz"; - ComparisonResult result = EventsUtils.compareEventsFiles(expected, actual); - Assertions.assertEquals(ComparisonResult.FILES_ARE_EQUAL, result); - } - } catch (Exception e) { - e.printStackTrace(); - Assertions.fail("something went wrong"); - } - } - - @Test - void testRunParkingNearestParkingSpotStrategy() { - try { - String configFile = "./src/main/resources/parkingsearch/config.xml"; - Config config = ConfigUtils.loadConfig(configFile, new ParkingSearchConfigGroup()); - config.controller().setLastIteration(0); - config.controller().setOutputDirectory(utils.getOutputDirectory()); - - ParkingSearchConfigGroup configGroup = (ParkingSearchConfigGroup) config.getModules().get(ParkingSearchConfigGroup.GROUP_NAME); - configGroup.setParkingSearchStrategy(ParkingSearchStrategy.NearestParkingSpot); - - new RunParkingSearchExample().run(config, false); - { - Population expected = PopulationUtils.createPopulation(ConfigUtils.createConfig()); - PopulationUtils.readPopulation(expected, utils.getInputDirectory() + "/output_plans.xml.gz"); - - Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig()); - PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz"); - - for (Id personId : expected.getPersons().keySet()) { - double scoreReference = expected.getPersons().get(personId).getSelectedPlan().getScore(); - double scoreCurrent = actual.getPersons().get(personId).getSelectedPlan().getScore(); - Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of person=" + personId + " are different"); - } - - } - { - String expected = utils.getInputDirectory() + "/output_events.xml.gz"; - String actual = utils.getOutputDirectory() + "/output_events.xml.gz"; - ComparisonResult result = EventsUtils.compareEventsFiles(expected, actual); - Assertions.assertEquals(ComparisonResult.FILES_ARE_EQUAL, result); - } - } catch (Exception e) { - e.printStackTrace(); - Assertions.fail("something went wrong"); - } - } -} diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/AbstractParkingTest.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/AbstractParkingTest.java new file mode 100644 index 00000000000..fee02ad587f --- /dev/null +++ b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/AbstractParkingTest.java @@ -0,0 +1,130 @@ +package org.matsim.contrib.parking.parkingsearch.facilityBasedParking; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; +import org.matsim.contrib.parking.parkingsearch.sim.ParkingSearchConfigGroup; +import org.matsim.contrib.parking.parkingsearch.sim.SetupParking; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.Controller; +import org.matsim.core.controler.ControllerUtils; +import org.matsim.core.events.EventsUtils; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.testcases.MatsimTestUtils; +import org.matsim.utils.eventsfilecomparison.ComparisonResult; + +public abstract class AbstractParkingTest { + @RegisterExtension + MatsimTestUtils utils = new MatsimTestUtils(); + + abstract ParkingSearchStrategy getParkingSearchStrategy(); + + @Test + void testParking1() { + Config config = getConfig(getParkingConfig()); + config.plans().setInputFile("population1.xml"); + run(config); + validate(); + } + + @Test + void testParking10() { + Config config = getConfig(getParkingConfig()); + config.plans().setInputFile("population10.xml"); + run(config); + validate(); + } + + @Test + void testParking100() { + Config config = getConfig(getParkingConfig()); + run(config); + validate(); + } + + @Test + void testParking1_onlyFacilityParking() { + ParkingSearchConfigGroup parkingConfig = getParkingConfig(); + parkingConfig.setCanParkOnlyAtFacilities(true); + Config config = getConfig(parkingConfig); + config.plans().setInputFile("population1.xml"); + run(config); + validate(); + } + + /** + * Tests the behaviour of the parking search when only parking at facilities is allowed. + * Result: Agents are trying to park at facilities and are searching so long for a parking space until they found one. + */ + @Test + void testParking10_onlyFacilityParking() { + ParkingSearchConfigGroup parkingConfig = getParkingConfig(); + parkingConfig.setCanParkOnlyAtFacilities(true); + Config config = getConfig(parkingConfig); + config.plans().setInputFile("population10.xml"); + run(config); + validate(); + } + + private ParkingSearchConfigGroup getParkingConfig() { + ParkingSearchConfigGroup parkingSearchConfigGroup = new ParkingSearchConfigGroup(); + parkingSearchConfigGroup.setParkingSearchStrategy(getParkingSearchStrategy()); + return parkingSearchConfigGroup; + } + + private Config getConfig(ParkingSearchConfigGroup parkingSearchConfigGroup) { + Config config = ConfigUtils.loadConfig("parkingsearch/config.xml", parkingSearchConfigGroup); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + return config; + } + + private void run(Config config) { + Scenario scenario = ScenarioUtils.loadScenario(config); + + Controller controller = ControllerUtils.createController(scenario); + SetupParking.installParkingModules(controller); + controller.run(); + } + + private void validate() { + comparePopulation(); + compareEvents(); + compareCsv("0.parkingStats.csv"); + compareCsv("0.parkingStatsPerTimeSteps.csv"); + } + + private void compareCsv(String fileName) { + String parkingStatsOut = utils.getOutputDirectory() + "/ITERS/it.0/" + fileName; + String parkingStatsIn = utils.getInputDirectory() + "/" + fileName; + MatsimTestUtils.assertEqualFilesLineByLine(parkingStatsIn, parkingStatsOut); + } + + private void compareEvents() { + String expectedEventsFile = utils.getInputDirectory() + "/output_events.xml.gz"; + String actualEventsFile = utils.getOutputDirectory() + "/output_events.xml.gz"; + ComparisonResult result = EventsUtils.compareEventsFiles(expectedEventsFile, actualEventsFile); + Assertions.assertEquals(ComparisonResult.FILES_ARE_EQUAL, result); + } + + private void comparePopulation() { + Population expected = PopulationUtils.createPopulation(ConfigUtils.createConfig()); + PopulationUtils.readPopulation(expected, utils.getInputDirectory() + "/output_plans.xml.gz"); + + Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig()); + PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz"); + + for (Id personId : expected.getPersons().keySet()) { + double scoreReference = expected.getPersons().get(personId).getSelectedPlan().getScore(); + double scoreCurrent = actual.getPersons().get(personId).getSelectedPlan().getScore(); + Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of person=" + personId + " are different"); + } + } +} diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest.java new file mode 100644 index 00000000000..fe21aa68bbe --- /dev/null +++ b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest.java @@ -0,0 +1,10 @@ +package org.matsim.contrib.parking.parkingsearch.facilityBasedParking; + +import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; + +public class BenensonParkingTest extends AbstractParkingTest { + @Override + ParkingSearchStrategy getParkingSearchStrategy() { + return ParkingSearchStrategy.Benenson; + } +} diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest.java new file mode 100644 index 00000000000..9822c5a68d5 --- /dev/null +++ b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest.java @@ -0,0 +1,10 @@ +package org.matsim.contrib.parking.parkingsearch.facilityBasedParking; + +import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; + +public class DistanceMemoryParkingTest extends AbstractParkingTest { + @Override + ParkingSearchStrategy getParkingSearchStrategy() { + return ParkingSearchStrategy.DistanceMemory; + } +} diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest.java new file mode 100644 index 00000000000..0403332ec60 --- /dev/null +++ b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest.java @@ -0,0 +1,12 @@ +package org.matsim.contrib.parking.parkingsearch.facilityBasedParking; + +import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; + +public class NearestParkingSpotTest extends AbstractParkingTest { + @Override + ParkingSearchStrategy getParkingSearchStrategy() { + return ParkingSearchStrategy.NearestParkingSpot; + } + + //TODO something is wrong with this strategy. Even for 100 vehicles, all of them are parking in the same parking spot. +} diff --git a/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest.java b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest.java new file mode 100644 index 00000000000..c473a821ea7 --- /dev/null +++ b/contribs/parking/src/test/java/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest.java @@ -0,0 +1,10 @@ +package org.matsim.contrib.parking.parkingsearch.facilityBasedParking; + +import org.matsim.contrib.parking.parkingsearch.ParkingSearchStrategy; + +public class RandomParkingTest extends AbstractParkingTest { + @Override + ParkingSearchStrategy getParkingSearchStrategy() { + return ParkingSearchStrategy.Random; + } +} diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_events.xml.gz deleted file mode 100644 index e80c449a03b..00000000000 Binary files a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_events.xml.gz and /dev/null differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_plans.xml.gz deleted file mode 100644 index e2a50e6fa9a..00000000000 Binary files a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingDistanceMemoryStrategy/output_plans.xml.gz and /dev/null differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_events.xml.gz new file mode 100644 index 00000000000..36d8ae41c21 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_plans.xml.gz new file mode 100644 index 00000000000..cf995fee841 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStats.csv new file mode 100644 index 00000000000..7bd305e83eb --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;10;5;5;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;10;5;5;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_events.xml.gz new file mode 100644 index 00000000000..fd76d129a1b Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_plans.xml.gz new file mode 100644 index 00000000000..b49179b7c90 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStats.csv new file mode 100644 index 00000000000..ee6192c5425 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;104;5;99;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;26;10;16;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;107;10;97;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;30;5;25;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..716c4f390f1 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;3 +09:15;0;0;1 +09:30;0;0;2 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_events.xml.gz new file mode 100644 index 00000000000..3300cf6fc43 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_plans.xml.gz new file mode 100644 index 00000000000..d18738479e9 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking100/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..dcdd85c0325 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;12;5;7;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;3;3;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;15;7;8;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;5;5;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..983cb03d56a Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..63644bd8eb6 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10OnlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..dcdd85c0325 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;12;5;7;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;3;3;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;15;7;8;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;5;5;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..983cb03d56a Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..63644bd8eb6 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..36d8ae41c21 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..cf995fee841 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1OnlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..36d8ae41c21 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..cf995fee841 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/BenensonParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_events.xml.gz new file mode 100644 index 00000000000..2bc7be4d53f Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_plans.xml.gz new file mode 100644 index 00000000000..26b51e95fff Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStats.csv new file mode 100644 index 00000000000..2ee1656326c --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;10;5;5;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;5;5;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;10;5;5;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;5;5;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_events.xml.gz new file mode 100644 index 00000000000..a216a012aef Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_plans.xml.gz new file mode 100644 index 00000000000..a8ff7a8b2bd Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStats.csv new file mode 100644 index 00000000000..804d206d189 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;100;5;95;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;90;10;80;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;100;10;90;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;95;5;90;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..12979cdbad0 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;7 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_events.xml.gz new file mode 100644 index 00000000000..1bb01ce6e46 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_plans.xml.gz new file mode 100644 index 00000000000..4c78de8075a Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking100/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..2ee1656326c --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;10;5;5;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;5;5;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;10;5;5;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;5;5;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..a216a012aef Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..a8ff7a8b2bd Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..2bc7be4d53f Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..26b51e95fff Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/DistanceMemoryParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStats.csv new file mode 100644 index 00000000000..7e2bf32fac8 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;0;0;0;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;0;0;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_events.xml.gz new file mode 100644 index 00000000000..8e1a8f4a86a Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_plans.xml.gz new file mode 100644 index 00000000000..c3d3666b97e Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStats.csv new file mode 100644 index 00000000000..7e2bf32fac8 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;0;0;0;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;0;0;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_events.xml.gz new file mode 100644 index 00000000000..cadcc82dcbc Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_plans.xml.gz new file mode 100644 index 00000000000..40f4eaec10e Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStats.csv new file mode 100644 index 00000000000..7e2bf32fac8 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;0;0;0;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;0;0;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingNearestParkingSpotStrategy/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/output_events.xml.gz similarity index 100% rename from contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingNearestParkingSpotStrategy/output_events.xml.gz rename to contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/output_events.xml.gz diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingNearestParkingSpotStrategy/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/output_plans.xml.gz similarity index 100% rename from contribs/parking/test/input/org/matsim/contrib/parking/parkingchoice/run/RunParkingSearchScenarioIT/testRunParkingNearestParkingSpotStrategy/output_plans.xml.gz rename to contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking100/output_plans.xml.gz diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..7e2bf32fac8 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;0;0;0;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;0;0;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..cadcc82dcbc Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..40f4eaec10e Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking10_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..7e2bf32fac8 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;0;0;0;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;0;0;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..8e1a8f4a86a Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..c3d3666b97e Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/NearestParkingSpotTest/testParking1_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_events.xml.gz new file mode 100644 index 00000000000..2bc7be4d53f Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_plans.xml.gz new file mode 100644 index 00000000000..26b51e95fff Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStats.csv new file mode 100644 index 00000000000..f3c91e1630b --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;10;5;5;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;10;5;5;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;1;1;1;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..aee46863f7a --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;0 +09:15;0;0;0 +09:30;0;0;0 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_events.xml.gz new file mode 100644 index 00000000000..fa9a7b934f2 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_plans.xml.gz new file mode 100644 index 00000000000..4c36398342c Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStats.csv new file mode 100644 index 00000000000..ddfea464dac --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;106;5;101;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;24;10;14;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;102;10;92;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;5;22;5;17;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..89a94f7925f --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1,62 @@ +time;rejectedParkingRequest;foundParking;unpark +09:00;0;0;2 +09:15;0;0;3 +09:30;0;0;2 +09:45;0;0;0 +10:00;0;0;0 +10:15;0;0;0 +10:30;0;0;0 +10:45;0;0;0 +11:00;0;0;0 +11:15;0;0;0 +11:30;0;0;0 +11:45;0;0;0 +12:00;0;0;0 +12:15;0;0;0 +12:30;0;0;0 +12:45;0;0;0 +13:00;0;0;0 +13:15;0;0;0 +13:30;0;0;0 +13:45;0;0;0 +14:00;0;0;0 +14:15;0;0;0 +14:30;0;0;0 +14:45;0;0;0 +15:00;0;0;0 +15:15;0;0;0 +15:30;0;0;0 +15:45;0;0;0 +16:00;0;0;0 +16:15;0;0;0 +16:30;0;0;0 +16:45;0;0;0 +17:00;0;0;0 +17:15;0;0;0 +17:30;0;0;0 +17:45;0;0;0 +18:00;0;0;0 +18:15;0;0;0 +18:30;0;0;0 +18:45;0;0;0 +19:00;0;0;0 +19:15;0;0;0 +19:30;0;0;0 +19:45;0;0;0 +20:00;0;0;0 +20:15;0;0;0 +20:30;0;0;0 +20:45;0;0;0 +21:00;0;0;0 +21:15;0;0;0 +21:30;0;0;0 +21:45;0;0;0 +22:00;0;0;0 +22:15;0;0;0 +22:30;0;0;0 +22:45;0;0;0 +23:00;0;0;0 +23:15;0;0;0 +23:30;0;0;0 +23:45;0;0;0 +24:00;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_events.xml.gz new file mode 100644 index 00000000000..1ba46f218f0 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_plans.xml.gz new file mode 100644 index 00000000000..f7d3b5d44ea Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking100/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..8704e2ee490 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;5;11;6;5;0;0;0 +149;300.0;-190.0;149_curbside;5.0;1;3;3;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;2;13;8;5;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;2;3;3;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..998560e4410 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..c9e8cf0c736 Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking10_onlyFacilityParking/output_plans.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv new file mode 100644 index 00000000000..11b81e47e1d --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStats.csv @@ -0,0 +1,5 @@ +linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn +114;-300.0;-790.0;114_curbside;5.0;1;1;1;0;0;0;0 +149;300.0;-190.0;149_curbside;5.0;0;0;0;0;0;0;0 +349;300.0;-210.0;349_curbside;5.0;0;1;1;0;0;0;0 +314;-300.0;-810.0;314_curbside;5.0;0;0;0;0;0;0;0 diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv new file mode 100644 index 00000000000..fc35dee9a03 --- /dev/null +++ b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/0.parkingStatsPerTimeSteps.csv @@ -0,0 +1 @@ +time;rejectedParkingRequest;foundParking;unpark diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz new file mode 100644 index 00000000000..2bc7be4d53f Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_events.xml.gz differ diff --git a/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz new file mode 100644 index 00000000000..26b51e95fff Binary files /dev/null and b/contribs/parking/test/input/org/matsim/contrib/parking/parkingsearch/facilityBasedParking/RandomParkingTest/testParking1_onlyFacilityParking/output_plans.xml.gz differ diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java index d0532315137..02ea9efcf79 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java +++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinks.java @@ -20,7 +20,6 @@ package org.matsim.pt.utils; -import com.google.common.annotations.Beta; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Link; @@ -40,11 +39,8 @@ * is assigned to a loop link, located in a node with the same coordinates as the stop. * The stop facility ID is used for node and link IDs. * - * @author mrieser, davibicudo - * - * @implNote THis functionality might be merged with {@link CreatePseudoNetwork}. + * @author mrieser, davibicudo, rakow */ -@Beta public class CreatePseudoNetworkWithLoopLinks { private final TransitSchedule schedule; @@ -82,23 +78,29 @@ public void createNetwork() { List> toBeRemoved = new LinkedList<>(); for (TransitLine tLine : this.schedule.getTransitLines().values()) { for (TransitRoute tRoute : tLine.getRoutes().values()) { - ArrayList> routeLinks = new ArrayList<>(); + + if (tRoute.getStops().size() < 2) { + System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule."); + toBeRemoved.add(new Tuple<>(tLine, tRoute)); + continue; + } + + List> routeLinks = new ArrayList<>(); TransitRouteStop prevStop = null; + for (TransitRouteStop stop : tRoute.getStops()) { if (prevStop != null) { Link link = getNetworkLink(prevStop, stop); routeLinks.add(link.getId()); } + + // Add the loop links of all stops to the route + routeLinks.add(getLoopLink(stop.getStopFacility()).getId()); prevStop = stop; } - if (!routeLinks.isEmpty()) { - NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks); - tRoute.setRoute(route); - } else { - System.err.println("Line " + tLine.getId() + " route " + tRoute.getId() + " has less than two stops. Removing this route from schedule."); - toBeRemoved.add(new Tuple<>(tLine, tRoute)); - } + NetworkRoute route = RouteUtils.createNetworkRoute(routeLinks); + tRoute.setRoute(route); } } @@ -114,6 +116,14 @@ private void createStopNodesAndLoopLinks() { this.nodes.put(stop, node); Link loopLink = this.network.getFactory().createLink(Id.createLinkId (this.prefix + stop.getId()), node, node); + // Loop links needs to have a length so that the travel time is not zero + loopLink.setLength(1); + loopLink.setFreespeed(linkFreeSpeed); + loopLink.setCapacity(linkCapacity); + // Ensure enough vehicles can be placed on the loop link + loopLink.setNumberOfLanes(linkCapacity); + loopLink.setAllowedModes(transitModes); + stop.setLinkId(loopLink.getId()); this.network.addLink(loopLink); Tuple connection = new Tuple<>(node, node); @@ -121,6 +131,15 @@ private void createStopNodesAndLoopLinks() { } } + /** + * Get the loop link for a stop facility. + */ + private Link getLoopLink(final TransitStopFacility stop) { + Node node = this.nodes.get(stop); + Tuple connection = new Tuple<>(node, node); + return this.links.get(connection); + } + private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteStop toStop) { TransitStopFacility fromFacility = fromStop.getStopFacility(); TransitStopFacility toFacility = toStop.getStopFacility(); @@ -137,13 +156,15 @@ private Link createAndAddLink(Tuple connection) { Node fromNode = connection.getFirst(); Node toNode = connection.getSecond(); Link link; - link = this.network.getFactory().createLink(Id.createLinkId(this.prefix + fromNode.getId() + "-" + toNode.getId()), fromNode, - toNode); - link.setLength(CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord())); + link = this.network.getFactory().createLink(Id.createLinkId(fromNode.getId() + "-" + toNode.getId()), + fromNode, toNode); + double dist = CoordUtils.calcEuclideanDistance(fromNode.getCoord(), toNode.getCoord()); + link.setLength(dist); link.setFreespeed(linkFreeSpeed); link.setCapacity(linkCapacity); link.setNumberOfLanes(1); + this.network.addLink(link); link.setAllowedModes(this.transitModes); this.links.put(connection, link); diff --git a/matsim/src/test/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinksTest.java b/matsim/src/test/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinksTest.java new file mode 100644 index 00000000000..431c0c87bcd --- /dev/null +++ b/matsim/src/test/java/org/matsim/pt/utils/CreatePseudoNetworkWithLoopLinksTest.java @@ -0,0 +1,28 @@ +package org.matsim.pt.utils; + +import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.scenario.ScenarioUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +class CreatePseudoNetworkWithLoopLinksTest { + + @Test + void createValidSchedule() { + + Scenario scenario = ScenarioUtils.loadScenario(ConfigUtils.loadConfig("test/scenarios/pt-tutorial/0.config.xml")); + + CreatePseudoNetworkWithLoopLinks creator = new CreatePseudoNetworkWithLoopLinks(scenario.getTransitSchedule(), scenario.getNetwork(), "pt_"); + creator.createNetwork(); + + + TransitScheduleValidator.ValidationResult result = TransitScheduleValidator.validateAll(scenario.getTransitSchedule(), scenario.getNetwork()); + + assertThat(result.getWarnings()).isEmpty(); + assertThat(result.getErrors()).isEmpty(); + assertThat(result.isValid()).isTrue(); + + } +} diff --git a/matsim/src/test/java/org/matsim/testcases/MatsimTestUtils.java b/matsim/src/test/java/org/matsim/testcases/MatsimTestUtils.java index 287858329cb..4432063a364 100644 --- a/matsim/src/test/java/org/matsim/testcases/MatsimTestUtils.java +++ b/matsim/src/test/java/org/matsim/testcases/MatsimTestUtils.java @@ -31,8 +31,8 @@ import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.utils.io.IOUtils; import org.matsim.core.utils.misc.CRCChecksum; -import org.matsim.utils.eventsfilecomparison.EventsFileComparator; import org.matsim.utils.eventsfilecomparison.ComparisonResult; +import org.matsim.utils.eventsfilecomparison.EventsFileComparator; import java.io.BufferedReader; import java.io.File; @@ -41,6 +41,9 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.Objects; /** @@ -51,6 +54,11 @@ public final class MatsimTestUtils implements BeforeEachCallback, AfterEachCallback { private static final Logger log = LogManager.getLogger(MatsimTestUtils.class); + //used for copying files from output to input. Don't delete even if they are unused in production + public static final String FILE_NAME_PLANS = "output_plans.xml.gz"; + public static final String FILE_NAME_NETWORK = "output_network.xml.gz"; + public static final String FILE_NAME_EVENTS = "output_events.xml.gz"; + public enum TestMethodType { Normal, Parameterized } @@ -60,12 +68,16 @@ public enum TestMethodType { */ public static final double EPSILON = 1e-10; - /** The default output directory, where files of this test should be written to. - * Includes the trailing '/' to denote a directory. */ + /** + * The default output directory, where files of this test should be written to. + * Includes the trailing '/' to denote a directory. + */ private String outputDirectory = null; - /** The default input directory, where files of this test should be read from. - * Includes the trailing '/' to denote a directory. */ + /** + * The default input directory, where files of this test should be read from. + * Includes the trailing '/' to denote a directory. + */ private String inputDirectory = null; /** @@ -144,7 +156,7 @@ public URL packageInputResourcePath() { private URL getResourceNotNull(String pathString) { URL resource = this.testClass.getResource(pathString); if (resource == null) { - throw new UncheckedIOException(new IOException("Not found: "+pathString)); + throw new UncheckedIOException(new IOException("Not found: " + pathString)); } return resource; } @@ -171,7 +183,8 @@ public Config createConfig(URL context) { /** * Loads a configuration from file (or the default config if configfile is null) - * and sets the output directory to {classPath}/{methodName}/. For parameterized tests, the output directory is {classPath}/{methodName}/{parameters}/. + * and sets the output directory to {classPath}/{methodName}/. For parameterized tests, the output directory is {classPath}/{methodName}/{ + * parameters}/. * * @param configfile The path/filename of a configuration file, or null to load the default configuration. * @return The loaded configuration. @@ -181,7 +194,7 @@ public Config loadConfig(final String configfile, TestMethodType testMethodType, if (configfile != null) { config = ConfigUtils.loadConfig(configfile, customGroups); } else { - config = ConfigUtils.createConfig( customGroups ); + config = ConfigUtils.createConfig(customGroups); } return setOutputDirectory(config, testMethodType); } @@ -195,7 +208,7 @@ public Config loadConfig(final URL configfile, TestMethodType testMethodType, fi if (configfile != null) { config = ConfigUtils.loadConfig(configfile, customGroups); } else { - config = ConfigUtils.createConfig( customGroups ); + config = ConfigUtils.createConfig(customGroups); } return setOutputDirectory(config, testMethodType); } @@ -226,7 +239,7 @@ public String getParameterizedTestInputString() { } public Config createConfig(final ConfigGroup... customGroups) { - Config config = ConfigUtils.createConfig( customGroups ); + Config config = ConfigUtils.createConfig(customGroups); this.outputDirectory = getOutputDirectory(); config.controller().setOutputDirectory(this.outputDirectory); return config; @@ -254,7 +267,7 @@ public String getOutputDirectory() { public String getOutputDirectory(String subDir) { if (this.outputDirectory == null) { - this.outputDirectory = "test/output/" + this.testClass.getCanonicalName().replace('.', '/') + "/" + getMethodName()+ "/" + subDir; + this.outputDirectory = "test/output/" + this.testClass.getCanonicalName().replace('.', '/') + "/" + getMethodName() + "/" + subDir; } createOutputDirectory(); return this.outputDirectory; @@ -271,18 +284,20 @@ public String getInputDirectory() { } return this.inputDirectory; } + /** - * Returns the path to the input directory one level above the default input directory for this test including a trailing slash as directory delimiter. + * Returns the path to the input directory one level above the default input directory for this test including a trailing slash as directory + * delimiter. * * @return path to the input directory for this test */ public String getClassInputDirectory() { if (this.classInputDirectory == null) { - LogManager.getLogger(this.getClass()).info( "user.dir = " + System.getProperty("user.dir") ) ; + LogManager.getLogger(this.getClass()).info("user.dir = " + System.getProperty("user.dir")); this.classInputDirectory = "test/input/" + - this.testClass.getCanonicalName().replace('.', '/') + "/"; + this.testClass.getCanonicalName().replace('.', '/') + "/"; // this.classInputDirectory = System.getProperty("user.dir") + "/test/input/" + // this.testClass.getCanonicalName().replace('.', '/') + "/"; // (this used to be relative, i.e. ... = "test/input/" + ... . Started failing when @@ -292,8 +307,10 @@ public String getClassInputDirectory() { } return this.classInputDirectory; } + /** - * Returns the path to the input directory two levels above the default input directory for this test including a trailing slash as directory delimiter. + * Returns the path to the input directory two levels above the default input directory for this test including a trailing slash as directory + * delimiter. * * @return path to the input directory for this test */ @@ -321,7 +338,7 @@ public String getMethodName() { * This should be used for "fixtures" only that provide a scenario common to several * test cases. */ - public void initWithoutJUnitForFixture(Class fixture, Method method){ + public void initWithoutJUnitForFixture(Class fixture, Method method) { this.testClass = fixture; this.testMethodName = method.getName(); } @@ -333,27 +350,62 @@ public static void assertEqualFilesLineByLine(String inputFilename, String outpu String lineInput; String lineOutput; - while( ((lineInput = readerV1Input.readLine()) != null) && ((lineOutput = readerV1Output.readLine()) != null) ){ - if ( !Objects.equals( lineInput.trim(), lineOutput.trim() ) ){ - log.info( "Reading line... " ); - log.info( lineInput ); - log.info( lineOutput ); - log.info( "" ); + while (((lineInput = readerV1Input.readLine()) != null) && ((lineOutput = readerV1Output.readLine()) != null)) { + if (!Objects.equals(lineInput.trim(), lineOutput.trim())) { + log.info("Reading line... "); + log.info(lineInput); + log.info(lineOutput); + log.info(""); } - Assertions.assertEquals(lineInput.trim(), lineOutput.trim(), "Lines have different content: " ); + Assertions.assertEquals(lineInput.trim(), lineOutput.trim(), "Lines have different content: "); } } catch (IOException e) { throw new UncheckedIOException(e); } } - public static void assertEqualEventsFiles( String filename1, String filename2 ) { - Assertions.assertEquals(ComparisonResult.FILES_ARE_EQUAL ,EventsFileComparator.compare(filename1, filename2) ); + public static void assertEqualEventsFiles(String filename1, String filename2) { + Assertions.assertEquals(ComparisonResult.FILES_ARE_EQUAL, EventsFileComparator.compare(filename1, filename2)); + } + + public static void assertEqualFilesBasedOnCRC(String filename1, String filename2) { + long checksum1 = CRCChecksum.getCRCFromFile(filename1); + long checksum2 = CRCChecksum.getCRCFromFile(filename2); + Assertions.assertEquals(checksum1, checksum2, "different file checksums"); + } + + /** + * Creates the input directory for this test. + */ + public void createInputDirectory() { + try { + Files.createDirectories(Path.of(getInputDirectory())); + } catch (IOException e) { + e.printStackTrace(); + Assertions.fail(); + } + } + + /** + * Copies a file from the output directory to the input directory. This is normally only needed during development, if one would not do it + * manually. + */ + public void copyFileFromOutputToInput(String fileName) { + createInputDirectory(); + copyFileFromOutputToInput(fileName, fileName); } - public static void assertEqualFilesBasedOnCRC( String filename1, String filename2 ) { - long checksum1 = CRCChecksum.getCRCFromFile(filename1) ; - long checksum2 = CRCChecksum.getCRCFromFile(filename2) ; - Assertions.assertEquals( checksum1, checksum2, "different file checksums" ); - } + /** + * Copies a file from the output directory to the input directory. This is normally only needed during development, if one would not do it + * manually. + */ + public void copyFileFromOutputToInput(String outputFile, String inputFile) { + createInputDirectory(); + try { + Files.copy(Path.of(getOutputDirectory() + outputFile), Path.of(getInputDirectory() + inputFile), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + e.printStackTrace(); + Assertions.fail(); + } + } }