From 8848007d28a812b1d48613f0d1ad2744463b3223 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 12:04:40 +0200 Subject: [PATCH 01/13] remove not needed (and already deprecated) calls --- .../initialPlans/ExampleSchedulingOfTransportChain.java | 3 --- .../logisticChainElementTests/DistributionElementTest.java | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/initialPlans/ExampleSchedulingOfTransportChain.java b/src/main/java/org/matsim/freight/logistics/examples/initialPlans/ExampleSchedulingOfTransportChain.java index 65650829..533ed60e 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/initialPlans/ExampleSchedulingOfTransportChain.java +++ b/src/main/java/org/matsim/freight/logistics/examples/initialPlans/ExampleSchedulingOfTransportChain.java @@ -72,7 +72,6 @@ private static LSP createInitialLSP(Scenario scenario) { CarrierVehicle.newInstance(vollectionVehicleId, collectionLinkId, collectionType); CarrierCapabilities.Builder capabilitiesBuilder = CarrierCapabilities.Builder.newInstance(); - capabilitiesBuilder.addType(collectionType); capabilitiesBuilder.addVehicle(carrierVehicle); capabilitiesBuilder.setFleetSize(FleetSize.INFINITE); CarrierCapabilities capabilities = capabilitiesBuilder.build(); @@ -142,7 +141,6 @@ private static LSP createInitialLSP(Scenario scenario) { CarrierCapabilities mainRunCapabilities = CarrierCapabilities.Builder.newInstance() - .addType(mainRunType) .addVehicle(mainRunCarrierVehicle) .setFleetSize(FleetSize.INFINITE) .build(); @@ -210,7 +208,6 @@ private static LSP createInitialLSP(Scenario scenario) { CarrierCapabilities.Builder distributionCapabilitiesBuilder = CarrierCapabilities.Builder.newInstance(); - distributionCapabilitiesBuilder.addType(distributionType); distributionCapabilitiesBuilder.addVehicle(distributionCarrierVehicle); distributionCapabilitiesBuilder.setFleetSize(FleetSize.INFINITE); CarrierCapabilities distributionCapabilities = distributionCapabilitiesBuilder.build(); diff --git a/src/test/java/org/matsim/freight/logistics/logisticChainElementTests/DistributionElementTest.java b/src/test/java/org/matsim/freight/logistics/logisticChainElementTests/DistributionElementTest.java index 8c191da9..3c9a923f 100644 --- a/src/test/java/org/matsim/freight/logistics/logisticChainElementTests/DistributionElementTest.java +++ b/src/test/java/org/matsim/freight/logistics/logisticChainElementTests/DistributionElementTest.java @@ -70,7 +70,6 @@ public void initialize() { CarrierVehicle carrierVehicle = CarrierVehicle.newInstance(distributionVehicleId, distributionLinkId, distributionType); CarrierCapabilities.Builder capabilitiesBuilder = CarrierCapabilities.Builder.newInstance(); - capabilitiesBuilder.addType(distributionType); capabilitiesBuilder.addVehicle(carrierVehicle); capabilitiesBuilder.setFleetSize(FleetSize.INFINITE); CarrierCapabilities capabilities = capabilitiesBuilder.build(); From 21c23bdb15f4123a0c39cf73de6333494d3f0c0d Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 14:08:20 +0200 Subject: [PATCH 02/13] also sum up jspritScore of auxiliary carriers --- .../CarrierSchedulerUtils.java | 15 +++++++++++++++ .../DistributionCarrierScheduler.java | 1 + 2 files changed, 16 insertions(+) diff --git a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java index 88ec931e..95efc31b 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java @@ -117,4 +117,19 @@ public static Double sumUpScore(List scheduledPlans) { } return score; } + + /** + * Sum up the jsprit score of the given list of CarrierPlans. + * As a consequence this is not from the one and only jsprit run, but from all jsprit runs af the different auxiliary carriers. + * @param scheduledPlans + * @return the summ of the scores coming from jsprit + */ + public static Double sumUpJspritScore(List scheduledPlans) { + double jspritScore = 0; + for (CarrierPlan scheduledPlan : scheduledPlans) { + if (scheduledPlan.getJspritScore() != null) { + jspritScore = jspritScore + scheduledPlan.getJspritScore(); } + } + return jspritScore; + } } diff --git a/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java b/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java index a31c2fad..f73b0c35 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java @@ -116,6 +116,7 @@ protected void scheduleResource() { CarrierPlan plan = new CarrierPlan(carrier, unifyTourIds(scheduledPlans)); plan.setScore(CarrierSchedulerUtils.sumUpScore(scheduledPlans)); + plan.setJspritScore(CarrierSchedulerUtils.sumUpJspritScore(scheduledPlans)); carrier.setSelectedPlan(plan); } From ddd8c28d7219da6cc0de0bade79dd99674ae01bc Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 14:10:40 +0200 Subject: [PATCH 03/13] WORKAROUND: pass rpScheme through to VRP solving. --- .../CollectionCarrierScheduler.java | 16 +++++++++++++- .../DistributionCarrierScheduler.java | 18 ++++++++++++++-- .../ResourceImplementationUtils.java | 21 +++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java index 9e0fbf96..cfa38213 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import org.matsim.api.core.v01.Id; +import org.matsim.contrib.roadpricing.RoadPricingScheme; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierService; import org.matsim.freight.carriers.ScheduledTour; @@ -46,11 +47,24 @@ private Carrier carrier; private CollectionCarrierResource resource; private ArrayList pairs; + private RoadPricingScheme rpscheme = null; CollectionCarrierScheduler() { this.pairs = new ArrayList<>(); } + /** + * Constructor for the CollectionCarrierScheduler. + * TODO: In the future, the road pricing scheme should come from some the scenario: RoadPricingUtils.getRoadPricingScheme(scenario). This here is only a dirty workaround. KMT'Aug'24 + * @deprecated This is only a dirty workaround. KMT'Aug'24 + * @param rpscheme the road pricing scheme + */ + @Deprecated + CollectionCarrierScheduler(RoadPricingScheme rpscheme) { + this.pairs = new ArrayList<>(); + this.rpscheme = rpscheme; + } + @Override public void initializeValues(LSPResource resource) { this.pairs = new ArrayList<>(); @@ -69,7 +83,7 @@ public void scheduleResource() { CarrierService carrierService = convertToCarrierService(tupleToBeAssigned); carrier.getServices().put(carrierService.getId(), carrierService); } - carrier = CarrierSchedulerUtils.solveVrpWithJspritWithToll(carrier, resource.getNetwork(), null); + carrier = CarrierSchedulerUtils.solveVrpWithJspritWithToll(carrier, resource.getNetwork(), rpscheme); } private CarrierService convertToCarrierService(LspShipmentWithTime tuple) { diff --git a/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java b/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java index f73b0c35..939ef5f6 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java @@ -27,6 +27,7 @@ import java.util.List; import org.locationtech.jts.util.Assert; import org.matsim.api.core.v01.Id; +import org.matsim.contrib.roadpricing.RoadPricingScheme; import org.matsim.freight.carriers.*; import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; import org.matsim.freight.carriers.Tour.Leg; @@ -52,11 +53,24 @@ private DistributionCarrierResource resource; private ArrayList pairs; private int carrierCnt = 1; + private RoadPricingScheme rpscheme = null; DistributionCarrierScheduler() { this.pairs = new ArrayList<>(); } + /** + * Constructor for the DistributionCarrierScheduler. + * TODO: In the future, the road pricing scheme should come from some the scenario: RoadPricingUtils.getRoadPricingScheme(scenario). This here is only a dirty workaround. KMT'Aug'24 + * @deprecated This is only a dirty workaround. KMT'Aug'24 + * @param rpscheme the road pricing scheme + */ + @Deprecated + DistributionCarrierScheduler(RoadPricingScheme rpscheme) { + this.pairs = new ArrayList<>(); + this.rpscheme = rpscheme; + } + @Override protected void initializeValues(LSPResource resource) { this.pairs = new ArrayList<>(); @@ -91,7 +105,7 @@ protected void scheduleResource() { CarrierSchedulerUtils.solveVrpWithJspritWithToll( createAuxiliaryCarrier( shipmentsInCurrentTour, availabilityTimeOfLastShipment + cumulatedLoadingTime), - resource.getNetwork(), null); + resource.getNetwork(), rpscheme); scheduledPlans.add(auxiliaryCarrier.getSelectedPlan()); carrier.getServices().putAll(auxiliaryCarrier.getServices()); cumulatedLoadingTime = 0; @@ -108,7 +122,7 @@ protected void scheduleResource() { CarrierSchedulerUtils.solveVrpWithJspritWithToll( createAuxiliaryCarrier( shipmentsInCurrentTour, availabilityTimeOfLastShipment + cumulatedLoadingTime), - resource.getNetwork(), null); + resource.getNetwork(), rpscheme); scheduledPlans.add(auxiliaryCarrier.getSelectedPlan()); carrier.getServices().putAll(auxiliaryCarrier.getServices()); shipmentsInCurrentTour.clear(); diff --git a/src/main/java/org/matsim/freight/logistics/resourceImplementations/ResourceImplementationUtils.java b/src/main/java/org/matsim/freight/logistics/resourceImplementations/ResourceImplementationUtils.java index d6a581b0..9c69547d 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/ResourceImplementationUtils.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/ResourceImplementationUtils.java @@ -29,6 +29,7 @@ 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.roadpricing.RoadPricingScheme; import org.matsim.core.utils.io.IOUtils; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierVehicle; @@ -221,6 +222,26 @@ public static CollectionCarrierScheduler createDefaultCollectionCarrierScheduler return new CollectionCarrierScheduler(); } + /** + * Utils method to create a DistributionCarrierScheduler with Roadpricing. + * TODO: In the future, the road pricing scheme should come from some the scenario: RoadPricingUtils.getRoadPricingScheme(scenario). This here is only a dirty workaround. KMT'Aug'24 + * @deprecated This is only a dirty workaround. KMT'Aug'24 + * @param roadPricingScheme the road pricing scheme + */ + public static DistributionCarrierScheduler createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingScheme roadPricingScheme) { + return new DistributionCarrierScheduler(roadPricingScheme); + } + + /** + * Utils method to create a Collection CarrierScheduler with Roadpricing. + * TODO: In the future, the road pricing scheme should come from some the scenario: RoadPricingUtils.getRoadPricingScheme(scenario). This here is only a dirty workaround. KMT'Aug'24 + * @deprecated This is only a dirty workaround. KMT'Aug'24 + * @param roadPricingScheme the road pricing scheme + */ + public static CollectionCarrierScheduler createDefaultCollectionCarrierSchedulerWithRoadPricing(RoadPricingScheme roadPricingScheme) { + return new CollectionCarrierScheduler(roadPricingScheme); + } + public static MainRunCarrierScheduler createDefaultMainRunCarrierScheduler() { return new MainRunCarrierScheduler(); } From 034b2feeeabcde809bcc1ac3ba06b709c2fc811c Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 14:11:20 +0200 Subject: [PATCH 04/13] comments --- .../EventBasedCarrierScorer4MultipleChains.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java index 7ac9c337..9e7c1b70 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java @@ -46,17 +46,13 @@ */ class EventBasedCarrierScorer4MultipleChains implements CarrierScoringFunctionFactory { - - @Inject private Network network; - @Inject private Scenario scenario; private double toll; private List tolledVehicleTypes = new ArrayList<>(); private List tolledLinks = new ArrayList<>(); - public ScoringFunction createScoringFunction(Carrier carrier) { SumScoringFunction sf = new SumScoringFunction(); sf.addScoringFunction(new EventBasedScoring()); @@ -119,7 +115,7 @@ private void handleEvent(CarrierTourStartEvent event) { tourStartTime.put(event.getTourId(), event.getTime()); } - // Fix costs for vehicle usage + // scores fix costs for vehicle usage and variable costs per time private void handleEvent(CarrierTourEndEvent event) { // Fix costs for vehicle usage final VehicleType vehicleType = @@ -134,6 +130,7 @@ private void handleEvent(CarrierTourEndEvent event) { score = score - (tourDuration * vehicleType.getCostInformation().getCostsPerSecond()); } + // scores variable costs per distance private void handleEvent(LinkEnterEvent event) { final double distance = network.getLinks().get(event.getLinkId()).getLength(); final double costPerMeter = From 81ee1c52668f2f348864e2210b9d97540062c5f7 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 15:14:54 +0200 Subject: [PATCH 05/13] add two EventsHandler to build connections between driver - vehicle - carrier --- .../analysis/Driver2VehicleEventHandler.java | 62 ++++++++++++++++++ .../analysis/Vehicle2CarrierEventHandler.java | 64 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java create mode 100644 src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java diff --git a/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java b/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java new file mode 100644 index 00000000..340290bf --- /dev/null +++ b/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java @@ -0,0 +1,62 @@ +/* + *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2024 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.freight.logistics.analysis; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; +import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent; +import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler; +import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler; +import org.matsim.api.core.v01.population.Person; +import org.matsim.vehicles.Vehicle; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class Driver2VehicleEventHandler implements VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler { + + private final Map, Id> driversVehicles = new ConcurrentHashMap<>(); + + @Override + public void reset(int iteration) { + driversVehicles.clear(); + } + + @Override + public void handleEvent(VehicleEntersTrafficEvent event) { + driversVehicles.put(event.getPersonId(), event.getVehicleId()); + } + + @Override + public void handleEvent(VehicleLeavesTrafficEvent event) { + driversVehicles.remove(event.getPersonId()); + } + + /** + * @param personId the unique driver identifier. + * @return vehicle id of the driver's vehicle + */ + public Id getVehicleOfDriver(Id personId) { + return driversVehicles.get(personId); + } + +} diff --git a/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java b/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java new file mode 100644 index 00000000..d310e02f --- /dev/null +++ b/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java @@ -0,0 +1,64 @@ +/* + *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2024 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.freight.logistics.analysis; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; +import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent; +import org.matsim.api.core.v01.population.Person; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.events.CarrierTourEndEvent; +import org.matsim.freight.carriers.events.CarrierTourStartEvent; +import org.matsim.freight.carriers.events.eventhandler.CarrierTourEndEventHandler; +import org.matsim.freight.carriers.events.eventhandler.CarrierTourStartEventHandler; +import org.matsim.vehicles.Vehicle; + +public class Vehicle2CarrierEventHandler implements CarrierTourStartEventHandler, CarrierTourEndEventHandler { + + private final Map, Id> vehicle2carrier = new ConcurrentHashMap<>(); + + @Override + public void reset(int iteration) { + vehicle2carrier.clear(); + } + + @Override + public void handleEvent(CarrierTourStartEvent event) { + vehicle2carrier.put(event.getVehicleId(), event.getCarrierId()); + } + + @Override + public void handleEvent(CarrierTourEndEvent event) { + vehicle2carrier.remove(event.getVehicleId()); + } + + /** + * @param vehicleId the unique vehicle Id + * @return id of the vehicle's carrier + */ + public Id getCarrierOfVehicle(Id vehicleId) { + return vehicle2carrier.get(vehicleId); + } + +} From 7bc3251ee515d28e353d20fca027aef1bf672dea Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 16:10:04 +0200 Subject: [PATCH 06/13] use toll scheme --- ...eTwoLspsGroceryDeliveryMultipleChainsWithToll.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java index 4277b034..0f6e0b95 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java @@ -74,7 +74,7 @@ final class ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll { private static final String EDEKA_SUPERMARKT_TROCKEN = "edeka_SUPERMARKT_TROCKEN"; private static final String KAUFLAND_VERBRAUCHERMARKT_TROCKEN = "kaufland_VERBRAUCHERMARKT_TROCKEN"; - private static final String OUTPUT_DIRECTORY = "output/groceryDelivery_kmt_10_toll"; + private static final String OUTPUT_DIRECTORY = "output/groceryDelivery_kmt_10_tollb_1000newTollScoring"; private ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll() {} @@ -97,6 +97,8 @@ public static void main(String[] args) { Carrier carrierEdeka = carriers.getCarriers().get(Id.create(EDEKA_SUPERMARKT_TROCKEN, CarrierImpl.class)); Carrier carrierKaufland = carriers.getCarriers().get(Id.create(KAUFLAND_VERBRAUCHERMARKT_TROCKEN, CarrierImpl.class)); + RoadPricingScheme rpScheme = setUpRoadpricing(scenario); + log.info("Add LSP(s) to the scenario"); Collection lsps = new LinkedList<>(); lsps.add(createLspWithTwoChains(scenario, "Edeka", MultipleChainsUtils.createLSPShipmentsFromCarrierShipments(carrierEdeka), getDepotLinkFromVehicle(carrierEdeka), HUB_LINK_ID_NEUKOELLN, vehicleTypes, vehicleTypes, vehicleTypes)); @@ -106,7 +108,6 @@ public static void main(String[] args) { LSPUtils.addLSPs(scenario, new LSPs(lsps)); - RoadPricingSchemeUsingTollFactor rpScheme = setUpRoadpricing(scenario); log.info("Prepare controler"); @@ -367,7 +368,8 @@ private static LogisticChain createTwoEchelonChain(Scenario scenario, String lsp ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( distributionCarrier, scenario.getNetwork()) .setDistributionScheduler( - ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) + ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) +// ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) .build(); LogisticChainElement distributionCarrierElement = @@ -439,7 +441,8 @@ private static LogisticChain createDirectChain(Scenario scenario, String lspName ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( directCarrier, scenario.getNetwork()) .setDistributionScheduler( - ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) + ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) +// ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) .build(); LogisticChainElement singleCarrierElement = From d51941d62fe8c06e3ec12772d6faeb897d1491a7 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 16:12:07 +0200 Subject: [PATCH 07/13] toll scoring also from events. Some tests may fail, because now each entry to the toll zone is now taken into account. -> Maybe add an option to decide if toll is only once per vehicle or not... --- ...ventBasedCarrierScorer4MultipleChains.java | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java index 9e7c1b70..59195af5 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java @@ -27,16 +27,18 @@ 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.events.Event; -import org.matsim.api.core.v01.events.LinkEnterEvent; +import org.matsim.api.core.v01.events.*; import org.matsim.api.core.v01.network.Network; import org.matsim.core.scoring.ScoringFunction; import org.matsim.core.scoring.SumScoringFunction; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.Tour; +import org.matsim.freight.carriers.controler.CarrierAgentTracker; import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; import org.matsim.freight.carriers.events.CarrierTourEndEvent; import org.matsim.freight.carriers.events.CarrierTourStartEvent; +import org.matsim.freight.logistics.analysis.Driver2VehicleEventHandler; +import org.matsim.freight.logistics.analysis.Vehicle2CarrierEventHandler; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; @@ -49,14 +51,17 @@ class EventBasedCarrierScorer4MultipleChains implements CarrierScoringFunctionFa @Inject private Network network; @Inject private Scenario scenario; + private double toll; private List tolledVehicleTypes = new ArrayList<>(); private List tolledLinks = new ArrayList<>(); + private Id carrierId; public ScoringFunction createScoringFunction(Carrier carrier) { + this.carrierId = carrier.getId(); SumScoringFunction sf = new SumScoringFunction(); sf.addScoringFunction(new EventBasedScoring()); - sf.addScoringFunction(new LinkBasedTollScoring(toll, tolledVehicleTypes, tolledLinks)); +// sf.addScoringFunction(new LinkBasedTollScoring(toll, tolledVehicleTypes, tolledLinks)); return sf; } @@ -80,10 +85,9 @@ void setTolledLinks(List tolledLinks) { private class EventBasedScoring implements SumScoringFunction.ArbitraryEventScoring { final Logger log = LogManager.getLogger(EventBasedScoring.class); - private final double MAX_SHIFT_DURATION = 8 * 3600; - private final Map vehicleType2TourDuration = new LinkedHashMap<>(); - private final Map vehicleType2ScoredFixCosts = new LinkedHashMap<>(); private final Map, Double> tourStartTime = new LinkedHashMap<>(); + private final Driver2VehicleEventHandler d2v = new Driver2VehicleEventHandler(); + private final Vehicle2CarrierEventHandler v2c = new Vehicle2CarrierEventHandler(); private double score; public EventBasedScoring() { @@ -101,22 +105,26 @@ public double getScore() { @Override public void handleEvent(Event event) { log.debug(event.toString()); - switch (event) { - case CarrierTourStartEvent freightTourStartEvent -> handleEvent(freightTourStartEvent); - case CarrierTourEndEvent freightTourEndEvent -> handleEvent(freightTourEndEvent); - case LinkEnterEvent linkEnterEvent -> handleEvent(linkEnterEvent); - default -> { - } - } + switch (event) { + case CarrierTourStartEvent carrierTourStartEvent -> handleEvent(carrierTourStartEvent); + case CarrierTourEndEvent carrierTourEndEvent -> handleEvent(carrierTourEndEvent); + case LinkEnterEvent linkEnterEvent -> handleEvent(linkEnterEvent); + case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); + case VehicleEntersTrafficEvent vehicleEntersTrafficEvent -> d2v.handleEvent(vehicleEntersTrafficEvent); + case VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent -> d2v.handleEvent(vehicleLeavesTrafficEvent); + default -> {} + } } private void handleEvent(CarrierTourStartEvent event) { + v2c.handleEvent(event); // Save time of freight tour start tourStartTime.put(event.getTourId(), event.getTime()); } // scores fix costs for vehicle usage and variable costs per time private void handleEvent(CarrierTourEndEvent event) { + v2c.handleEvent(event); // Fix costs for vehicle usage final VehicleType vehicleType = (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType(); @@ -141,6 +149,17 @@ private void handleEvent(LinkEnterEvent event) { // variable costs per distance score = score - (distance * costPerMeter); } + + // scores tolls for vehicles driving on tolled links + private void handleEvent(PersonMoneyEvent event) { + double tollValue = 0; + if (event.getPurpose().equals("toll")) { + if (carrierId.equals(v2c.getCarrierOfVehicle(d2v.getVehicleOfDriver(event.getPersonId())))) { + tollValue = event.getAmount(); + } + } + score = score - tollValue; + } } /** @@ -183,15 +202,16 @@ private void handleEvent(LinkEnterEvent event) { final Id vehicleTypeId = (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType().getId(); - // toll a vehicle only once. - if (!tolledVehicles.contains(event.getVehicleId())) +// // toll a vehicle only once. +// if (!tolledVehicles.contains(event.getVehicleId())) { if (vehicleTypesToBeTolled.contains(vehicleTypeId.toString())) { if (tolledLinkList.contains(event.getLinkId().toString())) { log.info("Tolling caused by event: {}", event); - tolledVehicles.add(event.getVehicleId()); +// tolledVehicles.add(event.getVehicleId()); score = score - toll; } } +// } } } } From 8148d390ba2e54ea453c936813e9a2c3dcb3f999 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 7 Aug 2024 16:15:04 +0200 Subject: [PATCH 08/13] javadoc --- .../analysis/Driver2VehicleEventHandler.java | 10 ++++++++++ .../analysis/Vehicle2CarrierEventHandler.java | 13 ++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java b/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java index 340290bf..5cfde304 100644 --- a/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java +++ b/src/main/java/org/matsim/freight/logistics/analysis/Driver2VehicleEventHandler.java @@ -32,6 +32,16 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +/** + * Basic event handler that collects the relation between vehicles and drivers. + * Necessary since link enter and leave events do not contain the driver anymore. + *

+ * This is the vice-versa implementation of {@link org.matsim.core.events.algorithms.Vehicle2DriverEventHandler}. + *

+ * In a first step only used internally. When needed more often, I have nothing against putting it more central. -> matsim-libs + * + * @author kturner + */ public class Driver2VehicleEventHandler implements VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler { private final Map, Id> driversVehicles = new ConcurrentHashMap<>(); diff --git a/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java b/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java index d310e02f..d7230ab3 100644 --- a/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java +++ b/src/main/java/org/matsim/freight/logistics/analysis/Vehicle2CarrierEventHandler.java @@ -24,9 +24,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; -import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent; -import org.matsim.api.core.v01.population.Person; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.events.CarrierTourEndEvent; import org.matsim.freight.carriers.events.CarrierTourStartEvent; @@ -34,6 +31,16 @@ import org.matsim.freight.carriers.events.eventhandler.CarrierTourStartEventHandler; import org.matsim.vehicles.Vehicle; +/** + * Basic event handler that collects the relation between vehicles and carrier. + * Necessary since there is no event having all this information together. + *

+ * This is a modified implementation of {@link org.matsim.core.events.algorithms.Vehicle2DriverEventHandler}. + *

+ * In a first step only used internally. When needed more often, I have nothing against putting it more central. -> matsim-libs + * + * @author kturner + */ public class Vehicle2CarrierEventHandler implements CarrierTourStartEventHandler, CarrierTourEndEventHandler { private final Map, Id> vehicle2carrier = new ConcurrentHashMap<>(); From 4bf50a23d48e865ebcb78d93218ac3fcf51e35e5 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Thu, 8 Aug 2024 11:15:11 +0200 Subject: [PATCH 09/13] reset old scorer and use another class for score tolls via personMoneyEvents --- ...ventBasedCarrierScorer4MultipleChains.java | 30 +--- ...dCarrierScorer4MultipleChainsInclToll.java | 155 ++++++++++++++++++ ...GroceryDeliveryMultipleChainsWithToll.java | 7 +- 3 files changed, 162 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java index 59195af5..f1820a38 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java @@ -29,11 +29,11 @@ import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.events.*; import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; import org.matsim.core.scoring.ScoringFunction; import org.matsim.core.scoring.SumScoringFunction; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.Tour; -import org.matsim.freight.carriers.controler.CarrierAgentTracker; import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; import org.matsim.freight.carriers.events.CarrierTourEndEvent; import org.matsim.freight.carriers.events.CarrierTourStartEvent; @@ -61,7 +61,7 @@ public ScoringFunction createScoringFunction(Carrier carrier) { this.carrierId = carrier.getId(); SumScoringFunction sf = new SumScoringFunction(); sf.addScoringFunction(new EventBasedScoring()); -// sf.addScoringFunction(new LinkBasedTollScoring(toll, tolledVehicleTypes, tolledLinks)); + sf.addScoringFunction(new LinkBasedTollScoring(toll, tolledVehicleTypes, tolledLinks)); return sf; } @@ -86,8 +86,6 @@ private class EventBasedScoring implements SumScoringFunction.ArbitraryEventScor final Logger log = LogManager.getLogger(EventBasedScoring.class); private final Map, Double> tourStartTime = new LinkedHashMap<>(); - private final Driver2VehicleEventHandler d2v = new Driver2VehicleEventHandler(); - private final Vehicle2CarrierEventHandler v2c = new Vehicle2CarrierEventHandler(); private double score; public EventBasedScoring() { @@ -109,22 +107,17 @@ public void handleEvent(Event event) { case CarrierTourStartEvent carrierTourStartEvent -> handleEvent(carrierTourStartEvent); case CarrierTourEndEvent carrierTourEndEvent -> handleEvent(carrierTourEndEvent); case LinkEnterEvent linkEnterEvent -> handleEvent(linkEnterEvent); - case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); - case VehicleEntersTrafficEvent vehicleEntersTrafficEvent -> d2v.handleEvent(vehicleEntersTrafficEvent); - case VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent -> d2v.handleEvent(vehicleLeavesTrafficEvent); default -> {} } } private void handleEvent(CarrierTourStartEvent event) { - v2c.handleEvent(event); // Save time of freight tour start tourStartTime.put(event.getTourId(), event.getTime()); } // scores fix costs for vehicle usage and variable costs per time private void handleEvent(CarrierTourEndEvent event) { - v2c.handleEvent(event); // Fix costs for vehicle usage final VehicleType vehicleType = (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType(); @@ -149,17 +142,6 @@ private void handleEvent(LinkEnterEvent event) { // variable costs per distance score = score - (distance * costPerMeter); } - - // scores tolls for vehicles driving on tolled links - private void handleEvent(PersonMoneyEvent event) { - double tollValue = 0; - if (event.getPurpose().equals("toll")) { - if (carrierId.equals(v2c.getCarrierOfVehicle(d2v.getVehicleOfDriver(event.getPersonId())))) { - tollValue = event.getAmount(); - } - } - score = score - tollValue; - } } /** @@ -202,16 +184,16 @@ private void handleEvent(LinkEnterEvent event) { final Id vehicleTypeId = (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType().getId(); -// // toll a vehicle only once. -// if (!tolledVehicles.contains(event.getVehicleId())) { + // toll a vehicle only once. + if (!tolledVehicles.contains(event.getVehicleId())) { if (vehicleTypesToBeTolled.contains(vehicleTypeId.toString())) { if (tolledLinkList.contains(event.getLinkId().toString())) { log.info("Tolling caused by event: {}", event); -// tolledVehicles.add(event.getVehicleId()); + tolledVehicles.add(event.getVehicleId()); score = score - toll; } } -// } + } } } } diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java new file mode 100644 index 00000000..652e82b6 --- /dev/null +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java @@ -0,0 +1,155 @@ +/* + *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2024 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.freight.logistics.examples.multipleChains; + +import com.google.inject.Inject; +import java.util.*; +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.events.*; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; +import org.matsim.core.scoring.ScoringFunction; +import org.matsim.core.scoring.SumScoringFunction; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Tour; +import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; +import org.matsim.freight.carriers.events.CarrierTourEndEvent; +import org.matsim.freight.carriers.events.CarrierTourStartEvent; +import org.matsim.freight.logistics.analysis.Driver2VehicleEventHandler; +import org.matsim.freight.logistics.analysis.Vehicle2CarrierEventHandler; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; + +/** + * @author Kai Martins-Turner (kturner) + */ +class EventBasedCarrierScorer4MultipleChainsInclToll implements CarrierScoringFunctionFactory { + + @Inject private Network network; + @Inject private Scenario scenario; + + private Id carrierId; + + public ScoringFunction createScoringFunction(Carrier carrier) { + this.carrierId = carrier.getId(); + SumScoringFunction sf = new SumScoringFunction(); + sf.addScoringFunction(new EventBasedScoring()); + return sf; + } + + /** + * Calculate the carrier's score based on Events. Currently, it includes: - fixed costs (using + * CarrierTourEndEvent) - time-dependent costs (using FreightTourStart- and -EndEvent) - + * distance-dependent costs (using LinkEnterEvent) + * tolls (using PersonMoneyEvent) + */ + private class EventBasedScoring implements SumScoringFunction.ArbitraryEventScoring { + + final Logger log = LogManager.getLogger(EventBasedScoring.class); + private final Map, Double> tourStartTime = new LinkedHashMap<>(); + private final Driver2VehicleEventHandler d2v = new Driver2VehicleEventHandler(); + private final Vehicle2CarrierEventHandler v2c = new Vehicle2CarrierEventHandler(); + private double score; + + public EventBasedScoring() { + super(); + } + + @Override + public void finish() {} + + @Override + public double getScore() { + return score; + } + + @Override + public void handleEvent(Event event) { + log.debug(event.toString()); + switch (event) { + case CarrierTourStartEvent carrierTourStartEvent -> handleEvent(carrierTourStartEvent); + case CarrierTourEndEvent carrierTourEndEvent -> handleEvent(carrierTourEndEvent); + case LinkEnterEvent linkEnterEvent -> handleEvent(linkEnterEvent); + case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); + case VehicleEntersTrafficEvent vehicleEntersTrafficEvent -> d2v.handleEvent(vehicleEntersTrafficEvent); + case VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent -> d2v.handleEvent(vehicleLeavesTrafficEvent); + default -> {} + } + } + + private void handleEvent(CarrierTourStartEvent event) { + v2c.handleEvent(event); + // Save time of freight tour start + tourStartTime.put(event.getTourId(), event.getTime()); + } + + // scores fix costs for vehicle usage and variable costs per time + private void handleEvent(CarrierTourEndEvent event) { + v2c.handleEvent(event); + // Fix costs for vehicle usage + final VehicleType vehicleType = + (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType(); + + double tourDuration = event.getTime() - tourStartTime.get(event.getTourId()); + + log.info("Score fixed costs for vehicle type: {}", vehicleType.getId().toString()); + score = score - vehicleType.getCostInformation().getFixedCosts(); + + // variable costs per time + score = score - (tourDuration * vehicleType.getCostInformation().getCostsPerSecond()); + } + + // scores variable costs per distance + private void handleEvent(LinkEnterEvent event) { + final double distance = network.getLinks().get(event.getLinkId()).getLength(); + final double costPerMeter = + (VehicleUtils.findVehicle(event.getVehicleId(), scenario)) + .getType() + .getCostInformation() + .getCostsPerMeter(); + // variable costs per distance + score = score - (distance * costPerMeter); + } + + private final List> tolledPersons = new ArrayList<>(); + + // scores tolls for vehicles driving on tolled links + private void handleEvent(PersonMoneyEvent event) { + double tollValue = 0; + + if (event.getPurpose().equals("toll")) { + if (carrierId.equals(v2c.getCarrierOfVehicle(d2v.getVehicleOfDriver(event.getPersonId())))) { +// toll a person only once. +// if (!tolledPersons.contains(event.getPersonId())) { +// tolledPersons.add(event.getPersonId()); + tollValue = event.getAmount(); +// } + } + } + score = score - tollValue; + } + } + +} diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java index 0f6e0b95..a4363b8f 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java @@ -124,12 +124,7 @@ public void install() { new AbstractModule() { @Override public void install() { - final EventBasedCarrierScorer4MultipleChains carrierScorer = - new EventBasedCarrierScorer4MultipleChains(); - carrierScorer.setToll(TOLL_VALUE); - carrierScorer.setTolledVehicleTypes(TOLLED_VEHICLE_TYPES); - carrierScorer.setTolledLinks(TOLLED_LINKS); - bind(CarrierScoringFunctionFactory.class).toInstance(carrierScorer); + bind(CarrierScoringFunctionFactory.class).toInstance(new EventBasedCarrierScorer4MultipleChainsInclToll()); bind(LSPScorerFactory.class).toInstance(MyLSPScorer::new); bind(CarrierStrategyManager.class) .toProvider( From 1a0259846afd49dd80635651e00738162c8e3ef0 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Thu, 8 Aug 2024 16:20:19 +0200 Subject: [PATCH 10/13] add PersonMoneyEventsAnalysisModule() to write out PersonMoneyEvents ... --- .../ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java index a4363b8f..5d476dc6 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java @@ -74,7 +74,7 @@ final class ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll { private static final String EDEKA_SUPERMARKT_TROCKEN = "edeka_SUPERMARKT_TROCKEN"; private static final String KAUFLAND_VERBRAUCHERMARKT_TROCKEN = "kaufland_VERBRAUCHERMARKT_TROCKEN"; - private static final String OUTPUT_DIRECTORY = "output/groceryDelivery_kmt_10_tollb_1000newTollScoring"; + private static final String OUTPUT_DIRECTORY = "output/groceryDelivery_kmt_10_tollb_1000newTollScoringONCE"; private ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll() {} @@ -117,6 +117,7 @@ public static void main(String[] args) { @Override public void install() { install(new LSPModule()); + install(new PersonMoneyEventsAnalysisModule()); } }); From 321ae2d0beec40cc4f56808043282b10e0336056 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Thu, 8 Aug 2024 16:20:27 +0200 Subject: [PATCH 11/13] add PersonMoneyEventsAnalysisModule() to write out PersonMoneyEvents ... --- ...mpleTwoLspsGroceryDeliveryMultipleChainsWithToll.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java index 5d476dc6..8dee7bbd 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java @@ -24,6 +24,7 @@ import java.util.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -364,8 +365,8 @@ private static LogisticChain createTwoEchelonChain(Scenario scenario, String lsp ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( distributionCarrier, scenario.getNetwork()) .setDistributionScheduler( - ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) -// ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) +// ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) + ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) .build(); LogisticChainElement distributionCarrierElement = @@ -437,8 +438,8 @@ private static LogisticChain createDirectChain(Scenario scenario, String lspName ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( directCarrier, scenario.getNetwork()) .setDistributionScheduler( - ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) -// ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) +// ResourceImplementationUtils.createDefaultDistributionCarrierSchedulerWithRoadPricing(RoadPricingUtils.getRoadPricingScheme(scenario))) + ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) .build(); LogisticChainElement singleCarrierElement = From 775d6fce1a6c040b1e1d8652970da1edf07716dd Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Thu, 8 Aug 2024 16:20:57 +0200 Subject: [PATCH 12/13] more revert of current EventBasedCarrierScorer4MultipleChains --- .../multipleChains/EventBasedCarrierScorer4MultipleChains.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java index f1820a38..c84e0e07 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChains.java @@ -55,10 +55,8 @@ class EventBasedCarrierScorer4MultipleChains implements CarrierScoringFunctionFa private double toll; private List tolledVehicleTypes = new ArrayList<>(); private List tolledLinks = new ArrayList<>(); - private Id carrierId; public ScoringFunction createScoringFunction(Carrier carrier) { - this.carrierId = carrier.getId(); SumScoringFunction sf = new SumScoringFunction(); sf.addScoringFunction(new EventBasedScoring()); sf.addScoringFunction(new LinkBasedTollScoring(toll, tolledVehicleTypes, tolledLinks)); From af62589daf4d3bb806f65621fc9016f806063ddf Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Thu, 8 Aug 2024 16:26:03 +0200 Subject: [PATCH 13/13] Versuche die Mautsachen aus den PersonMoneyEvents zu scoren... Klappt aber nicht! --- ...dCarrierScorer4MultipleChainsInclToll.java | 132 ++++++++++++++---- 1 file changed, 104 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java index 652e82b6..3b3c3712 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/EventBasedCarrierScorer4MultipleChainsInclToll.java @@ -1,22 +1,22 @@ /* - *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2024 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 * - * * - * *********************************************************************** + *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2024 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.freight.logistics.examples.multipleChains; @@ -28,13 +28,17 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.events.*; +import org.matsim.api.core.v01.events.handler.PersonMoneyEventHandler; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Person; import org.matsim.core.scoring.ScoringFunction; import org.matsim.core.scoring.SumScoringFunction; +import org.matsim.core.scoring.SumScoringFunction.ArbitraryEventScoring; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.Tour; import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; +import org.matsim.freight.carriers.events.CarrierServiceEndEvent; +import org.matsim.freight.carriers.events.CarrierServiceStartEvent; import org.matsim.freight.carriers.events.CarrierTourEndEvent; import org.matsim.freight.carriers.events.CarrierTourStartEvent; import org.matsim.freight.logistics.analysis.Driver2VehicleEventHandler; @@ -56,16 +60,19 @@ public ScoringFunction createScoringFunction(Carrier carrier) { this.carrierId = carrier.getId(); SumScoringFunction sf = new SumScoringFunction(); sf.addScoringFunction(new EventBasedScoring()); + sf.addScoringFunction(new FindOtherEventsForDebuggingOnly_NO_Scoring()); + sf.addScoringFunction(new TollMoneyScoringForDebuggingOnly_NO_Scoring()); return sf; } + /** * Calculate the carrier's score based on Events. Currently, it includes: - fixed costs (using * CarrierTourEndEvent) - time-dependent costs (using FreightTourStart- and -EndEvent) - * distance-dependent costs (using LinkEnterEvent) * tolls (using PersonMoneyEvent) */ - private class EventBasedScoring implements SumScoringFunction.ArbitraryEventScoring { + private class EventBasedScoring implements ArbitraryEventScoring { final Logger log = LogManager.getLogger(EventBasedScoring.class); private final Map, Double> tourStartTime = new LinkedHashMap<>(); @@ -92,7 +99,7 @@ public void handleEvent(Event event) { case CarrierTourStartEvent carrierTourStartEvent -> handleEvent(carrierTourStartEvent); case CarrierTourEndEvent carrierTourEndEvent -> handleEvent(carrierTourEndEvent); case LinkEnterEvent linkEnterEvent -> handleEvent(linkEnterEvent); - case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); + case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); //FIXME: Aus irgendwelchen Gründen kommen hier keine PersonMoneyEvents an... case VehicleEntersTrafficEvent vehicleEntersTrafficEvent -> d2v.handleEvent(vehicleEntersTrafficEvent); case VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent -> d2v.handleEvent(vehicleLeavesTrafficEvent); default -> {} @@ -110,7 +117,7 @@ private void handleEvent(CarrierTourEndEvent event) { v2c.handleEvent(event); // Fix costs for vehicle usage final VehicleType vehicleType = - (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType(); + (VehicleUtils.findVehicle(event.getVehicleId(), scenario)).getType(); double tourDuration = event.getTime() - tourStartTime.get(event.getTourId()); @@ -125,10 +132,10 @@ private void handleEvent(CarrierTourEndEvent event) { private void handleEvent(LinkEnterEvent event) { final double distance = network.getLinks().get(event.getLinkId()).getLength(); final double costPerMeter = - (VehicleUtils.findVehicle(event.getVehicleId(), scenario)) - .getType() - .getCostInformation() - .getCostsPerMeter(); + (VehicleUtils.findVehicle(event.getVehicleId(), scenario)) + .getType() + .getCostInformation() + .getCostsPerMeter(); // variable costs per distance score = score - (distance * costPerMeter); } @@ -142,14 +149,83 @@ private void handleEvent(PersonMoneyEvent event) { if (event.getPurpose().equals("toll")) { if (carrierId.equals(v2c.getCarrierOfVehicle(d2v.getVehicleOfDriver(event.getPersonId())))) { // toll a person only once. -// if (!tolledPersons.contains(event.getPersonId())) { -// tolledPersons.add(event.getPersonId()); + if (!tolledPersons.contains(event.getPersonId())) { + log.info("Tolling caused by event: {}", event); + tolledPersons.add(event.getPersonId()); tollValue = event.getAmount(); -// } + } } } score = score - tollValue; } } + /** + * Versuche nur mit dem Debugger die PersonMoneyEvents zu entdecken, die eigentlich da sein sollten. + */ + private class FindOtherEventsForDebuggingOnly_NO_Scoring implements ArbitraryEventScoring { + + final Logger log = LogManager.getLogger(FindOtherEventsForDebuggingOnly_NO_Scoring.class); + + + public FindOtherEventsForDebuggingOnly_NO_Scoring() { + super(); + } + + @Override + public void finish() {} + + @Override + public double getScore() { + return Double.MIN_VALUE; + } + + @Override + public void handleEvent(Event event) { + log.debug(event.toString()); + + switch (event) { + case CarrierTourStartEvent carrierTourStartEvent -> {} +// case CarrierTourEndEvent carrierTourEndEvent -> {} + case CarrierServiceStartEvent carrierServiceStartEvent -> {} + case CarrierServiceEndEvent carrierServiceEndEvent -> {} + case LinkEnterEvent linkEnterEvent ->{} + case LinkLeaveEvent linkLeaveEvent ->{} +// case PersonMoneyEvent personMoneyEvent -> handleEvent(personMoneyEvent); + default -> {handleOtherEvent(event);} + } + } + + private void handleOtherEvent(Event event) { + log.info("Found another event: {}", event.toString()); + } + + } + + + /** + * Versuche nur mit dem Debugger die Einträge aus den PersonMoneyEvents zu entdecken, die eigentlich da sein sollten. + */ + private static class TollMoneyScoringForDebuggingOnly_NO_Scoring implements SumScoringFunction.MoneyScoring, PersonMoneyEventHandler { + + private double score = 0.0; + @Override + public void addMoney(double amount) { + // TODO Auto-generated method stub + } + + @Override + public void finish() { } + + @Override + public double getScore() { + return this.score; + } + + @Override + public void handleEvent(PersonMoneyEvent event) { + // Todo: implement + } + } + }