From fceadfffd95b6905a2a08b9c57205725568477a3 Mon Sep 17 00:00:00 2001 From: Ricardo Ewert Date: Thu, 26 Sep 2024 14:49:14 +0200 Subject: [PATCH] simplify and update the population sampling option --- .../DemandReaderFromCSV.java | 38 +- .../DemandReaderFromCSVTest.java | 394 ++++++++++++------ 2 files changed, 287 insertions(+), 145 deletions(-) diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java index 196c1a62e52..b224c81d306 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java @@ -611,15 +611,14 @@ else if (population == null) possiblePersonsForService.putAll(population.getPersons()); int numberPossibleServices = (int) Math .round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - if (sampleSizeInputPopulation == sampleTo) - numberOfJobs = (int) Math.round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) - numberOfJobs = (int) Math.round((sampleTo / sampleSizeInputPopulation) - * (shareOfPopulationWithThisService * possiblePersonsForService.size())); - else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = (int) Math.round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - } else + int sampledNumberPossibleServices = (int) Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleServices); + if (sampleSizeInputPopulation == sampleTo || samplingOption.equals("changeDemandOnLocation")) + numberOfJobs = numberPossibleServices; + else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { + numberOfJobs = sampledNumberPossibleServices; + numberPossibleServices = numberOfJobs; + } + else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); if (numberPossibleServices != 0) @@ -823,37 +822,24 @@ else if (population == null) int sampledNumberPossibleJobsPickup = (int)Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleJobsPickup); int sampledNumberPossibleJobsDelivery = (int) Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleJobsDelivery); if (numberPossibleJobsPickup > numberPossibleJobsDelivery) { - if (sampleSizeInputPopulation == sampleTo) { - numberOfJobs = (int) Math.round(shareOfPopulationWithThisPickup * numberPossibleJobsPickup); - numberPossibleJobsPickup = numberOfJobs; - if (shareOfPopulationWithThisDelivery != null) - numberPossibleJobsDelivery = (int) Math - .round(shareOfPopulationWithThisDelivery * numberPossibleJobsDelivery); + if (sampleSizeInputPopulation == sampleTo ||samplingOption.equals("changeDemandOnLocation")) { + numberOfJobs = numberPossibleJobsPickup; } else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { numberOfJobs = sampledNumberPossibleJobsPickup; numberPossibleJobsPickup = numberOfJobs; if (shareOfPopulationWithThisDelivery != null) numberPossibleJobsDelivery = sampledNumberPossibleJobsDelivery; - } else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = numberPossibleJobsPickup; } else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); } else { - if (sampleSizeInputPopulation == sampleTo) { - numberOfJobs = (int) Math.round(shareOfPopulationWithThisDelivery * numberPossibleJobsDelivery); - numberPossibleJobsDelivery = numberOfJobs; - numberPossibleJobsPickup = (int) Math - .round(shareOfPopulationWithThisPickup * numberPossibleJobsPickup); + if (sampleSizeInputPopulation == sampleTo ||samplingOption.equals("changeDemandOnLocation")) { + numberOfJobs = numberPossibleJobsDelivery; } else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { numberOfJobs = sampledNumberPossibleJobsDelivery; numberPossibleJobsDelivery = numberOfJobs; if (shareOfPopulationWithThisDelivery != null) numberPossibleJobsPickup = sampledNumberPossibleJobsPickup; - } else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = numberPossibleJobsDelivery; } else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java index b7d3e7cdf39..c27b251afc4 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java @@ -20,7 +20,6 @@ import org.matsim.freight.carriers.*; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PopulationUtils; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.freightDemandGeneration.CarrierReaderFromCSV.CarrierInformationElement; @@ -62,7 +61,7 @@ void testLinkForPerson() { } @Test - void demandCreation() throws IOException { + void demandCreationWithSampleWithChangeNumberOfLocations() throws IOException { // read inputs Config config = ConfigUtils.createConfig(); config.network().setInputFile( @@ -82,120 +81,16 @@ void demandCreation() throws IOException { FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeNumberOfLocationsWithDemand"); // run methods - Set allNewCarrierInformation = CarrierReaderFromCSV - .readCarrierInformation(carrierCSVLocation); - CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, - indexShape, 1, null); - Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); - DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, indexShape, shapeCategory); - DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, false, - null); - Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size()); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, + population); - // check carrier 1 - Network network = NetworkUtils.readNetwork( - "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); - Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() - .get(Id.create("testCarrier1", Carrier.class)); - Assertions.assertEquals(14, testCarrier1.getServices().size()); - Assertions.assertEquals(0, testCarrier1.getShipments().size()); - Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>(); - Map> locationsPerServiceElement = new HashMap<>(); - int countDemand = 0; - for (CarrierService service : testCarrier1.getServices().values()) { - countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum); - countDemand = countDemand + service.getCapacityDemand(); - if (service.getCapacityDemand() == 0) { - Assertions.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement1", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else if (service.getCapacityDemand() == 1) { - Assertions.assertEquals(100, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else if (service.getCapacityDemand() == 2) { - Assertions.assertEquals(200, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else - Assertions.fail("Service has a wrong demand."); - } - Assertions.assertEquals(12, countDemand); - Assertions.assertEquals(4, countServicesWithCertainDemand.getInt(0)); - Assertions.assertEquals(8, countServicesWithCertainDemand.getInt(1)); - Assertions.assertEquals(2, countServicesWithCertainDemand.getInt(2)); - Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size()); - for (String locationsOfServiceElement : locationsPerServiceElement.get("serviceElement1")) { - Link link = network.getLinks().get(Id.createLinkId(locationsOfServiceElement)); - Assertions.assertTrue( - FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); - Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, - new String[] { "area1" }, null)); - Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, - new String[] { "area2" }, null)); - } - Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); - Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); + Network network = scenario.getNetwork(); - // check carrier 2 - Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() - .get(Id.create("testCarrier2", Carrier.class)); - Assertions.assertEquals(0, testCarrier2.getServices().size()); - Assertions.assertEquals(11, testCarrier2.getShipments().size()); - Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); - Map> locationsPerShipmentElement = new HashMap<>(); - countDemand = 0; - for (CarrierShipment shipment : testCarrier2.getShipments().values()) { - countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); - countDemand = countDemand + shipment.getSize(); - if (shipment.getSize() == 0) { - Assertions.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else if (shipment.getSize() == 2) { - Assertions.assertEquals(400, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(400, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else if (shipment.getSize() == 3) { - Assertions.assertEquals(600, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(600, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else - Assertions.fail("Shipment has an unexpected demand."); - } - Assertions.assertEquals(15, countDemand); - Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(0)); - Assertions.assertEquals(6, countShipmentsWithCertainDemand.getInt(2)); - Assertions.assertEquals(1, countShipmentsWithCertainDemand.getInt(3)); - Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); - Assertions.assertTrue(locationsPerShipmentElement.get("ShipmenElement1_delivery").contains("i(2,0)")); - Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement2_pickup").size()); - Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement2_delivery").size()); + checkCarrier1and2(scenario, network, indexShape); + + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + int countDemand; // check carrier 3 Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() @@ -213,16 +108,16 @@ void demandCreation() throws IOException { Assertions.assertEquals(1250, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_pickup", (k) -> new HashSet<>()) + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_delivery", (k) -> new HashSet<>()) + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) .add(shipment.getTo().toString()); } Assertions.assertEquals(20, countDemand); Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(5)); - Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); - for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmenElement1_delivery")) { + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); Assertions.assertTrue( FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); @@ -233,6 +128,140 @@ void demandCreation() throws IOException { } } + @Test + void demandCreationWithSampleWithDemandOnLocation() throws IOException { + // read inputs + Config config = ConfigUtils.createConfig(); + config.network().setInputFile( + "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); + Scenario scenario = ScenarioUtils.loadScenario(config); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); + Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv"); + Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); + ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); + String shapeCategory = "Ortsteil"; + ShpOptions.Index indexShape = shp.createIndex("Ortsteil"); + String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; + Population population = PopulationUtils.readPopulation(populationLocation); + FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeDemandOnLocation"); + + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, population); + + // check carrier 1 + Network network = scenario.getNetwork(); + + checkCarrier1and2(scenario, network, indexShape); + int countDemand; + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + + // check carrier 3 + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier3", Carrier.class)); + Assertions.assertEquals(0, testCarrier3.getServices().size()); + Assertions.assertEquals(2, testCarrier3.getShipments().size()); + countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier3.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + Assertions.assertEquals(10, shipment.getSize()); + Assertions.assertEquals(4000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2500, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } + Assertions.assertEquals(20, countDemand); + Assertions.assertEquals(2, countShipmentsWithCertainDemand.getInt(10)); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + } + + @Test + void demandCreationNoSampling() throws IOException { + // read inputs + Config config = ConfigUtils.createConfig(); + config.network().setInputFile( + "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); + Scenario scenario = ScenarioUtils.loadScenario(config); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); + Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv"); + Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); + ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); + String shapeCategory = "Ortsteil"; + ShpOptions.Index indexShape = shp.createIndex("Ortsteil"); + String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; + Population population = PopulationUtils.readPopulation(populationLocation); + FreightDemandGenerationUtils.preparePopulation(population, 0.5, 0.5, "changeDemandOnLocation"); + + // run methods + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, + population); + + // check carrier 1 + Network network = scenario.getNetwork(); + + checkCarrier1and2(scenario, network, indexShape); + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + int countDemand; + + // check carrier 3 + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier3", Carrier.class)); + Assertions.assertEquals(0, testCarrier3.getServices().size()); + Assertions.assertEquals(2, testCarrier3.getShipments().size()); + countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier3.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + Assertions.assertEquals(10, shipment.getSize()); + Assertions.assertEquals(4000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2500, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } + Assertions.assertEquals(20, countDemand); + Assertions.assertEquals(2, countShipmentsWithCertainDemand.getInt(10)); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + } + @Test void csvDemandReader() throws IOException { @@ -335,4 +364,131 @@ void csvDemandReader() throws IOException { Assertions.fail("No expected demandInformationElement found"); } } + + private static void createDemandAndCheckCarrier(Path carrierCSVLocation, Scenario scenario, FreightCarriersConfigGroup freightCarriersConfigGroup, + ShpOptions.Index indexShape, Path demandCSVLocation, String shapeCategory, + Population population) throws IOException { + // run methods + Set allNewCarrierInformation = CarrierReaderFromCSV + .readCarrierInformation(carrierCSVLocation); + CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, + indexShape, 1, null); + Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); + DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, indexShape, shapeCategory); + DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, false, + null); + Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size()); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + } + + /** + * These results should be the same for these carriers. + * The difference is only based on the population sample methods for carrier3, because a shareOfThePopulation is used. + * + * @param scenario the scenario + * @param network the network + * @param indexShape the index of the shape + */ + private static void checkCarrier1and2(Scenario scenario, Network network, ShpOptions.Index indexShape) { + Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier1", Carrier.class)); + Assertions.assertEquals(14, testCarrier1.getServices().size()); + Assertions.assertEquals(0, testCarrier1.getShipments().size()); + Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>(); + Map> locationsPerServiceElement = new HashMap<>(); + int countDemand = 0; + for (CarrierService service : testCarrier1.getServices().values()) { + countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum); + countDemand = countDemand + service.getCapacityDemand(); + if (service.getCapacityDemand() == 0) { + Assertions.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement1", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else if (service.getCapacityDemand() == 1) { + Assertions.assertEquals(100, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else if (service.getCapacityDemand() == 2) { + Assertions.assertEquals(200, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else + Assertions.fail("Service has a wrong demand."); + } + Assertions.assertEquals(12, countDemand); + Assertions.assertEquals(4, countServicesWithCertainDemand.getInt(0)); + Assertions.assertEquals(8, countServicesWithCertainDemand.getInt(1)); + Assertions.assertEquals(2, countServicesWithCertainDemand.getInt(2)); + Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size()); + for (String locationsOfServiceElement : locationsPerServiceElement.get("serviceElement1")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfServiceElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); + Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); + + // check carrier 2 + Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier2", Carrier.class)); + Assertions.assertEquals(0, testCarrier2.getServices().size()); + Assertions.assertEquals(11, testCarrier2.getShipments().size()); + Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + Map> locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier2.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + if (shipment.getSize() == 0) { + Assertions.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else if (shipment.getSize() == 2) { + Assertions.assertEquals(400, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(400, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else if (shipment.getSize() == 3) { + Assertions.assertEquals(600, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(600, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else + Assertions.fail("Shipment has an unexpected demand."); + } + Assertions.assertEquals(15, countDemand); + Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(0)); + Assertions.assertEquals(6, countShipmentsWithCertainDemand.getInt(2)); + Assertions.assertEquals(1, countShipmentsWithCertainDemand.getInt(3)); + Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + Assertions.assertTrue(locationsPerShipmentElement.get("ShipmentElement1_delivery").contains("i(2,0)")); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement2_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement2_delivery").size()); + } }