From ec96e7c7bd40335df6fb3fc73655596802208989 Mon Sep 17 00:00:00 2001 From: Ricardo Ewert Date: Wed, 4 Sep 2024 15:05:30 +0200 Subject: [PATCH 1/2] use coords for activity creation --- .../prepare/commercial/LTLFreightAgentGeneratorRuhr.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/matsim/prepare/commercial/LTLFreightAgentGeneratorRuhr.java b/src/main/java/org/matsim/prepare/commercial/LTLFreightAgentGeneratorRuhr.java index 8afbaa8..d80b64b 100644 --- a/src/main/java/org/matsim/prepare/commercial/LTLFreightAgentGeneratorRuhr.java +++ b/src/main/java/org/matsim/prepare/commercial/LTLFreightAgentGeneratorRuhr.java @@ -103,6 +103,7 @@ static void createPlansBasedOnCarrierPlans(Scenario scenario, Population outputP AtomicInteger integratedToursForWasteCollections = new AtomicInteger(); AtomicInteger integratedToursForParcelDelivery = new AtomicInteger(); + Network network = scenario.getNetwork(); // Sample tours of waste collections and parcel delivery to the scenario sample size. // Therefore, use an error to add a tour if the error is >1 carriers.getCarriers().values().forEach(carrier -> { @@ -157,7 +158,7 @@ else if (Math.abs(parcelDeliveryRoundingError.get()) >= 1.) { String mode = scheduledTour.getVehicle().getType().getNetworkMode(); List carrierScheduledPlanElements = scheduledTour.getTour().getTourElements(); - PopulationUtils.createAndAddActivityFromLinkId(plan, "start", scheduledTour.getTour().getStart().getLocation()).setEndTime( + PopulationUtils.createAndAddActivityFromCoord(plan, "start", network.getLinks().get(scheduledTour.getTour().getStart().getLocation()).getCoord()).setEndTime( scheduledTour.getDeparture()); Id previousLocation = scheduledTour.getTour().getStart().getLocation(); Id lastLocationOfTour = scheduledTour.getTour().getEnd().getLocation(); @@ -172,7 +173,7 @@ else if (Math.abs(parcelDeliveryRoundingError.get()) >= 1.) { if (lastActivity != null && lastActivity.getType().equals("pickup") && lastActivity.getLinkId().equals(linkID)) { lastActivity.setMaximumDuration(lastActivity.getMaximumDuration().seconds() + pickup.getDuration()); } else { - PopulationUtils.createAndAddActivityFromLinkId(plan, "pickup", linkID).setMaximumDuration( + PopulationUtils.createAndAddActivityFromCoord(plan, "pickup", network.getLinks().get(linkID).getCoord()).setMaximumDuration( pickup.getDuration()); previousLocation = linkID; } @@ -185,7 +186,7 @@ else if (Math.abs(parcelDeliveryRoundingError.get()) >= 1.) { lastActivity.setMaximumDuration( lastActivity.getMaximumDuration().seconds() + delivery.getDuration()); } else { - PopulationUtils.createAndAddActivityFromLinkId(plan, "delivery", linkID).setMaximumDuration( + PopulationUtils.createAndAddActivityFromCoord(plan, "delivery", network.getLinks().get(linkID).getCoord()).setMaximumDuration( delivery.getDuration()); previousLocation = linkID; } @@ -198,7 +199,7 @@ else if (Math.abs(parcelDeliveryRoundingError.get()) >= 1.) { PopulationUtils.createAndAddLeg(plan, mode); } } - PopulationUtils.createAndAddActivityFromLinkId(plan, "end", lastLocationOfTour).setMaximumDuration( + PopulationUtils.createAndAddActivityFromCoord(plan, "end", network.getLinks().get(lastLocationOfTour).getCoord()).setMaximumDuration( scheduledTour.getTour().getEnd().getDuration()); String key = carrier.getId().toString(); From 82bb6efd89221aca2f80f1846615d730cdc8e3f3 Mon Sep 17 00:00:00 2001 From: Ricardo Ewert Date: Wed, 4 Sep 2024 15:06:01 +0200 Subject: [PATCH 2/2] formatting --- .../GenerateLTLFreightPlansRuhr.java | 327 +++++++++--------- 1 file changed, 165 insertions(+), 162 deletions(-) diff --git a/src/main/java/org/matsim/prepare/commercial/GenerateLTLFreightPlansRuhr.java b/src/main/java/org/matsim/prepare/commercial/GenerateLTLFreightPlansRuhr.java index 28ea29f..11d251d 100644 --- a/src/main/java/org/matsim/prepare/commercial/GenerateLTLFreightPlansRuhr.java +++ b/src/main/java/org/matsim/prepare/commercial/GenerateLTLFreightPlansRuhr.java @@ -30,109 +30,110 @@ import java.util.concurrent.ExecutionException; public class GenerateLTLFreightPlansRuhr implements MATSimAppCommand { - private static final Logger log = LogManager.getLogger(GenerateLTLFreightPlansRuhr.class); - - @CommandLine.Option(names = "--data", description = "Path to generated freight data", - defaultValue = "scenarios/metropole-ruhr-v2.0/input/commercialTraffic/ruhr_freightData_100pct.xml.gz") - private String dataPath; - - @CommandLine.Option(names = "--network", description = "Path to desired network file", - defaultValue = "scenarios/metropole-ruhr-v2.0/input/metropole-ruhr-v2.0_network.xml.gz") - private String networkPath; - - @CommandLine.Option(names = "--vehicleTypesFilePath", description = "Path to vehicle types file", - defaultValue = "scenarios/metropole-ruhr-v2.0/input/metropole-ruhr-v2.0.mode-vehicles.xml") - private String vehicleTypesFilePath; - - @CommandLine.Option(names = "--output", description = "Output folder path", required = true, defaultValue = "scenarios/metropole-ruhr-v2.0/output/rvr_freightPlans/") - private Path output; - - @CommandLine.Option(names = "--nameOutputPopulation", description = "Name of the output population file") - private String nameOutputPopulation; - - @CommandLine.Option(names = "--working-days", defaultValue = "260", description = "Number of working days per year") - private int workingDays; - //TODO discuss if 260 is a good value - - @CommandLine.Option(names = "--sample", defaultValue = "0.01", description = "Scaling factor of the freight traffic (0, 1)") - private double sample; - - @CommandLine.Option(names = "--jsprit-iterations-for-LTL", defaultValue = "100", description = "Number of iterations for jsprit for solving the LTL vehicle routing problems", required = true) - private int jspritIterationsForLTL; - - @Override - public Integer call() throws Exception { - - log.info("preparing freight agent generator for FTL trips..."); - LTLFreightAgentGeneratorRuhr freightAgentGeneratorLTL = new LTLFreightAgentGeneratorRuhr(workingDays, sample, null, null, null, null); - - log.info("Freight agent generator for FTL trips successfully created!"); - - log.info("Reading freight data..."); - Population inputFreightDemandData = PopulationUtils.readPopulation(dataPath); - log.info("Freight data successfully loaded. There are {} trip relations", inputFreightDemandData.getPersons().size()); - - log.info("Start generating population..."); - Population outputPopulation = PopulationUtils.createPopulation(ConfigUtils.createConfig()); - - createPLansForLTLTrips(inputFreightDemandData, freightAgentGeneratorLTL, outputPopulation, jspritIterationsForLTL); - - if (!Files.exists(output)) { - Files.createDirectory(output); - } - - String sampleName = getSampleNameOfOutputFolder(sample); - String outputPlansPath; - if(nameOutputPopulation == null) - outputPlansPath = output.resolve("freight." + sampleName+ "pct.plansLTL.xml.gz").toString(); - else - outputPlansPath = output.resolve(nameOutputPopulation).toString(); - PopulationWriter populationWriter = new PopulationWriter(outputPopulation); - populationWriter.write(outputPlansPath); - - log.info("Freight plans successfully generated!"); - boolean writeTsv = false; - if (writeTsv) { - log.info("Writing down tsv file for visualization and analysis..."); - // Write down tsv file for visualization and analysis - String freightTripTsvPath = output.toString() + "/freight_trips_" + sampleName + "pct_data.tsv"; - CSVPrinter tsvWriter = new CSVPrinter(new FileWriter(freightTripTsvPath), CSVFormat.TDF); - tsvWriter.printRecord("trip_id", "fromCell", "toCell", "from_x", "from_y", "to_x", "to_y", "goodsType", "tripType"); - for (Person person : outputPopulation.getPersons().values()) { - List planElements = person.getSelectedPlan().getPlanElements(); - Activity act0 = (Activity) planElements.get(0); - Activity act1 = (Activity) planElements.get(2); - Coord fromCoord = act0.getCoord(); - Coord toCoord = act1.getCoord(); - String fromCell = CommercialTrafficUtils.getOriginCell(person); - String toCell = CommercialTrafficUtils.getDestinationCell(person); - String tripType = CommercialTrafficUtils.getTransportType(person); - - int goodsType = CommercialTrafficUtils.getGoodsType(person); - tsvWriter.printRecord(person.getId().toString(), fromCell, toCell, fromCoord.getX(), fromCoord.getY(), toCoord.getX(), toCoord.getY(), - goodsType, tripType); - } - tsvWriter.close(); - log.info("Tsv file successfully written to " + freightTripTsvPath); - } - return 0; - } - - /** - * Creates plans for LTL trips. Therefore, multiple carriers are created to solve the resulted vehicle routing problem. - */ - private void createPLansForLTLTrips(Population inputFreightDemandData, LTLFreightAgentGeneratorRuhr freightAgentGeneratorLTL, Population outputPopulation, - int jspritIterationsForLTL) throws ExecutionException, InterruptedException, IOException { + private static final Logger log = LogManager.getLogger(GenerateLTLFreightPlansRuhr.class); + + @CommandLine.Option(names = "--data", description = "Path to generated freight data", + defaultValue = "scenarios/metropole-ruhr-v2.0/input/commercialTraffic/ruhr_freightData_100pct.xml.gz") + private String dataPath; + + @CommandLine.Option(names = "--network", description = "Path to desired network file", + defaultValue = "scenarios/metropole-ruhr-v2.0/input/metropole-ruhr-v2.0_network.xml.gz") + private String networkPath; + + @CommandLine.Option(names = "--vehicleTypesFilePath", description = "Path to vehicle types file", + defaultValue = "scenarios/metropole-ruhr-v2.0/input/metropole-ruhr-v2.0.mode-vehicles.xml") + private String vehicleTypesFilePath; + + @CommandLine.Option(names = "--output", description = "Output folder path", required = true, defaultValue = "scenarios/metropole-ruhr-v2.0/output/rvr_freightPlans/") + private Path output; + + @CommandLine.Option(names = "--nameOutputPopulation", description = "Name of the output population file") + private String nameOutputPopulation; + + @CommandLine.Option(names = "--working-days", defaultValue = "260", description = "Number of working days per year") + private int workingDays; + //TODO discuss if 260 is a good value + + @CommandLine.Option(names = "--sample", defaultValue = "0.01", description = "Scaling factor of the freight traffic (0, 1)") + private double sample; + + @CommandLine.Option(names = "--jsprit-iterations-for-LTL", defaultValue = "100", description = "Number of iterations for jsprit for solving the LTL vehicle routing problems", required = true) + private int jspritIterationsForLTL; + + @Override + public Integer call() throws Exception { + + log.info("preparing freight agent generator for FTL trips..."); + LTLFreightAgentGeneratorRuhr freightAgentGeneratorLTL = new LTLFreightAgentGeneratorRuhr(workingDays, sample, null, null, null, null); + + log.info("Freight agent generator for FTL trips successfully created!"); + + log.info("Reading freight data..."); + Population inputFreightDemandData = PopulationUtils.readPopulation(dataPath); + log.info("Freight data successfully loaded. There are {} trip relations", inputFreightDemandData.getPersons().size()); + + log.info("Start generating population..."); + Population outputPopulation = PopulationUtils.createPopulation(ConfigUtils.createConfig()); + + createPLansForLTLTrips(inputFreightDemandData, freightAgentGeneratorLTL, outputPopulation, jspritIterationsForLTL); + + if (!Files.exists(output)) { + Files.createDirectory(output); + } + + String sampleName = getSampleNameOfOutputFolder(sample); + String outputPlansPath; + if (nameOutputPopulation == null) + outputPlansPath = output.resolve("freight." + sampleName + "pct.plansLTL.xml.gz").toString(); + else + outputPlansPath = output.resolve(nameOutputPopulation).toString(); + PopulationWriter populationWriter = new PopulationWriter(outputPopulation); + populationWriter.write(outputPlansPath); + + log.info("Freight plans successfully generated!"); + boolean writeTsv = false; + if (writeTsv) { + log.info("Writing down tsv file for visualization and analysis..."); + // Write down tsv file for visualization and analysis + String freightTripTsvPath = output.toString() + "/freight_trips_" + sampleName + "pct_data.tsv"; + CSVPrinter tsvWriter = new CSVPrinter(new FileWriter(freightTripTsvPath), CSVFormat.TDF); + tsvWriter.printRecord("trip_id", "fromCell", "toCell", "from_x", "from_y", "to_x", "to_y", "goodsType", "tripType"); + for (Person person : outputPopulation.getPersons().values()) { + List planElements = person.getSelectedPlan().getPlanElements(); + Activity act0 = (Activity) planElements.get(0); + Activity act1 = (Activity) planElements.get(2); + Coord fromCoord = act0.getCoord(); + Coord toCoord = act1.getCoord(); + String fromCell = CommercialTrafficUtils.getOriginCell(person); + String toCell = CommercialTrafficUtils.getDestinationCell(person); + String tripType = CommercialTrafficUtils.getTransportType(person); + + int goodsType = CommercialTrafficUtils.getGoodsType(person); + tsvWriter.printRecord(person.getId().toString(), fromCell, toCell, fromCoord.getX(), fromCoord.getY(), toCoord.getX(), toCoord.getY(), + goodsType, tripType); + } + tsvWriter.close(); + log.info("Tsv file successfully written to " + freightTripTsvPath); + } + return 0; + } + + /** + * Creates plans for LTL trips. Therefore, multiple carriers are created to solve the resulted vehicle routing problem. + */ + private void createPLansForLTLTrips(Population inputFreightDemandData, LTLFreightAgentGeneratorRuhr freightAgentGeneratorLTL, + Population outputPopulation, + int jspritIterationsForLTL) throws ExecutionException, InterruptedException, IOException { enum CarrierType { REST, WASTE, PARCEL } - Config config = ConfigUtils.createConfig(); - config.network().setInputFile(networkPath); - config.global().setCoordinateSystem("EPSG:25832"); - FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); - freightCarriersConfigGroup.setCarriersVehicleTypesFile(vehicleTypesFilePath); + Config config = ConfigUtils.createConfig(); + config.network().setInputFile(networkPath); + config.global().setCoordinateSystem("EPSG:25832"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(vehicleTypesFilePath); Path outputFolderCarriers = output.resolve("carriersLTL"); if (!Files.exists(outputFolderCarriers)) { Files.createDirectory(outputFolderCarriers); @@ -150,7 +151,7 @@ enum CarrierType { // Path carrierFile_noSolution = outputFolderCarriers.resolve("output_LTLcarriersNoSolution.xml.gz"); // Path carrierFile_withSolution = outputFolderCarriers.resolve("output_LTLcarriersWithSolution.xml.gz"); - for(CarrierType carrierType : CarrierType.values()) { + for (CarrierType carrierType : CarrierType.values()) { carrierFile_noSolution = switch (carrierType) { case REST -> carrierVRPFileLTL_Rest; case WASTE -> carrierVRPFileLTL_Waste; @@ -162,74 +163,76 @@ enum CarrierType { case PARCEL -> carrierVRPFile_Rest_Parcel; }; - Scenario scenario; - if (Files.exists(carrierFile_withSolution)) { - log.warn("Using existing carrier VRP file with solution: {}", carrierFile_withSolution); - freightCarriersConfigGroup.setCarriersFile(carrierFile_withSolution.toString()); - scenario = ScenarioUtils.loadScenario(config); - CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); - } else { - if (Files.exists(carrierFile_noSolution)) { - log.warn("Using existing carrier VRP file without solution: {}", carrierFile_noSolution); - freightCarriersConfigGroup.setCarriersFile(carrierFile_noSolution.toString()); - - scenario = ScenarioUtils.loadScenario(config); - CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); - - } else { - scenario = ScenarioUtils.loadScenario(config); - - log.info("Read carrier vehicle types"); - CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); - new CarrierVehicleTypeReader(carrierVehicleTypes).readURL( - IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersVehicleTypesFile())); - switch (carrierType) { - case REST -> - freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, Integer.MIN_VALUE); - case WASTE -> freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, 140); - case PARCEL -> freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, 150); - }; + Scenario scenario; + if (Files.exists(carrierFile_withSolution)) { + log.warn("Using existing carrier VRP file with solution: {}", carrierFile_withSolution); + freightCarriersConfigGroup.setCarriersFile(carrierFile_withSolution.toString()); + scenario = ScenarioUtils.loadScenario(config); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); + } else { + if (Files.exists(carrierFile_noSolution)) { + log.warn("Using existing carrier VRP file without solution: {}", carrierFile_noSolution); + freightCarriersConfigGroup.setCarriersFile(carrierFile_noSolution.toString()); + + scenario = ScenarioUtils.loadScenario(config); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); + + } else { + scenario = ScenarioUtils.loadScenario(config); + + log.info("Read carrier vehicle types"); + CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); + new CarrierVehicleTypeReader(carrierVehicleTypes).readURL( + IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersVehicleTypesFile())); + switch (carrierType) { + case REST -> freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, + Integer.MIN_VALUE); + case WASTE -> freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, 140); + case PARCEL -> freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL, 150); + }; // freightAgentGeneratorLTL.createCarriersForLTL(inputFreightDemandData, scenario, jspritIterationsForLTL); - CarriersUtils.writeCarriers(CarriersUtils.addOrGetCarriers(scenario), carrierFile_noSolution.toString()); - } - filterRelevantVehicleTypesForTourPlanning(scenario); + CarriersUtils.writeCarriers(CarriersUtils.addOrGetCarriers(scenario), carrierFile_noSolution.toString()); + } + filterRelevantVehicleTypesForTourPlanning(scenario); - CarriersUtils.runJsprit(scenario); + CarriersUtils.runJsprit(scenario); - CarriersUtils.writeCarriers(CarriersUtils.addOrGetCarriers(scenario), carrierFile_withSolution.toString()); - } + CarriersUtils.writeCarriers(CarriersUtils.addOrGetCarriers(scenario), carrierFile_withSolution.toString()); + } - LTLFreightAgentGeneratorRuhr.createPlansBasedOnCarrierPlans(scenario, outputPopulation); + LTLFreightAgentGeneratorRuhr.createPlansBasedOnCarrierPlans(scenario, outputPopulation); } - } - - /** Remove vehicle types which are not used by the carriers - * @param scenario the scenario - */ - private static void filterRelevantVehicleTypesForTourPlanning(Scenario scenario) { - // - Map, VehicleType> readVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes(); - List> usedCarrierVehicleTypes = CarriersUtils.getCarriers(scenario).getCarriers().values().stream() - .flatMap(carrier -> carrier.getCarrierCapabilities().getCarrierVehicles().values().stream()) - .map(vehicle -> vehicle.getType().getId()) - .distinct() - .toList(); - - readVehicleTypes.keySet().removeIf(vehicleType -> !usedCarrierVehicleTypes.contains(vehicleType)); - } - - public static void main(String[] args) { - new GenerateLTLFreightPlansRuhr().execute(args); - } - - private static String getSampleNameOfOutputFolder(double sample) { - String sampleName; - if ((sample * 100) % 1 == 0) - sampleName = String.valueOf((int) (sample * 100)); - else - sampleName = String.valueOf((sample * 100)); - return sampleName; - } + } + + /** + * Remove vehicle types which are not used by the carriers + * + * @param scenario the scenario + */ + private static void filterRelevantVehicleTypesForTourPlanning(Scenario scenario) { + // + Map, VehicleType> readVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes(); + List> usedCarrierVehicleTypes = CarriersUtils.getCarriers(scenario).getCarriers().values().stream() + .flatMap(carrier -> carrier.getCarrierCapabilities().getCarrierVehicles().values().stream()) + .map(vehicle -> vehicle.getType().getId()) + .distinct() + .toList(); + + readVehicleTypes.keySet().removeIf(vehicleType -> !usedCarrierVehicleTypes.contains(vehicleType)); + } + + public static void main(String[] args) { + new GenerateLTLFreightPlansRuhr().execute(args); + } + + private static String getSampleNameOfOutputFolder(double sample) { + String sampleName; + if ((sample * 100) % 1 == 0) + sampleName = String.valueOf((int) (sample * 100)); + else + sampleName = String.valueOf((sample * 100)); + return sampleName; + } }