From 472a3f306dcc9ece49b7fceebcbe04d8b976c627 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 30 Jul 2024 12:50:55 +0200 Subject: [PATCH 1/7] update MATSim version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 11806fdd..5e2b066f 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,8 @@ org.matsim matsim-all - - 2025.0-2024w31 + 2025.0-PR3386 + From a84c4a31070d3903f74c291b64c3728193238082 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 30 Jul 2024 12:56:11 +0200 Subject: [PATCH 2/7] renaming and JavaDoc --- .../CarrierSchedulerUtils.java | 28 ++++++++++++++++--- .../CollectionCarrierScheduler.java | 2 +- .../DistributionCarrierScheduler.java | 4 +-- 3 files changed, 27 insertions(+), 7 deletions(-) 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 bad24f1a..73e32368 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java @@ -7,6 +7,8 @@ import com.graphhopper.jsprit.core.util.Solutions; import java.util.Collection; import java.util.List; + +import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Network; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierPlan; @@ -21,12 +23,30 @@ * @author Kai Martins-Turner (kturner) */ public class CarrierSchedulerUtils { - public static Carrier routeCarrier(Carrier carrier, Network network) { + + /** + * Creates a VehicleRoutingProblem from a carrier and a network and solves it with Jsprit. + *

+ * This looks for me (KMT) similar to what is done in {@link org.matsim.freight.carriers.CarriersUtils#runJsprit(Scenario)}. + * So, maybe this can be more simplify. + *

+ * @Todo: include toll in the NetbasedCosts (if set), so it is also pat of the VRP + * @Todo: Find a way to reuse the netbasedCosts over the iterations(?) to avoid re-setting this up??? + *

  • Pro: saves computation times, + *
  • Con: There is now update of the costs if the network (load) changes. + *
  • --> do it at least per Carrier or generally or stay as it is? --> Discuss with KN + * @Todo: Make the number of jsprit-Iterations configurable + * + * @param carrier Carrier for which the problem should be solved + * @param network the underlying network to create the network based transport costs + * @return Carrier with the solution of the VehicleRoutingProblem and the routed plan. + */ + public static Carrier solveVrpWithJsprit(Carrier carrier, Network network) { VehicleRoutingProblem.Builder vrpBuilder = - MatsimJspritFactory.createRoutingProblemBuilder(carrier, network); + MatsimJspritFactory.createRoutingProblemBuilder(carrier, network); NetworkBasedTransportCosts.Builder tpcostsBuilder = - NetworkBasedTransportCosts.Builder.newInstance( - network, ResourceImplementationUtils.getVehicleTypeCollection(carrier)); + NetworkBasedTransportCosts.Builder.newInstance( + network, ResourceImplementationUtils.getVehicleTypeCollection(carrier)); NetworkBasedTransportCosts netbasedTransportCosts = tpcostsBuilder.build(); vrpBuilder.setRoutingCost(netbasedTransportCosts); VehicleRoutingProblem vrp = vrpBuilder.build(); 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 2d880d20..b0103bf2 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CollectionCarrierScheduler.java @@ -69,7 +69,7 @@ public void scheduleResource() { CarrierService carrierService = convertToCarrierService(tupleToBeAssigned); carrier.getServices().put(carrierService.getId(), carrierService); } - carrier = CarrierSchedulerUtils.routeCarrier(carrier, resource.getNetwork()); + carrier = CarrierSchedulerUtils.solveVrpWithJsprit(carrier, resource.getNetwork()); } 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 51f13267..031495e7 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/DistributionCarrierScheduler.java @@ -88,7 +88,7 @@ protected void scheduleResource() { > vehicleType.getCapacity().getOther().intValue()) { load = 0; Carrier auxiliaryCarrier = - CarrierSchedulerUtils.routeCarrier( + CarrierSchedulerUtils.solveVrpWithJsprit( createAuxiliaryCarrier( shipmentsInCurrentTour, availabilityTimeOfLastShipment + cumulatedLoadingTime), resource.getNetwork()); @@ -105,7 +105,7 @@ protected void scheduleResource() { if (!shipmentsInCurrentTour.isEmpty()) { Carrier auxiliaryCarrier = - CarrierSchedulerUtils.routeCarrier( + CarrierSchedulerUtils.solveVrpWithJsprit( createAuxiliaryCarrier( shipmentsInCurrentTour, availabilityTimeOfLastShipment + cumulatedLoadingTime), resource.getNetwork()); From 9ab7f0cfa83b37bfab50ff7953da3e1e70d76a27 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 31 Jul 2024 12:44:17 +0200 Subject: [PATCH 3/7] WIP: add method for calculation with toll. Some refactoring on the way --- .../CarrierSchedulerUtils.java | 65 +++++++++++++++---- 1 file changed, 54 insertions(+), 11 deletions(-) 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 73e32368..6eb57410 100644 --- a/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java +++ b/src/main/java/org/matsim/freight/logistics/resourceImplementations/CarrierSchedulerUtils.java @@ -5,16 +5,17 @@ import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.util.Solutions; -import java.util.Collection; import java.util.List; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Network; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierPlan; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.jsprit.MatsimJspritFactory; import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts; import org.matsim.freight.carriers.jsprit.NetworkRouter; +import org.matsim.freight.carriers.jsprit.VehicleTypeDependentRoadPricingCalculator; /** * This class contains some code fragments, that are used in the different *CarrierScheduler @@ -42,20 +43,23 @@ public class CarrierSchedulerUtils { * @return Carrier with the solution of the VehicleRoutingProblem and the routed plan. */ public static Carrier solveVrpWithJsprit(Carrier carrier, Network network) { - VehicleRoutingProblem.Builder vrpBuilder = - MatsimJspritFactory.createRoutingProblemBuilder(carrier, network); - NetworkBasedTransportCosts.Builder tpcostsBuilder = + NetworkBasedTransportCosts netbasedTransportCosts = NetworkBasedTransportCosts.Builder.newInstance( - network, ResourceImplementationUtils.getVehicleTypeCollection(carrier)); - NetworkBasedTransportCosts netbasedTransportCosts = tpcostsBuilder.build(); - vrpBuilder.setRoutingCost(netbasedTransportCosts); - VehicleRoutingProblem vrp = vrpBuilder.build(); + network, ResourceImplementationUtils.getVehicleTypeCollection(carrier)) + .build(); + + VehicleRoutingProblem vrp = + MatsimJspritFactory.createRoutingProblemBuilder(carrier, network) + .setRoutingCost(netbasedTransportCosts) + .build(); + + //Setting jspritIterations to use central infrastructure -> should go more up in the code + CarriersUtils.setJspritIterations(carrier, 1); VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(vrp); - algorithm.setMaxIterations(1); - Collection solutions = algorithm.searchSolutions(); + algorithm.setMaxIterations(CarriersUtils.getJspritIterations(carrier)); - VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); + VehicleRoutingProblemSolution solution = Solutions.bestOf(algorithm.searchSolutions()); CarrierPlan plan = MatsimJspritFactory.createPlan(carrier, solution); NetworkRouter.routePlan(plan, netbasedTransportCosts); @@ -63,6 +67,45 @@ public static Carrier solveVrpWithJsprit(Carrier carrier, Network network) { return carrier; } + /** + * First try with tolls. + * Rest is the same as {@link #solveVrpWithJsprit(Carrier, Network)}. + * @param carrier Carrier for which the problem should be solved + * @param network the underlying network to create the network based transport costs + * @param roadPricingCalculator the road pricing calculator to calculate the tolls + * @return Carrier with the solution of the VehicleRoutingProblem and the routed plan. + */ + public static Carrier solveVrpWithJspritWithToll(Carrier carrier, Network network, VehicleTypeDependentRoadPricingCalculator roadPricingCalculator) { + if (roadPricingCalculator != null) { + NetworkBasedTransportCosts netbasedTransportCosts = + NetworkBasedTransportCosts.Builder.newInstance( + network, ResourceImplementationUtils.getVehicleTypeCollection(carrier)) + .setRoadPricingCalculator(roadPricingCalculator) + .build(); + + VehicleRoutingProblem vrp = + MatsimJspritFactory.createRoutingProblemBuilder(carrier, network) + .setRoutingCost(netbasedTransportCosts) + .build(); + + //Setting jspritIterations to use central infrastructure -> should go more up in the code + CarriersUtils.setJspritIterations(carrier, 1); + + VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp); + vra.setMaxIterations(CarriersUtils.getJspritIterations(carrier)); + VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions()); + + CarrierPlan plan = MatsimJspritFactory.createPlan(carrier, solution); + NetworkRouter.routePlan(plan, netbasedTransportCosts); + carrier.setSelectedPlan(plan); + return carrier; + + } else { //no Toll -> goto previous implementation without toll + return solveVrpWithJsprit(carrier, network); + } + + } + public static Double sumUpScore(List scheduledPlans) { double score = 0; for (CarrierPlan scheduledPlan : scheduledPlans) { From c200a316b50adc8f484bb2330c23d1c01d07526e Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 31 Jul 2024 16:31:27 +0200 Subject: [PATCH 4/7] run settings --- .../ExampleTwoLspsGroceryDeliveryMultipleChains.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java index 6d4a51a5..fabce3b2 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java @@ -181,7 +181,7 @@ private static Config prepareConfig(String[] args) { } ConfigUtils.applyCommandline(config, args); } else { - config.controller().setOutputDirectory("output/groceryDelivery_kmt9_1it"); + config.controller().setOutputDirectory("output/groceryDelivery_kmt_10"); config.controller().setLastIteration(1); } From 2ff01514622945e16ce9122eba439ead64f67814 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 31 Jul 2024 16:32:14 +0200 Subject: [PATCH 5/7] first try with Roadprincing contrib --- ...GroceryDeliveryMultipleChainsWithToll.java | 479 ++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java 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 new file mode 100644 index 00000000..a95acb2b --- /dev/null +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.java @@ -0,0 +1,479 @@ +/* + *********************************************************************** * + * 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 java.net.URL; +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.network.Link; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.roadpricing.*; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.VspExperimentalConfigGroup; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.replanning.GenericPlanStrategyImpl; +import org.matsim.core.replanning.selectors.BestPlanSelector; +import org.matsim.core.replanning.selectors.ExpBetaPlanSelector; +import org.matsim.core.replanning.selectors.GenericWorstPlanForRemovalSelector; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.core.utils.misc.Time; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.controler.CarrierControlerUtils; +import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; +import org.matsim.freight.carriers.controler.CarrierStrategyManager; +import org.matsim.freight.logistics.*; +import org.matsim.freight.logistics.examples.ExampleConstants; +import org.matsim.freight.logistics.resourceImplementations.ResourceImplementationUtils; +import org.matsim.freight.logistics.shipment.LSPShipment; +import org.matsim.vehicles.Vehicle; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; + +/** + * This bases on {@link ExampleGroceryDeliveryMultipleChains}. + * Now it will include two different LSPs + * + */ +final class ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll { + + private static final Logger log = LogManager.getLogger(ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll.class); + private static final Id HUB_LINK_ID_NEUKOELLN = Id.createLinkId("91085"); + private static final double HUBCOSTS_FIX = 100; + + private static final List TOLLED_LINKS = ExampleConstants.TOLLED_LINK_LIST_BERLIN; + private static final List TOLLED_VEHICLE_TYPES = List.of("heavy40t"); // Für welche Fahrzeugtypen soll das MautSchema gelten? + private static final double TOLL_VALUE = 1000; + + private static final String CARRIER_PLAN_FILE = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/CarrierLEH_v2_withFleet_Shipment_OneTW_PickupTime_ICEVandBEV.xml"; + private static final String VEHICLE_TYPE_FILE = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; + 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 ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll() {} + + public static void main(String[] args) { + log.info("Prepare config"); + Config config = prepareConfig(args); + + log.info("Prepare scenario"); + Scenario scenario = ScenarioUtils.loadScenario(config); + + CarrierVehicleTypes vehicleTypes = new CarrierVehicleTypes(); + CarrierVehicleTypeReader vehicleTypeReader = new CarrierVehicleTypeReader(vehicleTypes); + vehicleTypeReader.readFile(VEHICLE_TYPE_FILE); + + Carriers carriers = new Carriers(); + CarrierPlanXmlReader carrierReader = new CarrierPlanXmlReader(carriers, vehicleTypes); + carrierReader.readFile(CARRIER_PLAN_FILE); + + Carrier carrierEdeka = carriers.getCarriers().get(Id.create(EDEKA_SUPERMARKT_TROCKEN, CarrierImpl.class)); + Carrier carrierKaufland = carriers.getCarriers().get(Id.create(KAUFLAND_VERBRAUCHERMARKT_TROCKEN, CarrierImpl.class)); + + 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)); + lsps.add(createLspWithTwoChains(scenario, "Kaufland", MultipleChainsUtils.createLSPShipmentsFromCarrierShipments(carrierKaufland), getDepotLinkFromVehicle(carrierKaufland), HUB_LINK_ID_NEUKOELLN, vehicleTypes, vehicleTypes, vehicleTypes)); + lsps.add(createLspWithDirectChain(scenario, "Edeka_DIRECT", MultipleChainsUtils.createLSPShipmentsFromCarrierShipments(carrierEdeka), getDepotLinkFromVehicle(carrierEdeka), vehicleTypes)); + lsps.add(createLspWithDirectChain(scenario, "Kaufland_DIRECT", MultipleChainsUtils.createLSPShipmentsFromCarrierShipments(carrierKaufland), getDepotLinkFromVehicle(carrierKaufland), vehicleTypes)); + LSPUtils.addLSPs(scenario, new LSPs(lsps)); + + + RoadPricingSchemeUsingTollFactor rpScheme = setUpRoadpricing(config, scenario); + + + log.info("Prepare controler"); + Controler controler = new Controler(scenario); + controler.addOverridingModule( + new AbstractModule() { + @Override + public void install() { + install(new LSPModule()); + } + }); + + controler.addOverridingModule( + 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(LSPScorerFactory.class).toInstance(MyLSPScorer::new); + bind(CarrierStrategyManager.class) + .toProvider( + () -> { + CarrierStrategyManager strategyManager = + CarrierControlerUtils.createDefaultCarrierStrategyManager(); + strategyManager.addStrategy( + new GenericPlanStrategyImpl<>(new BestPlanSelector<>()), null, 1); + return strategyManager; + }); + bind(LSPStrategyManager.class) + .toProvider( + () -> { + LSPStrategyManager strategyManager = new LSPStrategyManagerImpl(); + strategyManager.addStrategy(new GenericPlanStrategyImpl<>(new ExpBetaPlanSelector<>(new ScoringConfigGroup())), null, 1); + strategyManager.addStrategy(RandomShiftingStrategyFactory.createStrategy(), null, 4); + strategyManager.setMaxPlansPerAgent(5); + strategyManager.setPlanSelectorForRemoval(new GenericWorstPlanForRemovalSelector<>()); + return strategyManager; + }); + } + }); + if (!rpScheme.getTolledLinkIds().isEmpty()) { + // RoadPricing.configure(controler); + controler.addOverridingModule( new RoadPricingModule(rpScheme) ); + } + + log.info("Run MATSim"); + + // The VSP default settings are designed for person transport simulation. After talking to Kai, + // they will be set to WARN here. Kai MT may'23 + controler + .getConfig() + .vspExperimental() + .setVspDefaultsCheckingLevel(VspExperimentalConfigGroup.VspDefaultsCheckingLevel.warn); + controler.run(); + + log.info("Done."); + } + + /* + * Set up roadpricing --- this is a copy paste from KMT laecture in GVSim --> need some adaptions + * TODO Adapt settings + */ + private static RoadPricingSchemeUsingTollFactor setUpRoadpricing(Config config, Scenario scenario) { + + //Create Rp Scheme from code. + RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme, "MautFromcodeKMT"); + RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme, "Mautdaten erstellt aus Link-Liste."); + + /* Add general toll. */ + for (String linkIdString : TOLLED_LINKS) { + RoadPricingUtils.addLink(scheme, Id.createLinkId(linkIdString)); + } + + RoadPricingUtils.createAndAddGeneralCost(scheme, + Time.parseTime("00:00:00"), + Time.parseTime("72:00:00"), + TOLL_VALUE); + ///___ End creating from Code + + + // Roadpricing settings + RoadPricingConfigGroup roadPricingConfigGroup = + ConfigUtils.addOrGetModule(config, RoadPricingConfigGroup.class); + + // Wenn FzgTypId in Liste, erfolgt die Bemautung mit dem Kostensatz (Faktor = 1), + // sonst mit 0 (Faktor = 0). ((MATSim seite) + TollFactor tollFactor = + new TollFactor() { + @Override + public double getTollFactor(Id personId, Id vehicleId, Id linkId, double time) { + var vehTypeId = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId(); + if (TOLLED_VEHICLE_TYPES.contains(vehTypeId.toString())) { + return 1; + } else { + return 0; + } + } + }; + + return new RoadPricingSchemeUsingTollFactor(scheme, tollFactor); + } + + + private static Config prepareConfig(String[] args) { + Config config = ConfigUtils.createConfig(); + if (args.length != 0) { + for (String arg : args) { + log.warn(arg); + } + ConfigUtils.applyCommandline(config, args); + } else { + config.controller().setOutputDirectory(OUTPUT_DIRECTORY); + config.controller().setLastIteration(1); + } + + config.network().setInputFile( + "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/berlin-v5.5-10pct/input/berlin-v5.5-network.xml.gz"); + config.global().setCoordinateSystem("EPSG:31468"); + config.global().setRandomSeed(4177); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setWriteEventsInterval(1); + + FreightCarriersConfigGroup freightConfig = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightConfig.setTimeWindowHandling(FreightCarriersConfigGroup.TimeWindowHandling.ignore); + + return config; + } + + /** + * Creates an LSP with two chains: + * - direct delivery + * - 2-echelon delivery + *

    + * TODO: Es sollten dann am Besten direkt die zur Verfügung stehenden VehicleTypes übergeben werden und diese dann hier jeweils (alle) hinzugefügt werden. + * Aktuell erfolgt die Auswahl ja noch hier. Das sollte dann aber nicht mehr so sein, sondern bereits weiter upstream definiert werden. + * kmt Jul'24 + * + * @param scenario the scenario, used e.g. for getting the network and register some stuff + * @param lspName String of LSP's Id + * @param lspShipments Collection of LSPShipments to be assigned to the LSP + * @param depotLinkId Id of the depot link + * @param hubLinkId location of the hub + * @param vehicleTypesMainRun vehicle types for the main run (2e-chain) + * @param vehicleTypesDistributionRun vehicle types for the distribution run (2e-chain) + * @param vehicleTypesDirect vehicle types for the direct run (direct chain) + * @return the LSP + */ + private static LSP createLspWithTwoChains(Scenario scenario, String lspName, Collection lspShipments, Id depotLinkId, Id hubLinkId, CarrierVehicleTypes vehicleTypesMainRun, CarrierVehicleTypes vehicleTypesDistributionRun, CarrierVehicleTypes vehicleTypesDirect) { + log.info("create LSP"); + //Chains + LogisticChain directChain = createDirectChain(scenario, lspName, depotLinkId, vehicleTypesDirect); + LogisticChain twoEchelonChain = createTwoEchelonChain(scenario, lspName, hubLinkId, depotLinkId, vehicleTypesMainRun, vehicleTypesDistributionRun); + + LSPPlan multipleMixedEchelonChainsPlan = + LSPUtils.createLSPPlan() + .addLogisticChain(directChain) + .addLogisticChain(twoEchelonChain) + .setInitialShipmentAssigner(MultipleChainsUtils.createRandomLogisticChainShipmentAssigner()); + + List lspPlans = List.of(multipleMixedEchelonChainsPlan); + + LSP lsp = LSPUtils.LSPBuilder.getInstance(Id.create(lspName, LSP.class)) + .setInitialPlan(multipleMixedEchelonChainsPlan) + .setLogisticChainScheduler( + ResourceImplementationUtils.createDefaultSimpleForwardLogisticChainScheduler( + createResourcesListFromLSPPlans(lspPlans))) + .build(); + + log.info("assign the shipments to the LSP"); + for (LSPShipment shipment : lspShipments) { + lsp.assignShipmentToLSP(shipment); + } + + log.info("schedule the LSP with the shipments and according to the scheduler of the Resource"); + lsp.scheduleLogisticChains(); + + return lsp; + } + + private static Id getDepotLinkFromVehicle(Carrier carrier) { + return carrier + .getCarrierCapabilities() + .getCarrierVehicles() + .values() + .iterator() + .next() + .getLinkId(); + } + + /* + TODO: Es sollten dann am Besten direkt die zur Verfügung stehenden VehicleTypes übergeben werden und diese dann hier jeweils (alle) hinzugefügt werden. + Aktuell erfolgt die Auswahl ja noch hier. Das sollte dann aber nicht mehr so sein, sondern bereits weiter upstream definiert werden. + kmt Jul'24 + */ + private static LogisticChain createTwoEchelonChain(Scenario scenario, String lspName, Id hubLinkId, Id depotLinkFromVehicles, CarrierVehicleTypes vehicleTypesMainRun, CarrierVehicleTypes vehicleTypesDistributionRun) { + LogisticChain hubChain; + Carrier mainCarrier = CarriersUtils.createCarrier(Id.create(lspName +"_mainCarrier", Carrier.class)); + mainCarrier.getCarrierCapabilities().setFleetSize(CarrierCapabilities.FleetSize.INFINITE); + + CarriersUtils.addCarrierVehicle( + mainCarrier, + CarrierVehicle.newInstance( + Id.createVehicleId("mainTruck"), + depotLinkFromVehicles, + vehicleTypesMainRun.getVehicleTypes().get(Id.create("heavy40t", VehicleType.class)))); + LSPResource mainCarrierResource = + ResourceImplementationUtils.MainRunCarrierResourceBuilder.newInstance( + mainCarrier, scenario.getNetwork()) + .setFromLinkId(depotLinkFromVehicles) + .setMainRunCarrierScheduler( + ResourceImplementationUtils.createDefaultMainRunCarrierScheduler()) + .setToLinkId(hubLinkId) + .setVehicleReturn(ResourceImplementationUtils.VehicleReturn.returnToFromLink) + .build(); + + LogisticChainElement mainCarrierElement = + LSPUtils.LogisticChainElementBuilder.newInstance( + Id.create("mainCarrierElement", LogisticChainElement.class)) + .setResource(mainCarrierResource) + .build(); + + LSPResourceScheduler hubScheduler = + ResourceImplementationUtils.TranshipmentHubSchedulerBuilder.newInstance() + .setCapacityNeedFixed(10) + .setCapacityNeedLinear(1) + .build(); + + LSPResource hubResource = + ResourceImplementationUtils.TransshipmentHubBuilder.newInstance( + Id.create(lspName +"_Hub", LSPResource.class), hubLinkId, scenario) + .setTransshipmentHubScheduler(hubScheduler) + .build(); + + LSPUtils.setFixedCost(hubResource, HUBCOSTS_FIX); + + LogisticChainElement hubElement = + LSPUtils.LogisticChainElementBuilder.newInstance( + Id.create("HubElement", LogisticChainElement.class)) + .setResource(hubResource) + .build(); + + Carrier distributionCarrier = + CarriersUtils.createCarrier(Id.create(lspName +"_distributionCarrier", Carrier.class)); + distributionCarrier + .getCarrierCapabilities() + .setFleetSize(CarrierCapabilities.FleetSize.INFINITE); + + CarriersUtils.addCarrierVehicle( + distributionCarrier, + CarrierVehicle.newInstance( + Id.createVehicleId("distributionTruck"), + hubLinkId, + vehicleTypesDistributionRun + .getVehicleTypes() + .get(Id.create("heavy40t_electro", VehicleType.class)))); + LSPResource distributionCarrierResource = + ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( + distributionCarrier, scenario.getNetwork()) + .setDistributionScheduler( + ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) + .build(); + + LogisticChainElement distributionCarrierElement = + LSPUtils.LogisticChainElementBuilder.newInstance( + Id.create("distributionCarrierElement", LogisticChainElement.class)) + .setResource(distributionCarrierResource) + .build(); + + mainCarrierElement.connectWithNextElement(hubElement); + hubElement.connectWithNextElement(distributionCarrierElement); + + hubChain = + LSPUtils.LogisticChainBuilder.newInstance(Id.create("hubChain", LogisticChain.class)) + .addLogisticChainElement(mainCarrierElement) + .addLogisticChainElement(hubElement) + .addLogisticChainElement(distributionCarrierElement) + .build(); + return hubChain; + } + + /** + * Creates an LSP with direct chains: + * + * @param scenario the scenario, used e.g. for getting the network and register some stuff + * @param lspName String of LSP's Id + * @param lspShipments Collection of LSPShipments to be assigned to the LSP + * @param depotLinkId Id of the depot link + * @param vehicleTypesDirect vehicle types for the direct run (direct chain) + * @return the LSP + */ + private static LSP createLspWithDirectChain(Scenario scenario, String lspName, Collection lspShipments, Id depotLinkId, CarrierVehicleTypes vehicleTypesDirect) { + log.info("create LSP"); + + LSPPlan lspPlan = LSPUtils.createLSPPlan() + .addLogisticChain(createDirectChain(scenario, lspName, depotLinkId, vehicleTypesDirect)) + .setInitialShipmentAssigner(MultipleChainsUtils.createRandomLogisticChainShipmentAssigner()); + + LSP lsp = + LSPUtils.LSPBuilder.getInstance(Id.create(lspName, LSP.class)) + .setInitialPlan(lspPlan) + .setLogisticChainScheduler( + ResourceImplementationUtils.createDefaultSimpleForwardLogisticChainScheduler( + createResourcesListFromLSPPlans(List.of(lspPlan)))) + .build(); + + log.info("assign the shipments to the LSP"); + for (LSPShipment shipment : lspShipments) { + lsp.assignShipmentToLSP(shipment); + } + + log.info("schedule the LSP with the shipments and according to the scheduler of the Resource"); + lsp.scheduleLogisticChains(); + + return lsp; + } + + + private static LogisticChain createDirectChain(Scenario scenario, String lspName, Id depotLinkFromVehicles, CarrierVehicleTypes vehicleTypes) { + LogisticChain directChain; + Carrier directCarrier = CarriersUtils.createCarrier(Id.create(lspName +"_directCarrier", Carrier.class)); + directCarrier.getCarrierCapabilities().setFleetSize(CarrierCapabilities.FleetSize.INFINITE); + + CarriersUtils.addCarrierVehicle(directCarrier, + CarrierVehicle.newInstance( + Id.createVehicleId("directCarrierTruck"), + depotLinkFromVehicles, + vehicleTypes.getVehicleTypes().get(Id.create("heavy40t", VehicleType.class)))); + LSPResource singleCarrierResource = + ResourceImplementationUtils.DistributionCarrierResourceBuilder.newInstance( + directCarrier, scenario.getNetwork()) + .setDistributionScheduler( + ResourceImplementationUtils.createDefaultDistributionCarrierScheduler()) + .build(); + + LogisticChainElement singleCarrierElement = + LSPUtils.LogisticChainElementBuilder.newInstance( + Id.create("directCarrierElement", LogisticChainElement.class)) + .setResource(singleCarrierResource) + .build(); + + directChain = + LSPUtils.LogisticChainBuilder.newInstance(Id.create("directChain", LogisticChain.class)) + .addLogisticChainElement(singleCarrierElement) + .build(); + return directChain; + } + + private static List createResourcesListFromLSPPlans(List lspPlans) { + log.info("Collecting all LSPResources from the LSPPlans"); + List resourceList = new ArrayList<>(); + for (LSPPlan lspPlan : lspPlans) { + for (LogisticChain logisticChain : lspPlan.getLogisticChains()) { + for (LogisticChainElement logisticChainElement : logisticChain.getLogisticChainElements()) { + resourceList.add(logisticChainElement.getResource()); + } + } + } + return resourceList; + } +} From 254892ca6a39b8b2fe45e428cbb2a815a280f9db Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 31 Jul 2024 16:35:23 +0200 Subject: [PATCH 6/7] minor refactoring --- .../ExampleGroceryDeliveryMultipleChains.java | 3 ++- ...eTwoLspsGroceryDeliveryMultipleChains.java | 21 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleGroceryDeliveryMultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleGroceryDeliveryMultipleChains.java index 544ef283..0b0a2054 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleGroceryDeliveryMultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleGroceryDeliveryMultipleChains.java @@ -60,6 +60,7 @@ final class ExampleGroceryDeliveryMultipleChains { private static final Id HUB_LINK_ID = Id.createLinkId("91085"); private static final double TOLL_VALUE = 1000; static final double HUBCOSTS_FIX = 100; + private static final List TOLLED_LINKS = ExampleConstants.TOLLED_LINK_LIST_BERLIN; private ExampleGroceryDeliveryMultipleChains() {} @@ -88,7 +89,7 @@ public void install() { new EventBasedCarrierScorer4MultipleChains(); carrierScorer.setToll(TOLL_VALUE); carrierScorer.setTolledVehicleTypes( List.of("heavy40t")); - carrierScorer.setTolledLinks(ExampleConstants.TOLLED_LINK_LIST_BERLIN); + carrierScorer.setTolledLinks(TOLLED_LINKS); bind(CarrierScoringFunctionFactory.class).toInstance(carrierScorer); bind(LSPScorerFactory.class).toInstance(MyLSPScorer::new); bind(CarrierStrategyManager.class) diff --git a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java index fabce3b2..d460747f 100644 --- a/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/examples/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java @@ -80,13 +80,22 @@ final class ExampleTwoLspsGroceryDeliveryMultipleChains { private static final Logger log = LogManager.getLogger(ExampleTwoLspsGroceryDeliveryMultipleChains.class); + private static final Id HUB_LINK_ID_NEUKOELLN = Id.createLinkId("91085"); - private static final double TOLL_VALUE = 1000; private static final double HUBCOSTS_FIX = 100; + + private static final List TOLLED_LINKS = ExampleConstants.TOLLED_LINK_LIST_BERLIN; + private static final List TOLLED_VEHICLE_TYPES = List.of("heavy40t"); + private static final double TOLL_VALUE = 1000; + private static final String CARRIER_PLAN_FILE = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/CarrierLEH_v2_withFleet_Shipment_OneTW_PickupTime_ICEVandBEV.xml"; private static final String VEHICLE_TYPE_FILE = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; - public static final String EDEKA_SUPERMARKT_TROCKEN = "edeka_SUPERMARKT_TROCKEN"; - public static final String KAUFLAND_VERBRAUCHERMARKT_TROCKEN = "kaufland_VERBRAUCHERMARKT_TROCKEN"; + 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"; + + private ExampleTwoLspsGroceryDeliveryMultipleChains() {} @@ -134,8 +143,8 @@ public void install() { final EventBasedCarrierScorer4MultipleChains carrierScorer = new EventBasedCarrierScorer4MultipleChains(); carrierScorer.setToll(TOLL_VALUE); - carrierScorer.setTolledVehicleTypes( List.of("heavy40t")); - carrierScorer.setTolledLinks(ExampleConstants.TOLLED_LINK_LIST_BERLIN); + carrierScorer.setTolledVehicleTypes(TOLLED_VEHICLE_TYPES); + carrierScorer.setTolledLinks(TOLLED_LINKS); bind(CarrierScoringFunctionFactory.class).toInstance(carrierScorer); bind(LSPScorerFactory.class).toInstance(MyLSPScorer::new); bind(CarrierStrategyManager.class) @@ -181,7 +190,7 @@ private static Config prepareConfig(String[] args) { } ConfigUtils.applyCommandline(config, args); } else { - config.controller().setOutputDirectory("output/groceryDelivery_kmt_10"); + config.controller().setOutputDirectory(OUTPUT_DIRECTORY); config.controller().setLastIteration(1); } From 609ceb90f481313d036b3ca569fe49b3bdd0f708 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Wed, 31 Jul 2024 16:55:56 +0200 Subject: [PATCH 7/7] javadoc and cleanup --- ...GroceryDeliveryMultipleChainsWithToll.java | 68 ++++++++----------- 1 file changed, 29 insertions(+), 39 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 a95acb2b..7ec09a44 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 @@ -21,14 +21,12 @@ package org.matsim.freight.logistics.examples.multipleChains; -import java.net.URL; 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.network.Link; -import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.roadpricing.*; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; @@ -42,7 +40,6 @@ import org.matsim.core.replanning.selectors.ExpBetaPlanSelector; import org.matsim.core.replanning.selectors.GenericWorstPlanForRemovalSelector; import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.core.utils.io.IOUtils; import org.matsim.core.utils.misc.Time; import org.matsim.freight.carriers.*; import org.matsim.freight.carriers.controler.CarrierControlerUtils; @@ -52,14 +49,15 @@ import org.matsim.freight.logistics.examples.ExampleConstants; import org.matsim.freight.logistics.resourceImplementations.ResourceImplementationUtils; import org.matsim.freight.logistics.shipment.LSPShipment; -import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; /** - * This bases on {@link ExampleGroceryDeliveryMultipleChains}. - * Now it will include two different LSPs - * + * This bases on {@link ExampleTwoLspsGroceryDeliveryMultipleChains}. + * It is extended in a way that it will use the roadpricing contrib... + * This class is here only for development and will be merged into {@link ExampleTwoLspsGroceryDeliveryMultipleChains} + * once the result is satisfying. + * KMT, Jul'24 */ final class ExampleTwoLspsGroceryDeliveryMultipleChainsWithToll { @@ -108,7 +106,7 @@ public static void main(String[] args) { LSPUtils.addLSPs(scenario, new LSPs(lsps)); - RoadPricingSchemeUsingTollFactor rpScheme = setUpRoadpricing(config, scenario); + RoadPricingSchemeUsingTollFactor rpScheme = setUpRoadpricing(scenario); log.info("Prepare controler"); @@ -172,51 +170,43 @@ public void install() { } /* - * Set up roadpricing --- this is a copy paste from KMT laecture in GVSim --> need some adaptions - * TODO Adapt settings + * Set up roadpricing --- this is a copy paste from KMT lecture in GVSim --> need some adaptions + * TODO Adapt settings */ - private static RoadPricingSchemeUsingTollFactor setUpRoadpricing(Config config, Scenario scenario) { + private static RoadPricingSchemeUsingTollFactor setUpRoadpricing(Scenario scenario) { //Create Rp Scheme from code. - RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); - /* Configure roadpricing scheme. */ - RoadPricingUtils.setName(scheme, "MautFromcodeKMT"); - RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); - RoadPricingUtils.setDescription(scheme, "Mautdaten erstellt aus Link-Liste."); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme, "MautFromCodeKMT"); + RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme, "Mautdaten erstellt aus Link-Liste."); - /* Add general toll. */ + /* Add general toll. */ for (String linkIdString : TOLLED_LINKS) { RoadPricingUtils.addLink(scheme, Id.createLinkId(linkIdString)); } - RoadPricingUtils.createAndAddGeneralCost(scheme, - Time.parseTime("00:00:00"), - Time.parseTime("72:00:00"), - TOLL_VALUE); + RoadPricingUtils.createAndAddGeneralCost(scheme, + Time.parseTime("00:00:00"), + Time.parseTime("72:00:00"), + TOLL_VALUE); ///___ End creating from Code - - // Roadpricing settings - RoadPricingConfigGroup roadPricingConfigGroup = - ConfigUtils.addOrGetModule(config, RoadPricingConfigGroup.class); - // Wenn FzgTypId in Liste, erfolgt die Bemautung mit dem Kostensatz (Faktor = 1), // sonst mit 0 (Faktor = 0). ((MATSim seite) TollFactor tollFactor = - new TollFactor() { - @Override - public double getTollFactor(Id personId, Id vehicleId, Id linkId, double time) { - var vehTypeId = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId(); - if (TOLLED_VEHICLE_TYPES.contains(vehTypeId.toString())) { - return 1; - } else { - return 0; - } - } + (personId, vehicleId, linkId, time) -> { + var vehTypeId = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId(); + if (TOLLED_VEHICLE_TYPES.contains(vehTypeId.toString())) { + return 1; + } else { + return 0; + } }; - return new RoadPricingSchemeUsingTollFactor(scheme, tollFactor); + return new RoadPricingSchemeUsingTollFactor(scheme, tollFactor); } @@ -410,11 +400,11 @@ private static LogisticChain createTwoEchelonChain(Scenario scenario, String lsp private static LSP createLspWithDirectChain(Scenario scenario, String lspName, Collection lspShipments, Id depotLinkId, CarrierVehicleTypes vehicleTypesDirect) { log.info("create LSP"); - LSPPlan lspPlan = LSPUtils.createLSPPlan() + LSPPlan lspPlan = LSPUtils.createLSPPlan() .addLogisticChain(createDirectChain(scenario, lspName, depotLinkId, vehicleTypesDirect)) .setInitialShipmentAssigner(MultipleChainsUtils.createRandomLogisticChainShipmentAssigner()); - LSP lsp = + LSP lsp = LSPUtils.LSPBuilder.getInstance(Id.create(lspName, LSP.class)) .setInitialPlan(lspPlan) .setLogisticChainScheduler(