diff --git a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleGroceryDeliveryMultipleChains.java b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleGroceryDeliveryMultipleChains.java index 4a21941e..0d5690a3 100644 --- a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleGroceryDeliveryMultipleChains.java +++ b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleGroceryDeliveryMultipleChains.java @@ -80,20 +80,14 @@ public void install() { .toProvider( () -> { LSPStrategyManager strategyManager = new LSPStrategyManagerImpl(); - strategyManager.addStrategy( - new GenericPlanStrategyImpl<>( - new ExpBetaPlanSelector<>(new ScoringConfigGroup())), - null, - 1); + strategyManager.addStrategy(new GenericPlanStrategyImpl<>(new ExpBetaPlanSelector<>(new ScoringConfigGroup())), null, 1); // strategyManager.addStrategy(new // RebalancingShipmentsStrategyFactory().createStrategy(), null, 2); - // strategyManager.addStrategy(new - // RandomShiftingStrategyFactory().createStrategy(), null, 1); + strategyManager.addStrategy(new RandomShiftingStrategyFactory().createStrategy(), null, 1); // strategyManager.addStrategy(new // ProximityStrategyFactory(scenario.getNetwork()).createStrategy(), null, 1); - // strategyManager.setMaxPlansPerAgent(5); - strategyManager.setPlanSelectorForRemoval( - new GenericWorstPlanForRemovalSelector<>()); + strategyManager.setMaxPlansPerAgent(5); + strategyManager.setPlanSelectorForRemoval(new GenericWorstPlanForRemovalSelector<>()); return strategyManager; }); } @@ -120,22 +114,17 @@ private static Config prepareConfig(String[] args) { } ConfigUtils.applyCommandline(config, args); } else { - config.controller().setOutputDirectory("output/groceryDelivery"); - config.controller().setLastIteration(5); + config.controller().setOutputDirectory("output/groceryDelivery_kmt"); + config.controller().setLastIteration(20); } - config - .network() - .setInputFile( + 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 - .controller() - .setOverwriteFileSetting( + config.controller().setOverwriteFileSetting( OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); config.controller().setWriteEventsInterval(1); - FreightCarriersConfigGroup freightConfig = - ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + FreightCarriersConfigGroup freightConfig = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); freightConfig.setTimeWindowHandling(FreightCarriersConfigGroup.TimeWindowHandling.ignore); return config; @@ -151,10 +140,8 @@ private static Scenario prepareScenario(Config config) { } private static LSP createLSP(Scenario scenario) { - String carrierPlanFile = - "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"; - String vehicleTypeFile = - "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; + String carrierPlanFile = "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"; + String vehicleTypeFile = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; CarrierVehicleTypes vehicleTypes = new CarrierVehicleTypes(); CarrierVehicleTypeReader vehicleTypeReader = new CarrierVehicleTypeReader(vehicleTypes); @@ -164,14 +151,11 @@ private static LSP createLSP(Scenario scenario) { CarrierPlanXmlReader carrierReader = new CarrierPlanXmlReader(carriers, vehicleTypes); carrierReader.readFile(carrierPlanFile); - Carrier carrier = - carriers - .getCarriers() + Carrier carrier = carriers.getCarriers() .get(Id.create("kaufland_VERBRAUCHERMARKT_TROCKEN", CarrierImpl.class)); // Id depotLinkFromShipments = // carrier.getShipments().values().iterator().next().getFrom(); - Id depotLinkFromVehicles = - carrier + Id depotLinkFromVehicles = carrier .getCarrierCapabilities() .getCarrierVehicles() .values() @@ -185,12 +169,10 @@ private static LSP createLSP(Scenario scenario) { { LogisticChain directChain; { - Carrier singleCarrier = - CarriersUtils.createCarrier(Id.create("singleCarrier", Carrier.class)); + Carrier singleCarrier = CarriersUtils.createCarrier(Id.create("singleCarrier", Carrier.class)); singleCarrier.getCarrierCapabilities().setFleetSize(CarrierCapabilities.FleetSize.INFINITE); - CarriersUtils.addCarrierVehicle( - singleCarrier, + CarriersUtils.addCarrierVehicle(singleCarrier, CarrierVehicle.newInstance( Id.createVehicleId("singleCarrier"), depotLinkFromVehicles, diff --git a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java new file mode 100644 index 00000000..f4277404 --- /dev/null +++ b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/ExampleTwoLspsGroceryDeliveryMultipleChains.java @@ -0,0 +1,440 @@ +/* + *********************************************************************** * + * 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.example.lsp.multipleChains; + +import static org.matsim.freight.logistics.example.lsp.multipleChains.MultipleChainsUtils.createLSPShipmentsFromCarrierShipments; + +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.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.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.resourceImplementations.ResourceImplementationUtils; +import org.matsim.freight.logistics.shipment.LSPShipment; +import org.matsim.vehicles.VehicleType; + + +/** + * This bases on {@link ExampleGroceryDeliveryMultipleChains}. + * Now it will include two different LSPs + * + */ +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; + static double HUBCOSTS_FIX = 100; + + private ExampleTwoLspsGroceryDeliveryMultipleChains() {} + + public static void main(String[] args) { + log.info("Prepare config"); + Config config = prepareConfig(args); + + log.info("Prepare scenario"); + Scenario scenario = prepareScenario(config); + + 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 EventBasedCarrierScorer_MultipleChains carrierScorer = + new EventBasedCarrierScorer_MultipleChains(); + carrierScorer.setToll(TOLL_VALUE); + 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(new + // RebalancingShipmentsStrategyFactory().createStrategy(), null, 2); + strategyManager.addStrategy(new RandomShiftingStrategyFactory().createStrategy(), null, 4); + // strategyManager.addStrategy(new + // ProximityStrategyFactory(scenario.getNetwork()).createStrategy(), null, 1); + strategyManager.setMaxPlansPerAgent(5); + strategyManager.setPlanSelectorForRemoval(new GenericWorstPlanForRemovalSelector<>()); + return strategyManager; + }); + } + }); + + 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."); + } + + 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/groceryDelivery_kmt8_10it_b"); + config.controller().setLastIteration(10); + } + + 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; + } + + private static Scenario prepareScenario(Config config) { + Scenario scenario = ScenarioUtils.loadScenario(config); + + log.info("Add LSP to the scenario"); + Collection lsps = new LinkedList<>(); + lsps.add(createLspWithTwoChains(scenario, "myLSP2", "edeka_SUPERMARKT_TROCKEN", HUB_LINK_ID_NEUKOELLN)); + lsps.add(createLspWithTwoChains(scenario, "myLSP1", "kaufland_VERBRAUCHERMARKT_TROCKEN", HUB_LINK_ID_NEUKOELLN)); + lsps.add(createLspWithDirectChain(scenario, "myLSP2_DIRECT", "edeka_SUPERMARKT_TROCKEN")); + lsps.add(createLspWithDirectChain(scenario, "myLSP1_DIRECT", "kaufland_VERBRAUCHERMARKT_TROCKEN")); + LSPUtils.addLSPs(scenario, new LSPs(lsps)); + + return scenario; + } + + /** + * Creates an LSP with two chains: + * - direct delivery + * - 2-echelon delivery + * + * @param scenario the scenria, used e.g. for getting the network and register some stuff + * @param lspName String of LSP's Id + * @param carrierIdString Name of the carrier, the (lsp's) demand (shipments) are created from. + * @param hubLinkId location of the hub + * @return the LSP + */ + private static LSP createLspWithTwoChains(Scenario scenario, String lspName, String carrierIdString, Id hubLinkId) { + String carrierPlanFile = "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"; + String vehicleTypeFile = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; + + CarrierVehicleTypes vehicleTypes = new CarrierVehicleTypes(); + CarrierVehicleTypeReader vehicleTypeReader = new CarrierVehicleTypeReader(vehicleTypes); + vehicleTypeReader.readFile(vehicleTypeFile); + + Carriers carriers = new Carriers(); + CarrierPlanXmlReader carrierReader = new CarrierPlanXmlReader(carriers, vehicleTypes); + carrierReader.readFile(carrierPlanFile); + + Carrier carrier = carriers.getCarriers() + .get(Id.create(carrierIdString, CarrierImpl.class)); + // Id depotLinkFromShipments = + // carrier.getShipments().values().iterator().next().getFrom(); + Id depotLinkFromVehicles = carrier + .getCarrierCapabilities() + .getCarrierVehicles() + .values() + .iterator() + .next() + .getLinkId(); + + log.info("create LSP"); + + //Chains + LogisticChain directChain = createDirectChain(scenario, lspName, depotLinkFromVehicles, vehicleTypes); + LogisticChain twoEchelonChain = createTwoEchelonChain(scenario, lspName, hubLinkId, depotLinkFromVehicles, vehicleTypes); + + LSPPlan multipleMixedEchelonChainsPlan = + LSPUtils.createLSPPlan() + .addLogisticChain(directChain) + .addLogisticChain(twoEchelonChain) + .addLogisticChain(twoEchelonChain) + .setInitialShipmentAssigner(MultipleChainsUtils.createRandomLogisticChainShipmentAssigner()); + + List lspPlans = new ArrayList<>(); + lspPlans.add(multipleMixedEchelonChainsPlan); + + LSP lsp = + LSPUtils.LSPBuilder.getInstance(Id.create(lspName, LSP.class)) + .setInitialPlan(multipleMixedEchelonChainsPlan) + .setLogisticChainScheduler( + ResourceImplementationUtils.createDefaultSimpleForwardLogisticChainScheduler( + createResourcesListFromLSPPlans(lspPlans))) + .build(); + + log.info("create initial LSPShipments"); + log.info("assign the shipments to the LSP"); + for (LSPShipment shipment : createLSPShipmentsFromCarrierShipments(carrier)) { + 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 createTwoEchelonChain(Scenario scenario, String lspName, Id hubLinkId, Id depotLinkFromVehicles, CarrierVehicleTypes vehicleTypes) { + 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, + vehicleTypes.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, + vehicleTypes + .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 scenria, used e.g. for getting the network and register some stuff + * @param lspName String of LSP's Id + * @param carrierIdString Name of the carrier, the (lsp's) demand (shipments) are created from. + * @return the LSP + */ + private static LSP createLspWithDirectChain(Scenario scenario, String lspName, String carrierIdString) { + String carrierPlanFile = "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"; + String vehicleTypeFile = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/berlin/projects/freight/foodRetailing_wo_rangeConstraint/input/vehicleTypesBVWP100_DC_noTax.xml"; + + CarrierVehicleTypes vehicleTypes = new CarrierVehicleTypes(); + CarrierVehicleTypeReader vehicleTypeReader = new CarrierVehicleTypeReader(vehicleTypes); + vehicleTypeReader.readFile(vehicleTypeFile); + + Carriers carriers = new Carriers(); + CarrierPlanXmlReader carrierReader = new CarrierPlanXmlReader(carriers, vehicleTypes); + carrierReader.readFile(carrierPlanFile); + + Carrier carrier = carriers.getCarriers() + .get(Id.create(carrierIdString, CarrierImpl.class)); + // Id depotLinkFromShipments = + // carrier.getShipments().values().iterator().next().getFrom(); + Id depotLinkFromVehicles = carrier + .getCarrierCapabilities() + .getCarrierVehicles() + .values() + .iterator() + .next() + .getLinkId(); + + log.info("create LSP"); + + LSPPlan lspPlan; + { + LogisticChain directChain; + directChain = createDirectChain(scenario, lspName, depotLinkFromVehicles, vehicleTypes); + + lspPlan = + LSPUtils.createLSPPlan() + .addLogisticChain(directChain) + .setInitialShipmentAssigner(MultipleChainsUtils.createRandomLogisticChainShipmentAssigner()); + } + + List lspPlans = new ArrayList<>(); + lspPlans.add(lspPlan); + + LSP lsp = + LSPUtils.LSPBuilder.getInstance(Id.create(lspName, LSP.class)) + .setInitialPlan(lspPlan) + .setLogisticChainScheduler( + ResourceImplementationUtils.createDefaultSimpleForwardLogisticChainScheduler( + createResourcesListFromLSPPlans(lspPlans))) + .build(); + + log.info("create initial LSPShipments"); + log.info("assign the shipments to the LSP"); + for (LSPShipment shipment : createLSPShipmentsFromCarrierShipments(carrier)) { + 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; + } +} diff --git a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomLogisticChainShipmentAssigner.java b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomLogisticChainShipmentAssigner.java index 049ad135..5142c55b 100644 --- a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomLogisticChainShipmentAssigner.java +++ b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomLogisticChainShipmentAssigner.java @@ -5,7 +5,6 @@ import java.util.Random; import org.matsim.core.gbl.Gbl; import org.matsim.core.gbl.MatsimRandom; -import org.matsim.freight.logistics.LSP; import org.matsim.freight.logistics.LSPPlan; import org.matsim.freight.logistics.LogisticChain; import org.matsim.freight.logistics.InitialShipmentAssigner; @@ -18,14 +17,17 @@ */ class RandomLogisticChainShipmentAssigner implements InitialShipmentAssigner { - RandomLogisticChainShipmentAssigner() {} + private final Random random; + + RandomLogisticChainShipmentAssigner() { + this.random = MatsimRandom.getLocalInstance(); + } @Override public void assignToPlan(LSPPlan lspPlan, LSPShipment shipment) { Gbl.assertIf(!lspPlan.getLogisticChains().isEmpty()); List logisticChains = new ArrayList<>(lspPlan.getLogisticChains()); - Random rand = MatsimRandom.getRandom(); - int index = rand.nextInt(logisticChains.size()); + int index = random.nextInt(logisticChains.size()); LogisticChain logisticChain = logisticChains.get(index); logisticChain.addShipmentToChain(shipment); } diff --git a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomShiftingStrategyFactory.java b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomShiftingStrategyFactory.java index ee40907b..dcf25320 100644 --- a/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomShiftingStrategyFactory.java +++ b/src/main/java/org/matsim/freight/logistics/example/lsp/multipleChains/RandomShiftingStrategyFactory.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Random; + import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.replanning.GenericPlanStrategy; @@ -16,72 +18,69 @@ import org.matsim.freight.logistics.shipment.LSPShipment; class RandomShiftingStrategyFactory { - //This is ok so as long as it is **non-public**. - //Before making it public, it should be configurable either via config or Injection. - //KMT, KN (Jan'24) + private static final Random random = MatsimRandom.getLocalInstance(); - private - RandomShiftingStrategyFactory() {} // class contains only static methods; do not instantiate. + //This is ok so as long as it is **non-public**. + //Before making it public, it should be configurable either via config or Injection. + //KMT, KN (Jan'24) - static GenericPlanStrategy createStrategy() { + RandomShiftingStrategyFactory() {} // class contains only static methods; do not instantiate. - GenericPlanStrategyImpl strategy = - new GenericPlanStrategyImpl<>(new ExpBetaPlanSelector<>(new ScoringConfigGroup())); - GenericPlanStrategyModule randomModule = - new GenericPlanStrategyModule<>() { + static GenericPlanStrategy createStrategy() { - @Override - public void prepareReplanning(ReplanningContext replanningContext) {} + GenericPlanStrategyImpl strategy = new GenericPlanStrategyImpl<>(new ExpBetaPlanSelector<>(new ScoringConfigGroup())); + GenericPlanStrategyModule randomModule = new GenericPlanStrategyModule<>() { - @Override - public void handlePlan(LSPPlan lspPlan) { + @Override + public void prepareReplanning(ReplanningContext replanningContext) {} - // Shifting shipments only makes sense for multiple chains - if (lspPlan.getLogisticChains().size() < 2) return; + @Override + public void handlePlan(LSPPlan lspPlan) { - LSP lsp = lspPlan.getLSP(); + // Shifting shipments only makes sense for multiple chains + if (lspPlan.getLogisticChains().size() < 2) return; - // Make a new list of shipments and pick a random shipment from it - List shipments = new ArrayList<>(lsp.getShipments()); - int shipmentIndex = MatsimRandom.getRandom().nextInt(lsp.getShipments().size()); - LSPShipment shipment = shipments.get(shipmentIndex); + LSP lsp = lspPlan.getLSP(); - // Find and remove the random shipment from its current logistic chain - LogisticChain sourceLogisticChain = null; - for (LogisticChain logisticChain : lsp.getSelectedPlan().getLogisticChains()) { - if (logisticChain.getShipmentIds().remove(shipment.getId())) { - sourceLogisticChain = logisticChain; - break; - } - } + // Make a new list of shipments and pick a random shipment from it + List shipments = new ArrayList<>(lsp.getShipments()); + int shipmentIndex = random.nextInt(lsp.getShipments().size()); + LSPShipment shipment = shipments.get(shipmentIndex); - // Find a new logistic chain for the shipment - // Ensure that the chain selected is not the same as the one it was removed from - int chainIndex; - LogisticChain targetLogisticChain = null; - do { - chainIndex = - MatsimRandom.getRandom() - .nextInt(lsp.getSelectedPlan().getLogisticChains().size()); - Iterator iterator = - lsp.getSelectedPlan().getLogisticChains().iterator(); - for (int i = 0; iterator.hasNext(); i++) { - targetLogisticChain = iterator.next(); - if (i == chainIndex) { - break; + // Find and remove the random shipment from its current logistic chain + LogisticChain sourceLogisticChain = null; + for (LogisticChain logisticChain : lsp.getSelectedPlan().getLogisticChains()) { + if (logisticChain.getShipmentIds().remove(shipment.getId())) { + sourceLogisticChain = logisticChain; + break; + } } - } - } while (targetLogisticChain == sourceLogisticChain); - // Add the shipment to the new logistic chain - targetLogisticChain.addShipmentToChain(shipment); - } + // Find a new logistic chain for the shipment + // Ensure that the chain selected is not the same as the one it was removed from + int chainIndex; + LogisticChain targetLogisticChain = null; + do { + chainIndex = random.nextInt(lsp.getSelectedPlan().getLogisticChains().size()); + Iterator iterator = lsp.getSelectedPlan().getLogisticChains().iterator(); + for (int i = 0; iterator.hasNext(); i++) { + targetLogisticChain = iterator.next(); + if (i == chainIndex) { + break; + } + } + } while (targetLogisticChain == sourceLogisticChain); + + // Add the shipment to the new logistic chain + assert targetLogisticChain != null; + targetLogisticChain.addShipmentToChain(shipment); + } - @Override - public void finishReplanning() {} + @Override + public void finishReplanning() {} }; - strategy.addStrategyModule(randomModule); - return strategy; - } + strategy.addStrategyModule(randomModule); + return strategy; + } }