diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 749aa797fa1..9878d8651cc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,9 +4,6 @@ updates: directory: "/" schedule: interval: "daily" - groups: - maven: - patterns: ["*"] - package-ecosystem: "github-actions" directory: "/" diff --git a/.github/workflows/code-coverage.yaml b/.github/workflows/code-coverage.yaml index 20ffe41971a..bdf0d7bfcde 100644 --- a/.github/workflows/code-coverage.yaml +++ b/.github/workflows/code-coverage.yaml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 021bae1c67c..7804cbe9423 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' @@ -27,7 +27,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: 'java' # If you wish to specify custom queries, you can do so here or in a config file. @@ -41,9 +41,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:java" diff --git a/.github/workflows/deploy-on-pr-merge.yaml b/.github/workflows/deploy-on-pr-merge.yaml index 332a3dfe178..ef046e1bdb0 100644 --- a/.github/workflows/deploy-on-pr-merge.yaml +++ b/.github/workflows/deploy-on-pr-merge.yaml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/deploy-on-release-created.yaml b/.github/workflows/deploy-on-release-created.yaml index 7c37d3c6f7d..ace4f1881fb 100644 --- a/.github/workflows/deploy-on-release-created.yaml +++ b/.github/workflows/deploy-on-release-created.yaml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/deploy-weekly.yaml b/.github/workflows/deploy-weekly.yaml index 0861a80ff91..88e183083b7 100644 --- a/.github/workflows/deploy-weekly.yaml +++ b/.github/workflows/deploy-weekly.yaml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/full-integration.yaml b/.github/workflows/full-integration.yaml index 57789d54a8c..e63fc75985b 100644 --- a/.github/workflows/full-integration.yaml +++ b/.github/workflows/full-integration.yaml @@ -1,6 +1,7 @@ name: full-integration on: + workflow_dispatch: schedule: - cron: '30 0 * * *' # daily at 0:30 UTC @@ -13,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Prepare git @@ -24,7 +25,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/verify-push.yaml b/.github/workflows/verify-push.yaml index 6c98df57073..a4eb837efcb 100644 --- a/.github/workflows/verify-push.yaml +++ b/.github/workflows/verify-push.yaml @@ -58,7 +58,6 @@ jobs: - contribs/railsim - contribs/roadpricing - contribs/analysis - - contribs/eventsBasedPTRouter - contribs/hybridsim - contribs/informed-mode-choice - contribs/otfvis @@ -85,7 +84,7 @@ jobs: - name: Setup Java if: ${{matrix.module != 'matsim' || steps.detect-changes.outputs.outside-contribs == 'true'}} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 43ee7d820b2..f8104490737 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -41,8 +41,12 @@ 16.0-SNAPSHOT - junit - junit + org.junit.jupiter + junit-jupiter-engine + + + org.junit.jupiter + junit-jupiter diff --git a/benchmark/src/main/java/org/matsim/benchmark/Benchmark.java b/benchmark/src/main/java/org/matsim/benchmark/Benchmark.java index 9c11ff9f623..addf157f821 100644 --- a/benchmark/src/main/java/org/matsim/benchmark/Benchmark.java +++ b/benchmark/src/main/java/org/matsim/benchmark/Benchmark.java @@ -32,7 +32,7 @@ public class Benchmark { public static void main(String[] args) throws IOException { Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("benchmark"), "config.xml")); Controler ctl = new Controler(config); - ctl.getConfig().controler().setCreateGraphs(false); + ctl.getConfig().controller().setCreateGraphs(false); ctl.run(); } diff --git a/contribs/accessibility/pom.xml b/contribs/accessibility/pom.xml index 300f8fb1bd1..45d1f56723b 100644 --- a/contribs/accessibility/pom.xml +++ b/contribs/accessibility/pom.xml @@ -52,7 +52,7 @@ org.openstreetmap.osmosis osmosis-core - 0.48.3 + ${osmosis.version} @@ -65,7 +65,7 @@ org.openstreetmap.osmosis osmosis-xml - 0.48.3 + ${osmosis.version} org.matsim.contrib diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationNairobiLandUseLocalCopy.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationNairobiLandUseLocalCopy.java index ef0f7fdc022..91e6e1c72ca 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationNairobiLandUseLocalCopy.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationNairobiLandUseLocalCopy.java @@ -39,26 +39,26 @@ */ class AccessibilityComputationNairobiLandUseLocalCopy { public static final Logger LOG = LogManager.getLogger(AccessibilityComputationNairobiLandUseLocalCopy.class); - + public static void main(String[] args) { int tileSize_m = 500; boolean push2Geoserver = false; // Set true for run on server boolean createQGisOutput = true; // Set false for run on server - + final Config config = ConfigUtils.createConfig(new AccessibilityConfigGroup()); - + Envelope envelope = new Envelope(246000, 271000, 9853000, 9863000); // Central part of Nairobi String scenarioCRS = "EPSG:21037"; // EPSG:21037 = Arc 1960 / UTM zone 37S, for Nairobi, Kenya - + config.network().setInputFile("../nairobi/data/nairobi/input/2015-10-15_network.xml"); config.facilities().setInputFile("../nairobi/data/land_use/Nairobi_LU_2010/facilities.xml"); String runId = "ke_nairobi_landuse_hexagons_" + tileSize_m; - config.controler().setOutputDirectory("../nairobi/data/nairobi/output/" + runId + "_lcpt_par4_car_tr-7_500/"); - config.controler().setRunId(runId); - - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(0); - + config.controller().setOutputDirectory("../nairobi/data/nairobi/output/" + runId + "_lcpt_par4_car_tr-7_500/"); + config.controller().setRunId(runId); + + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); + AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class); acg.setAreaOfAccessibilityComputation(AreaOfAccesssibilityComputation.fromBoundingBoxHexagons); acg.setEnvelope(envelope); @@ -69,17 +69,17 @@ public static void main(String[] args) { acg.setOutputCrs(scenarioCRS); //acg.setUseParallelization(false); - + ConfigUtils.setVspDefaults(config); - + final Scenario scenario = ScenarioUtils.loadScenario(config); - + // final List activityTypes = Arrays.asList(new String[]{"educational", "commercial", "industrial", "recreational", "water_body"}); final List activityTypes = Arrays.asList(new String[]{"educational"}); final ActivityFacilities densityFacilities = AccessibilityUtils.createFacilityForEachLink(Labels.DENSITIY, scenario.getNetwork()); - + final Controler controler = new Controler(scenario); - + for (String activityType : activityTypes) { AccessibilityModule module = new AccessibilityModule(); module.setConsideredActivityType(activityType); @@ -88,17 +88,17 @@ public static void main(String[] args) { module.setCreateQGisOutput(createQGisOutput); controler.addOverridingModule(module); } - + controler.run(); - + if (createQGisOutput) { final Integer range = 9; // In the current implementation, this must always be 9 final Double lowerBound = -3.5; // (upperBound - lowerBound) ideally nicely divisible by (range - 2) final Double upperBound = 3.5; final int populationThreshold = (int) (10 / (1000/tileSize_m * 1000/tileSize_m)); // People per km^2 or roads (?) - + String osName = System.getProperty("os.name"); - String workingDirectory = config.controler().getOutputDirectory(); + String workingDirectory = config.controller().getOutputDirectory(); for (String actType : activityTypes) { String actSpecificWorkingDirectory = workingDirectory + actType + "/"; for (Modes4Accessibility mode : acg.getIsComputingMode()) { diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationShutdownListener.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationShutdownListener.java index a3f82abfa44..39637e1228f 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationShutdownListener.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityComputationShutdownListener.java @@ -30,11 +30,10 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; -import org.matsim.api.core.v01.network.Node; import org.matsim.contrib.accessibility.utils.AggregationObject; import org.matsim.contrib.accessibility.utils.ProgressBar; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.controler.events.ShutdownEvent; import org.matsim.core.controler.listener.ShutdownListener; import org.matsim.core.gbl.Gbl; @@ -58,9 +57,9 @@ final class AccessibilityComputationShutdownListener implements ShutdownListener private final ArrayList zoneDataExchangeListeners = new ArrayList<>(); private AccessibilityConfigGroup acg; - private final PlanCalcScoreConfigGroup cnScoringGroup; + private final ScoringConfigGroup cnScoringGroup; + - public AccessibilityComputationShutdownListener(Scenario scenario, ActivityFacilities measuringPoints, ActivityFacilities opportunities, String outputDirectory) { this.measuringPoints = measuringPoints; @@ -69,7 +68,7 @@ public AccessibilityComputationShutdownListener(Scenario scenario, ActivityFacil this.outputDirectory = outputDirectory; this.acg = ConfigUtils.addOrGetModule(scenario.getConfig(), AccessibilityConfigGroup.GROUP_NAME, AccessibilityConfigGroup.class); - this.cnScoringGroup = scenario.getConfig().planCalcScore(); + this.cnScoringGroup = scenario.getConfig().scoring(); if (cnScoringGroup.getOrCreateModeParams(TransportMode.car).getMarginalUtilityOfDistance() != 0.) { LOG.error("Marginal utility of distance for car different from zero, but not used in accessibility computations"); @@ -241,10 +240,10 @@ private void writeCSVFile(String adaptedOutputDirectory) { writer.writeField(facility.getCoord().getX()); writer.writeField(facility.getCoord().getY()); writer.writeField(tuple.getSecond()); - + for (String mode : getModes() ) { final double value = accessibilitiesMap.get(tuple).get(mode); - if (!Double.isNaN(value)) { + if (!Double.isNaN(value)) { writer.writeField(value) ; } else { writer.writeField(Double.NaN) ; diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityFromEvents.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityFromEvents.java index 476471ebd8c..b200e3a46f0 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityFromEvents.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityFromEvents.java @@ -58,7 +58,7 @@ private AccessibilityFromEvents( Scenario scenario, String eventsFile, List map = new LinkedHashMap<>( ) ; EventsManager events = EventsUtils.createEventsManager(); - for( String mode : scenario.getConfig().plansCalcRoute().getNetworkModes() ){ + for( String mode : scenario.getConfig().routing().getNetworkModes() ){ TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder( scenario.getNetwork() ); builder.setCalculateLinkTravelTimes( true ); builder.setCalculateLinkToLinkTravelTimes( false ); @@ -74,7 +74,7 @@ public void run() { install( new ScenarioByInstanceModule( scenario ) ) ; install( new TripRouterModule() ) ; install( new TimeInterpretationModule() ); - for( String mode : getConfig().plansCalcRoute().getNetworkModes() ){ + for( String mode : getConfig().routing().getNetworkModes() ){ addTravelTimeBinding( mode ).toInstance( map.get(mode) ); } install( new TravelDisutilityModule() ) ; diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java index 19c98283c02..c4677dd3fd3 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java @@ -139,7 +139,7 @@ public ControlerListener get() { } AccessibilityUtils.assignAdditionalFacilitiesDataToMeasurePoint(measuringPoints, measurePointGeometryMap, additionalFacs); - String outputDirectory = scenario.getConfig().controler().getOutputDirectory() + "/" + activityType; + String outputDirectory = scenario.getConfig().controller().getOutputDirectory() + "/" + activityType; AccessibilityComputationShutdownListener accessibilityShutdownListener = new AccessibilityComputationShutdownListener(scenario, measuringPoints, opportunities, outputDirectory); // for (Modes4Accessibility mode : acg.getIsComputingMode()) { @@ -150,14 +150,14 @@ public ControlerListener get() { final TravelDisutilityFactory travelDisutilityFactory = travelDisutilityFactories.get(TransportMode.car); Gbl.assertNotNull(travelDisutilityFactory); calculator = new NetworkModeAccessibilityExpContributionCalculator(mode, new FreeSpeedTravelTime(), travelDisutilityFactory, scenario); - } else if ( config.plansCalcRoute().getNetworkModes().contains( mode ) ) { + } else if ( config.routing().getNetworkModes().contains( mode ) ) { final TravelTime nwModeTravelTime = travelTimes.get(mode); Gbl.assertNotNull(nwModeTravelTime); final TravelDisutilityFactory nwModeTravelDisutility = travelDisutilityFactories.get(mode); Gbl.assertNotNull( nwModeTravelDisutility ); calculator = new NetworkModeAccessibilityExpContributionCalculator(mode, nwModeTravelTime, nwModeTravelDisutility, scenario); } else if ( TransportMode.pt.equals( mode ) ){ - calculator = new SwissRailRaptorAccessibilityContributionCalculator( mode, config.planCalcScore(), scenario ); + calculator = new SwissRailRaptorAccessibilityContributionCalculator( mode, config.scoring(), scenario ); } else if ( Modes4Accessibility.matrixBasedPt.name().equals( mode ) ) { throw new RuntimeException("currently not supported because implementation not consistent with guice grapher. kai, sep'19") ; // calculator = new LeastCostPathCalculatorAccessibilityContributionCalculator( @@ -175,7 +175,7 @@ public ControlerListener get() { if ( travelDisutilityFactory==null ) { throw new RuntimeException("mode=" + mode + "; travelDisutilityFactory is null!") ; } - calculator = new TripRouterAccessibilityContributionCalculator(mode, tripRouter, config.planCalcScore(), scenario, + calculator = new TripRouterAccessibilityContributionCalculator(mode, tripRouter, config.scoring(), scenario, travelTime, travelDisutilityFactory ); } @@ -195,7 +195,7 @@ public ControlerListener get() { } Set additionalFacInfo = additionalFacs.keySet(); accessibilityShutdownListener.addFacilityDataExchangeListener(new GeoserverUpdater(acg.getOutputCrs(), - config.controler().getRunId() + "_" + activityType, measurePointGeometryMap, additionalFacInfo, + config.controller().getRunId() + "_" + activityType, measurePointGeometryMap, additionalFacInfo, outputDirectory, pushing2Geoserver, createQGisOutput)); } diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityUtils.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityUtils.java index 0de040c489c..db9adc47ccd 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityUtils.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityUtils.java @@ -34,7 +34,7 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.NetworkConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.gbl.Gbl; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.algorithms.TransportModeNetworkFilter; @@ -65,7 +65,7 @@ public static final Map, AggregationObject> aggregat // yyyy this method ignores the "capacities" of the facilities. kai, mar'14 // for now, we decided not to add "capacities" as it is not needed for current projects. dz, feb'16 - double walkSpeed_m_h = config.plansCalcRoute().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600.; + double walkSpeed_m_h = config.routing().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600.; AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.GROUP_NAME, AccessibilityConfigGroup.class); LOG.info("Aggregating " + opportunities.getFacilities().size() + " opportunities with same nearest node..."); @@ -76,11 +76,11 @@ public static final Map, AggregationObject> aggregat double distance_m = NetworkUtils.getEuclideanDistance(opportunity.getCoord(), nearestNode.getCoord()); // in MATSim this is [utils/h]: cnScoringGroup.getTravelingWalk_utils_hr() - cnScoringGroup.getPerforming_utils_hr() - double walkBetaTT_utils_h = config.planCalcScore().getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - - config.planCalcScore().getPerforming_utils_hr(); // default values: -12 = (-6.) - (6.) + double walkBetaTT_utils_h = config.scoring().getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() + - config.scoring().getPerforming_utils_hr(); // default values: -12 = (-6.) - (6.) double VjkWalkTravelTime = walkBetaTT_utils_h * (distance_m / walkSpeed_m_h); - double expVjk = Math.exp(config.planCalcScore().getBrainExpBeta() * VjkWalkTravelTime); + double expVjk = Math.exp(config.scoring().getBrainExpBeta() * VjkWalkTravelTime); // add Vjk to sum AggregationObject jco = opportunityClusterMap.get(nearestNode.getId()); // Why "jco"? @@ -142,16 +142,16 @@ public static Network createModeSpecificSubNetwork(Network network, String mode, } - public static double getModeSpecificConstantForAccessibilities(String mode, PlanCalcScoreConfigGroup planCalcScoreConfigGroup) { + public static double getModeSpecificConstantForAccessibilities(String mode, ScoringConfigGroup scoringConfigGroup) { double modeSpecificConstant; if (mode.equals(Modes4Accessibility.freespeed.name())) { - modeSpecificConstant = planCalcScoreConfigGroup.getModes().get(TransportMode.car).getConstant(); + modeSpecificConstant = scoringConfigGroup.getModes().get(TransportMode.car).getConstant(); } else { - modeSpecificConstant = planCalcScoreConfigGroup.getModes().get(mode).getConstant(); + modeSpecificConstant = scoringConfigGroup.getModes().get(mode).getConstant(); } return modeSpecificConstant; } - + /** * Collects all facilities of a given type that have been loaded to the sceanrio. */ @@ -191,8 +191,8 @@ public static List collectAllFacilityOptionTypes(Scenario scenario) { public static void combineDifferentActivityOptionTypes(final Scenario scenario, String combinedType, final List activityOptionsToBeIncluded) { - ActivityOption markerOption = new ActivityOptionImpl(combinedType); - + ActivityOption markerOption = new ActivityOptionImpl(combinedType); + // Memorize all facilities that have certain activity options in a activity facilities container final ActivityFacilities consideredFacilities = FacilitiesUtils.createActivityFacilities(); for (ActivityFacility facility : scenario.getActivityFacilities().getFacilities().values()) { @@ -205,7 +205,7 @@ public static void combineDifferentActivityOptionTypes(final Scenario scenario, } } } - + // Add marker option to facilities to be considered for (ActivityFacility facility : consideredFacilities.getFacilities().values()) { facility.addActivityOption(markerOption); @@ -227,16 +227,16 @@ public static final ActivityFacilities createFacilityForEachLink(String facility public static final ActivityFacilities createFacilityFromBuildingShapefile(String shapeFileName, String identifierCaption, String numberOfHouseholdsCaption) { ShapeFileReader shapeFileReader = new ShapeFileReader(); Collection features = shapeFileReader.readFileAndInitialize(shapeFileName); - + ActivityFacilities facilities = FacilitiesUtils.createActivityFacilities("DensitiyFacilities"); ActivityFacilitiesFactory aff = facilities.getFactory(); - + for (SimpleFeature feature : features) { String featureId = (String) feature.getAttribute(identifierCaption); Integer numberOfHouseholds = Integer.parseInt((String) feature.getAttribute(numberOfHouseholdsCaption)); Geometry geometry = (Geometry) feature.getDefaultGeometry(); Coord coord = CoordUtils.createCoord(geometry.getCentroid().getX(), geometry.getCentroid().getY()); - + for (int i = 0; i < numberOfHouseholds; i++) { ActivityFacility facility = aff.createActivityFacility(Id.create(featureId + "_" + i, ActivityFacility.class), coord); facilities.addActivityFacility(facility); @@ -255,7 +255,7 @@ public static ActivityFacilities createMeasuringPointsFromNetworkBounds(Network double xMax = boundingBox.getXMax(); double yMin = boundingBox.getYMin(); double yMax = boundingBox.getYMax(); - + ActivityFacilities measuringPoints = GridUtils.createGridLayerByGridSizeByBoundingBoxV2(xMin, yMin, xMax, yMax, cellSize); return measuringPoints; } @@ -263,7 +263,7 @@ public static ActivityFacilities createMeasuringPointsFromNetworkBounds(Network /** * Calculates the sum of the values of a given list. - * + * * @param valueList * @return sum */ @@ -279,7 +279,7 @@ public static double calculateSum(List valueList) { /** * Calculates Gini coefficient of the values of a given values. The Gini Coefficient is equals to the half of * the relative mean absolute difference (RMD). - * + * * @see * @see * @param valueList @@ -289,7 +289,7 @@ public static double calculateGiniCoefficient(List valueList) { int numberOfValues = valueList.size(); double sumOfValues = calculateSum(valueList); double arithmeticMean = sumOfValues / numberOfValues; - + double sumOfAbsoluteDifferences = 0.; for (double i : valueList) { for (double j : valueList) { @@ -310,24 +310,24 @@ public static double calculateGiniCoefficient(List valueList) { public static ActivityFacilities createFacilitiesFromPlans(Population population) { ActivityFacilitiesFactory aff = new ActivityFacilitiesFactoryImpl(); ActivityFacilities facilities = FacilitiesUtils.createActivityFacilities(); - + for(Person person : population.getPersons().values()) { for(Plan plan : person.getPlans()) { Id personId = person.getId(); - + for (PlanElement planElement : plan.getPlanElements()) { if (planElement instanceof Activity) { Activity activity = (Activity) planElement; - + Coord coord= activity.getCoord(); if (coord == null) { throw new NullPointerException("Activity does not have any coordinates."); } - + String activityType = activity.getType(); - + // In case an agent visits the same activity location twice, create another activity facility with a modified ID - Integer i = 1; + Integer i = 1; Id facilityId = Id.create(activityType + "_" + personId.toString() + "_" + i.toString(), ActivityFacility.class); while (facilities.getFacilities().containsKey(facilityId)) { i++; @@ -335,7 +335,7 @@ public static ActivityFacilities createFacilitiesFromPlans(Population population } ActivityFacility facility = aff.createActivityFacility(facilityId, activity.getCoord()); - + facility.addActivityOption(aff.createActivityOption(activityType)); facilities.addActivityFacility(facility); // log.info("Created activity with option of type " + activityType + " and ID " + facilityId + "."); @@ -353,7 +353,7 @@ public static String getDate() { String monthStr = month + ""; if (month < 10) monthStr = "0" + month; - String date = cal.get(Calendar.YEAR) + "-" + String date = cal.get(Calendar.YEAR) + "-" + monthStr + "-" + cal.get(Calendar.DAY_OF_MONTH); return date; } @@ -363,16 +363,16 @@ public static void assignAdditionalFacilitiesDataToMeasurePoint(ActivityFaciliti Map additionalFacilityData) { LOG.info("Start assigning additional facilities data to measure point."); GeometryFactory geometryFactory = new GeometryFactory(); - + for (ActivityFacilities additionalDataFacilities : additionalFacilityData.values()) { // Iterate over all additional data collections String additionalDataName = additionalDataFacilities.getName(); int additionalDataFacilitiesToAssign = additionalDataFacilities.getFacilities().size(); - + for (Id measurePointId : measurePoints.getFacilities().keySet()) { // Iterate over all measure points ActivityFacility measurePoint = measurePoints.getFacilities().get(measurePointId); measurePoint.getAttributes().putAttribute(additionalDataName, 0); Geometry geometry = measurePointGeometryMap.get(measurePointId); - + for (ActivityFacility facility : additionalDataFacilities.getFacilities().values()) { // Iterate over additional-data facilities Point point = geometryFactory.createPoint(new Coordinate(facility.getCoord().getX(), facility.getCoord().getY())); if (geometry.contains(point)) { diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/ConstantSpeedAccessibilityExpContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/ConstantSpeedAccessibilityExpContributionCalculator.java index 329155e30e4..90179912f8d 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/ConstantSpeedAccessibilityExpContributionCalculator.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/ConstantSpeedAccessibilityExpContributionCalculator.java @@ -29,7 +29,7 @@ import org.matsim.contrib.accessibility.utils.Distances; import org.matsim.contrib.accessibility.utils.NetworkUtil; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.algorithms.TransportModeNetworkFilter; import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; @@ -54,14 +54,14 @@ final class ConstantSpeedAccessibilityExpContributionCalculator implements Acces // private Network network; private Network subNetwork; private Scenario scenario; - + private double logitScaleParameter; - + private double betaModeTT; // in MATSim this is [utils/h]: cnScoringGroup.getTravelingBike_utils_hr() - cnScoringGroup.getPerforming_utils_hr() private double betaModeTD; // in MATSim this is 0 !!! since getMonetaryDistanceCostRateBike doesn't exist: private double constMode; private double modeSpeed_m_h = -1; - + private double betaWalkTT; private double betaWalkTD; private double walkSpeed_m_h; @@ -77,27 +77,27 @@ public ConstantSpeedAccessibilityExpContributionCalculator(final String mode, fi this.scenario = scenario; this.config = scenario.getConfig(); - final PlanCalcScoreConfigGroup planCalcScoreConfigGroup = config.planCalcScore() ; + final ScoringConfigGroup scoringConfigGroup = config.scoring() ; - if (planCalcScoreConfigGroup.getOrCreateModeParams(mode).getMonetaryDistanceRate() != 0.) { + if (scoringConfigGroup.getOrCreateModeParams(mode).getMonetaryDistanceRate() != 0.) { LOG.error("Monetary distance cost rate for " + mode + " different from zero, but not used in accessibility computations"); } - logitScaleParameter = planCalcScoreConfigGroup.getBrainExpBeta(); + logitScaleParameter = scoringConfigGroup.getBrainExpBeta(); - if (config.plansCalcRoute().getTeleportedModeSpeeds().get(mode) == null) { + if (config.routing().getTeleportedModeSpeeds().get(mode) == null) { LOG.error("No teleported mode speed for mode " + mode + " set."); } - this.modeSpeed_m_h = config.plansCalcRoute().getTeleportedModeSpeeds().get(mode) * 3600.; + this.modeSpeed_m_h = config.routing().getTeleportedModeSpeeds().get(mode) * 3600.; - final PlanCalcScoreConfigGroup.ModeParams modeParams = planCalcScoreConfigGroup.getOrCreateModeParams(mode); - betaModeTT = modeParams.getMarginalUtilityOfTraveling() - planCalcScoreConfigGroup.getPerforming_utils_hr(); + final ScoringConfigGroup.ModeParams modeParams = scoringConfigGroup.getOrCreateModeParams(mode); + betaModeTT = modeParams.getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr(); betaModeTD = modeParams.getMarginalUtilityOfDistance(); constMode = modeParams.getConstant(); - betaWalkTT = planCalcScoreConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - planCalcScoreConfigGroup.getPerforming_utils_hr(); - betaWalkTD = planCalcScoreConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfDistance(); - this.walkSpeed_m_h = config.plansCalcRoute().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600; + betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr(); + betaWalkTD = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfDistance(); + this.walkSpeed_m_h = config.routing().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600; } @@ -124,14 +124,14 @@ public void initialize(ActivityFacilities measuringPoints, ActivityFacilities op } - + @Override public void notifyNewOriginNode(Id fromNodeId, Double departureTime) { this.fromNode = subNetwork.getNodes().get(fromNodeId); this.lcptTravelDistance.calculate(subNetwork, fromNode, departureTime); } - + @Override public double computeContributionOfOpportunity(ActivityFacility origin, Map, AggregationObject> aggregatedOpportunities, Double departureTime) { diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/LeastCostPathCalculatorAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/LeastCostPathCalculatorAccessibilityContributionCalculator.java index 74dbdfeffa2..ee526dafc6d 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/LeastCostPathCalculatorAccessibilityContributionCalculator.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/LeastCostPathCalculatorAccessibilityContributionCalculator.java @@ -5,7 +5,7 @@ import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Node; import org.matsim.contrib.accessibility.utils.AggregationObject; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.facilities.ActivityFacilities; import org.matsim.facilities.ActivityFacility; @@ -18,7 +18,7 @@ */ final class LeastCostPathCalculatorAccessibilityContributionCalculator implements AccessibilityContributionCalculator { private final LeastCostPathCalculator leastCostPathCalculator; - private final PlanCalcScoreConfigGroup planCalcScoreConfigGroup; + private final ScoringConfigGroup scoringConfigGroup; private Node fromNode; private Double departureTime; private Scenario scenario; @@ -27,8 +27,8 @@ final class LeastCostPathCalculatorAccessibilityContributionCalculator implement Map, AggregationObject> aggregatedOpportunities; - public LeastCostPathCalculatorAccessibilityContributionCalculator(PlanCalcScoreConfigGroup planCalcScoreConfigGroup, LeastCostPathCalculator leastCostPathCalculator, Scenario scenario) { - this.planCalcScoreConfigGroup = planCalcScoreConfigGroup; + public LeastCostPathCalculatorAccessibilityContributionCalculator(ScoringConfigGroup scoringConfigGroup, LeastCostPathCalculator leastCostPathCalculator, Scenario scenario) { + this.scoringConfigGroup = scoringConfigGroup; this.leastCostPathCalculator = leastCostPathCalculator; this.scenario = scenario; } @@ -55,7 +55,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, for (final AggregationObject destination : aggregatedOpportunities.values()) { LeastCostPathCalculator.Path path = leastCostPathCalculator.calcLeastCostPath(fromNode, (Node) destination.getNearestBasicLocation(), departureTime, null, null); - expSum += destination.getSum() * Math.exp(planCalcScoreConfigGroup.getBrainExpBeta() * path.travelCost); + expSum += destination.getSum() * Math.exp(scoringConfigGroup.getBrainExpBeta() * path.travelCost); } return expSum; } @@ -64,7 +64,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, @Override public LeastCostPathCalculatorAccessibilityContributionCalculator duplicate() { LeastCostPathCalculatorAccessibilityContributionCalculator leastCostPathCalculatorAccessibilityContributionCalculator = - new LeastCostPathCalculatorAccessibilityContributionCalculator(this.planCalcScoreConfigGroup, this.leastCostPathCalculator, this.scenario); + new LeastCostPathCalculatorAccessibilityContributionCalculator(this.scoringConfigGroup, this.leastCostPathCalculator, this.scenario); return leastCostPathCalculatorAccessibilityContributionCalculator; } diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/NetworkModeAccessibilityExpContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/NetworkModeAccessibilityExpContributionCalculator.java index cfaf0906478..ff5aee3d9fa 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/NetworkModeAccessibilityExpContributionCalculator.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/NetworkModeAccessibilityExpContributionCalculator.java @@ -12,7 +12,7 @@ import org.matsim.contrib.accessibility.utils.*; import org.matsim.contrib.roadpricing.RoadPricingScheme; import org.matsim.core.config.groups.NetworkConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.gbl.Gbl; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.algorithms.TransportModeNetworkFilter; @@ -40,7 +40,7 @@ final class NetworkModeAccessibilityExpContributionCalculator implements Accessi private final Scenario scenario; private final TravelDisutility travelDisutility; - private final PlanCalcScoreConfigGroup planCalcScoreConfigGroup; + private final ScoringConfigGroup scoringConfigGroup; private final NetworkConfigGroup networkConfigGroup; private Network subNetwork; @@ -68,7 +68,7 @@ public NetworkModeAccessibilityExpContributionCalculator(String mode, final Trav Gbl.assertNotNull(travelDisutilityFactory); this.travelDisutility = travelDisutilityFactory.createTravelDisutility(travelTime); - planCalcScoreConfigGroup = scenario.getConfig().planCalcScore(); + scoringConfigGroup = scenario.getConfig().scoring(); networkConfigGroup = scenario.getConfig().network(); RoadPricingScheme scheme = (RoadPricingScheme) scenario.getScenarioElement( RoadPricingScheme.ELEMENT_NAME ); @@ -78,9 +78,9 @@ public NetworkModeAccessibilityExpContributionCalculator(String mode, final Trav //FastMultiNodeDijkstraFactory fastMultiNodeDijkstraFactory = new FastMultiNodeDijkstraFactory(true); //this.multiNodePathCalculator = (MultiNodePathCalculator) fastMultiNodeDijkstraFactory.createPathCalculator(network, travelDisutility, travelTime); - betaWalkTT = planCalcScoreConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - planCalcScoreConfigGroup.getPerforming_utils_hr(); + betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr(); - this.walkSpeed_m_s = scenario.getConfig().plansCalcRoute().getTeleportedModeSpeeds().get(TransportMode.walk); + this.walkSpeed_m_s = scenario.getConfig().routing().getTeleportedModeSpeeds().get(TransportMode.walk); } @@ -137,7 +137,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, double congestedCarUtilityRoad2Node = -travelDisutility.getLinkTravelDisutility(nearestLink, departureTime, null, null) * distanceFraction; // Combine all utility components (using the identity: exp(a+b) = exp(a) * exp(b)) - double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, planCalcScoreConfigGroup); + double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, scoringConfigGroup); for (final AggregationObject destination : aggregatedOpportunities.values()) { @@ -151,7 +151,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, // Pre-computed effect of all opportunities reachable from destination network node double sumExpVjkWalk = destination.getSum(); - expSum += Math.exp(this.planCalcScoreConfigGroup.getBrainExpBeta() * (walkUtilityMeasuringPoint2Road + modeSpecificConstant + expSum += Math.exp(this.scoringConfigGroup.getBrainExpBeta() * (walkUtilityMeasuringPoint2Road + modeSpecificConstant + congestedCarUtilityRoad2Node + congestedCarUtility)) * sumExpVjkWalk; } return expSum; diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java index b64c6fa7b4e..6fcd4466276 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java @@ -25,7 +25,7 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.accessibility.utils.AggregationObject; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.gbl.Gbl; import org.matsim.core.utils.geometry.CoordUtils; import org.matsim.facilities.*; @@ -44,7 +44,7 @@ class SwissRailRaptorAccessibilityContributionCalculator implements Accessibilit private static final Logger LOG = LogManager.getLogger( SwissRailRaptorAccessibilityContributionCalculator.class ); private SwissRailRaptor raptor; private String mode; - private PlanCalcScoreConfigGroup planCalcScoreConfigGroup; + private ScoringConfigGroup scoringConfigGroup; private Scenario scenario; Map, ArrayList> aggregatedMeasurePoints; @@ -58,7 +58,7 @@ class SwissRailRaptorAccessibilityContributionCalculator implements Accessibilit Map, Collection> stopsPerAggregatedOpportunity = new LinkedHashMap<>(); - public SwissRailRaptorAccessibilityContributionCalculator(String mode, PlanCalcScoreConfigGroup planCalcScoreConfigGroup, Scenario scenario) { + public SwissRailRaptorAccessibilityContributionCalculator(String mode, ScoringConfigGroup scoringConfigGroup, Scenario scenario) { this.mode = mode; TransitSchedule schedule = scenario.getTransitSchedule(); @@ -69,12 +69,12 @@ public SwissRailRaptorAccessibilityContributionCalculator(String mode, PlanCalcS this.raptorData = SwissRailRaptorData.create(schedule, null, raptorConfig, ptNetwork, null); this.raptor = new SwissRailRaptor.Builder(raptorData, scenario.getConfig()).build(); - this.planCalcScoreConfigGroup = planCalcScoreConfigGroup; + this.scoringConfigGroup = scoringConfigGroup; this.scenario = scenario; - this.betaWalkTT = planCalcScoreConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - planCalcScoreConfigGroup.getPerforming_utils_hr(); + this.betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr(); - this.walkSpeed_m_h = scenario.getConfig().plansCalcRoute().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600.; + this.walkSpeed_m_h = scenario.getConfig().routing().getTeleportedModeSpeeds().get(TransportMode.walk) * 3600.; } @@ -167,8 +167,8 @@ public double computeContributionOfOpportunity(ActivityFacility origin, //check whether direct walk time is cheaper travelCost = Math.min(travelCost, directWalkCost); - double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, planCalcScoreConfigGroup); - expSum += Math.exp(this.planCalcScoreConfigGroup.getBrainExpBeta() * (-travelCost + modeSpecificConstant)); + double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, scoringConfigGroup); + expSum += Math.exp(this.scoringConfigGroup.getBrainExpBeta() * (-travelCost + modeSpecificConstant)); } return expSum; } @@ -177,7 +177,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, @Override public SwissRailRaptorAccessibilityContributionCalculator duplicate() { SwissRailRaptorAccessibilityContributionCalculator swissRailRaptorAccessibilityContributionCalculator = - new SwissRailRaptorAccessibilityContributionCalculator(this.mode, this.planCalcScoreConfigGroup, this.scenario); + new SwissRailRaptorAccessibilityContributionCalculator(this.mode, this.scoringConfigGroup, this.scenario); swissRailRaptorAccessibilityContributionCalculator.aggregatedMeasurePoints = this.aggregatedMeasurePoints; swissRailRaptorAccessibilityContributionCalculator.aggregatedOpportunities = this.aggregatedOpportunities; swissRailRaptorAccessibilityContributionCalculator.stopsPerAggregatedOpportunity = this.stopsPerAggregatedOpportunity; diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TravelTimeBasedTravelDisutility.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TravelTimeBasedTravelDisutility.java index 34ee8375753..6a70a5911fa 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TravelTimeBasedTravelDisutility.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TravelTimeBasedTravelDisutility.java @@ -18,30 +18,30 @@ * *********************************************************************** */ /** - * + * */ package org.matsim.contrib.accessibility; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.router.util.TravelDisutility; import org.matsim.core.router.util.TravelTime; import org.matsim.vehicles.Vehicle; /** * A simple cost calculator which only respects time to calculate generalized costs - * This is based on org.matsim.core.router.costcalculators.TravelTimeAndDistanceBasedTravelDisutility + * This is based on org.matsim.core.router.costcalculators.TravelTimeAndDistanceBasedTravelDisutility * * @author mrieser, thomas */ class TravelTimeBasedTravelDisutility implements TravelDisutility{ - + protected final TravelTime timeCalculator; private final double marginalCostOfTime; - public TravelTimeBasedTravelDisutility(final TravelTime timeCalculator, PlanCalcScoreConfigGroup cnScoringGroup) { + public TravelTimeBasedTravelDisutility(final TravelTime timeCalculator, ScoringConfigGroup cnScoringGroup) { this.timeCalculator = timeCalculator; /* Usually, the travel-utility should be negative (it's a disutility) * but the cost should be positive. Thus negate the utility. diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TripRouterAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TripRouterAccessibilityContributionCalculator.java index 0f3dece8928..2f027d9863c 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TripRouterAccessibilityContributionCalculator.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/TripRouterAccessibilityContributionCalculator.java @@ -38,7 +38,7 @@ import org.matsim.contrib.accessibility.utils.Distances; import org.matsim.contrib.accessibility.utils.NetworkUtil; import org.matsim.core.config.groups.NetworkConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.gbl.Gbl; import org.matsim.core.network.NetworkUtils; import org.matsim.core.router.TripRouter; @@ -60,7 +60,7 @@ class TripRouterAccessibilityContributionCalculator implements AccessibilityCont private static final Logger LOG = LogManager.getLogger( TripRouterAccessibilityContributionCalculator.class ); private TripRouter tripRouter ; private String mode; - private PlanCalcScoreConfigGroup planCalcScoreConfigGroup; + private ScoringConfigGroup scoringConfigGroup; private NetworkConfigGroup networkConfigGroup; private Scenario scenario; @@ -79,18 +79,18 @@ class TripRouterAccessibilityContributionCalculator implements AccessibilityCont private final TravelTime travelTime; - public TripRouterAccessibilityContributionCalculator(String mode, TripRouter tripRouter, PlanCalcScoreConfigGroup planCalcScoreConfigGroup, Scenario scenario, - TravelTime travelTime, TravelDisutilityFactory travelDisutilityFactory) { + public TripRouterAccessibilityContributionCalculator(String mode, TripRouter tripRouter, ScoringConfigGroup scoringConfigGroup, Scenario scenario, + TravelTime travelTime, TravelDisutilityFactory travelDisutilityFactory) { LOG.warn("This is currently heavliy oriented on the need of car-based computatations. Revise beofre using for other modes!"); this.mode = mode; this.tripRouter = tripRouter; - this.planCalcScoreConfigGroup = planCalcScoreConfigGroup; + this.scoringConfigGroup = scoringConfigGroup; this.networkConfigGroup = scenario.getConfig().network(); this.scenario = scenario; - betaWalkTT = planCalcScoreConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - planCalcScoreConfigGroup.getPerforming_utils_hr(); + betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr(); - this.walkSpeed_m_s = scenario.getConfig().plansCalcRoute().getTeleportedModeSpeeds().get(TransportMode.walk); + this.walkSpeed_m_s = scenario.getConfig().routing().getTeleportedModeSpeeds().get(TransportMode.walk); this.travelTime = travelTime; this.travelDisutilityFactory = travelDisutilityFactory; @@ -152,21 +152,21 @@ public double computeContributionOfOpportunity(ActivityFacility origin, // Note: The following computation where the end link length is added is only correct once the end link is removed from the route // in the NetworkRoutingModule (route.setDistance(RouteUtils.calcDistance(route, 1.0, 0.0, this.network));) - if (this.planCalcScoreConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfDistance() != 0.) { + if (this.scoringConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfDistance() != 0.) { LOG.warn("A computation including a marginal utility of distance will only be correct if the route time/distance" + "inconsistency in the NetworkRoutingModule is solved."); } - utility += (leg.getRoute().getDistance() + endLinkLength) * this.planCalcScoreConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfDistance(); - utility += (leg.getRoute().getTravelTime().seconds() + estimatedEndLinkTT) * this.planCalcScoreConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfTraveling() / 3600.; - utility += -(leg.getRoute().getTravelTime().seconds() + estimatedEndLinkTT) * this.planCalcScoreConfigGroup.getPerforming_utils_hr() / 3600.; + utility += (leg.getRoute().getDistance() + endLinkLength) * this.scoringConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfDistance(); + utility += (leg.getRoute().getTravelTime().seconds() + estimatedEndLinkTT) * this.scoringConfigGroup.getModes().get(leg.getMode()).getMarginalUtilityOfTraveling() / 3600.; + utility += -(leg.getRoute().getTravelTime().seconds() + estimatedEndLinkTT) * this.scoringConfigGroup.getPerforming_utils_hr() / 3600.; } // Utility based on opportunities that are attached to destination node double sumExpVjkWalk = destination.getSum(); // exp(beta * a) * exp(beta * b) = exp(beta * (a+b)) - double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, planCalcScoreConfigGroup); - expSum += Math.exp(this.planCalcScoreConfigGroup.getBrainExpBeta() * (utility + modeSpecificConstant + walkUtilityMeasuringPoint2Road + congestedCarUtilityRoad2Node)) * sumExpVjkWalk; + double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(mode, scoringConfigGroup); + expSum += Math.exp(this.scoringConfigGroup.getBrainExpBeta() * (utility + modeSpecificConstant + walkUtilityMeasuringPoint2Road + congestedCarUtilityRoad2Node)) * sumExpVjkWalk; } return expSum; @@ -176,7 +176,7 @@ public double computeContributionOfOpportunity(ActivityFacility origin, @Override public TripRouterAccessibilityContributionCalculator duplicate() { TripRouterAccessibilityContributionCalculator tripRouterAccessibilityContributionCalculator = - new TripRouterAccessibilityContributionCalculator(this.mode, this.tripRouter, this.planCalcScoreConfigGroup, + new TripRouterAccessibilityContributionCalculator(this.mode, this.tripRouter, this.scoringConfigGroup, this.scenario, this.travelTime, this.travelDisutilityFactory); tripRouterAccessibilityContributionCalculator.subNetwork = this.subNetwork; tripRouterAccessibilityContributionCalculator.aggregatedMeasurePoints = this.aggregatedMeasurePoints; diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/run/RunAccessibilityExample.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/run/RunAccessibilityExample.java index 53d94a2c1de..7db337954bd 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/run/RunAccessibilityExample.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/run/RunAccessibilityExample.java @@ -46,7 +46,7 @@ public static void main(String[] args) { throw new RuntimeException("No config.xml file provided. The config file needs to reference a network file and a facilities file.") ; } Config config = ConfigUtils.loadConfig(args[0]); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); AccessibilityConfigGroup accConfig = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class ) ; accConfig.setComputingAccessibilityForMode(Modes4Accessibility.freespeed, true); @@ -54,11 +54,11 @@ public static void main(String[] args) { run(scenario); // The run method is extracted so that a test can operate on it. } - + public static void run(final Scenario scenario) { List activityTypes = AccessibilityUtils.collectAllFacilityOptionTypes(scenario); LOG.info("The following activity types were found: " + activityTypes); - + Controler controler = new Controler(scenario); for (final String actType : activityTypes) { // Add an overriding module for each activity type. final AccessibilityModule module = new AccessibilityModule(); diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GeoJsonPolygonFeatureWriter.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GeoJsonPolygonFeatureWriter.java index c022be98067..f0e3dc08db3 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GeoJsonPolygonFeatureWriter.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GeoJsonPolygonFeatureWriter.java @@ -1,6 +1,6 @@ package org.matsim.contrib.accessibility.utils; -import org.json.simple.JSONValue; +import com.google.gson.Gson; import org.matsim.api.core.v01.Coord; import java.util.*; @@ -34,7 +34,7 @@ public String asGeoJson() { featureCollectionMap.put("features", featuresList); featureCollectionMap.put("crs", parseCRS()); featureCollectionMap.put("bbox", boundingBox.getBoundingBox()); - return JSONValue.toJSONString(featureCollectionMap); + return new Gson().toJson(featureCollectionMap); } private List> parseFeatureList() { diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GnuplotScriptWriter.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GnuplotScriptWriter.java index d9c1c029634..797211edc2b 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GnuplotScriptWriter.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/GnuplotScriptWriter.java @@ -34,7 +34,7 @@ */ public final class GnuplotScriptWriter { private static final Logger log = LogManager.getLogger( GnuplotScriptWriter.class ) ; - + private GnuplotScriptWriter() {} // do not instantiate public static void createGnuplotScript(Config config, List activityTypes) { @@ -49,37 +49,37 @@ public static void createGnuplotScript(Config config, List activityTypes log.error("skipping everything except freespeed for debugging purposes; remove in production code. dz, nov'14") ; continue ; } - + // the following might be made configurable if this is ever re-used: Boolean doPopulationWeightedPlot = true ; Boolean doNonPopulationWeightedPlot = true ; - - + + if (doPopulationWeightedPlot == false && doNonPopulationWeightedPlot == false) { throw new RuntimeException("At least one plot (pop-weighted or non-pop-weighted) needs to be activated."); } - + // produce gnuplot scripts try { - BufferedWriter writer = IOUtils.getBufferedWriter( config.controler().getOutputDirectory() + "/" + actType + BufferedWriter writer = IOUtils.getBufferedWriter( config.controller().getOutputDirectory() + "/" + actType + "/" + mode + "/t.gpl" ) ; // pm3d is an splot style for drawing palette-mapped 3d and 4d data as color/gray maps and surfaces (docu p.134) // To use pm3d coloring to generate a two-dimensional plot rather than a 3D surface, use set view map // or set pm3d map (p.135) writer.write("set pm3d map\n"); - + // flush { begin | center | end } writer.write("set pm3d flush begin\n") ; - + // corners2color { mean|geomean|median|min|max|c1|c2|c3|c4 } writer.write("set pm3d corners2color c1\n"); - + // The set style data command changes the default plotting style for data plots (docu p.148) // There are many plotting styles available in gnuplot. They are listed alphabetically below. The commands // set style data and set style function change the default plotting style for subsequent plot and splot // commands. (docu p.42) writer.write("set style data pm3d\n"); - + // Palette is a color storage for use by pm3d, filled color contours or polygons, color histograms, color gradient // background, and whatever it is or it will be implemented (docu p.137) // Gray-to-rgb mapping can be manually set by use of palette defined: A color gradient is defined and used @@ -87,86 +87,86 @@ public static void createGnuplotScript(Config config, List activityTypes // space [0,1]x[0,1]x[0,1]. You must specify the gray values and the corresponding RGB values between which // linear interpolation will be done (docu p.139) writer.write("set palette defined ( 0. '#ff0000', 0.82 '#ff0000', 0.86 '#00ff00', 0.9 '#0000ff', 1.0 '#0000ff' )\n"); - + // The set zrange command sets the range that will be displayed on the z axis. The zrange is used only by // splot and is ignored by plot (docu p.166) writer.write("#set zrange [-40:10]\n"); - + // The set cbrange command sets the range of values which are colored using the current palette by styles // with pm3d, with image and with palette. Values outside of the color range use color of the nearest // extreme (docu p.167) writer.write("#set cbrange [-0:10]\n"); - + // gnuplot supports many different graphics devices. Use set terminal to tell gnuplot what kind of output // to generate (docu p.152) // This terminal produces files in the Adobe Portable Document Format (PDF), useable for printing or display // with tools like Acrobat Reader (docu p.206) //writer.write("set term pdf size 25cm,20cm\n"); writer.write("set term pdf font 'Helvetica,6' size 25cm,20cm\n"); - + // The set view command sets the viewing angle for splots. It controls how the 3D coordinates of the plot are // mapped into the 2D screen space. It provides controls for both rotation and scaling of the plotted data, but // supports orthographic projections only (docu p.156) writer.write("#set view 45,30;\n"); writer.write("\n") ; - + // see docu p.137 writer.write("# set palette model HSV functions gray, 1, 1\n"); writer.write("\n"); - + // New user-defined variables and functions of one through twelve variables may be declared and used anywhere, // including on the plot command itself (docu p.30) // define minimum and maximum functions writer.write("min(a,b) = (a < b) ? a : b\n"); writer.write("max(a,b) = (a < b) ? b : a\n"); - + // define two variables writer.write("accmin=3 ; # accessibilities below this are red\n"); writer.write("accmax=9 ; # accessibilities above this are blue. max is around 12\n"); - + // define a function to determine the shade of gray. gray(acc) will have a value from 0 through 1 // Acc values equal to or below accmin lead to 0; acc values equal to or above accmax lead to 1 writer.write("gray(acc) = 2.*min( 1, max(0 , (acc-accmin)/(accmax-accmin) ) ) ;\n") ; writer.write("# I have no idea why this needs to be multiplied by 2. kai, feb'14\n") ; writer.write("\n") ; - + // consider population density // define two variables writer.write("densmax=1000 ; # 2726 is the maximum value in NMB\n") ; writer.write("maxwhite = 240 ; # 255 means that we go all the way to full white\n") ; - + while (doPopulationWeightedPlot == true || doNonPopulationWeightedPlot == true) { // define a function that gets the higher the smaller the population density // maxwhite*1 for pop dens = 0; maxwhite*0 for pop dens higher than densmax if (doPopulationWeightedPlot == true) { writer.write("val(dens) = max(0,maxwhite*(densmax-dens)/densmax) ;\n") ; - + // By default, screens are displayed to the standard output. The set output command redirects the display // to the specified file or device (docu p.132) writer.write("set out 'accessibility-pop-weighted.pdf'\n"); - + // The set title command produces a plot title that is centered at the top of the plot. set title is a special // case of set label (docu p.155) //writer.write("set title 'accessibility to " + actType + " by " + mode + " (population-weighted)'\n") ; - + doPopulationWeightedPlot = false; - + } else if (doNonPopulationWeightedPlot == true) { writer.write("val(dens) = 0. ; # unset this comment to get the non-pop-weighted version (for paper)\n"); writer.write("set out 'accessibility.pdf'\n"); //writer.write("set title 'accessibility to " + actType + " by " + mode + " (non-population-weighted)'\n") ; - + doNonPopulationWeightedPlot = false; } writer.write("\n") ; - + // define three color functions // so far not clear to me where the functions come from, dz mai14 writer.write("blue(acc,dens) = min(255, val(dens)+255*max(0,1.-2.*gray(acc)) ) ;\n") ; writer.write("green(acc,dens) = min(255, val(dens)+255*max(0,min(2.*gray(acc),2.-2.*gray(acc))) ) ;\n") ; writer.write("red(acc,dens) = min(255, val(dens)+255*max(0,2.*gray(acc)-1) ) ;\n") ; writer.write("\n") ; - + // define color function based on accessibility and population density // int(x) = integer part of x, truncated toward zero (docu p.26) // Example: rgb(r,g,b) = 65536 * int(r) + 256 * int(g) + int(b) (docu p.35) @@ -175,8 +175,8 @@ public static void createGnuplotScript(Config config, List activityTypes writer.write("\n") ; writer.write("unset colorbox ; # useless with lc rgb variable\n") ; writer.write("\n") ; // end new - - // plot csv file based on three values; first two are coordinates; third takes into account accessibility and + + // plot csv file based on three values; first two are coordinates; third takes into account accessibility and // population density and is calculated based on above-defined rgb formula // The "lc rgbcolor variable" tells the program to read RGB color information for each line in the data file. // This requires a corresponding additional column in the using specifier. The extra column is interpreted as a @@ -186,27 +186,27 @@ public static void createGnuplotScript(Config config, List activityTypes // writer.write("splot \"accessibilities.csv\" u 1:2:(rgb($3,$8)) lc rgb variable\n"); // writer.write("splot \"accessibilities.csv\" u 1:2:(rgb($3,$8)) notitle lc rgb variable\n"); } - + writer.close(); } catch (Exception ee ) { - ee.printStackTrace(); + ee.printStackTrace(); throw new RuntimeException( "writing t.gpl did not work") ; } - - + + // start running gnuplot with above-created script - + // If working on a Windows system, it is important that the environment variable PATH includes the gnuplot folder // so that gnuplot can be run from the folder where the data is stored (otherwise the relative paths won't work) String cmd = "gnuplot t.gpl"; - + // Doesn't work if root of directory is not passed - String stdoutFileName = config.controler().getOutputDirectory() + actType + "/" + mode + "/gnuplot.log"; + String stdoutFileName = config.controller().getOutputDirectory() + actType + "/" + mode + "/gnuplot.log"; // String stdoutFileName = config.controler().getOutputDirectory() + "gnuplot.log"; int timeout = 99999; - + // 4th argument = workingDirectory. Since we are working with relative paths, workingDirectory needs to be passed. - ExeRunner.run(cmd, stdoutFileName, timeout, config.controler().getOutputDirectory() + actType + "/" + mode); + ExeRunner.run(cmd, stdoutFileName, timeout, config.controller().getOutputDirectory() + actType + "/" + mode); } } } diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/LeastCostPathTreeExtended.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/LeastCostPathTreeExtended.java index 0378f9c7f71..74d2dd7d216 100644 --- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/LeastCostPathTreeExtended.java +++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/utils/LeastCostPathTreeExtended.java @@ -18,7 +18,7 @@ * *********************************************************************** */ /** - * + * */ package org.matsim.contrib.accessibility.utils; @@ -36,7 +36,7 @@ import org.matsim.contrib.matrixbasedptrouter.utils.TempDirectoryUtil; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.network.NetworkUtils; import org.matsim.core.router.util.TravelDisutility; @@ -54,17 +54,17 @@ * accumulate distance and toll separately along the route. *

* To re-iterate: This class does not lead to a different tree than the base class. - * + * * @author thomas - * + * */ public final class LeastCostPathTreeExtended extends LeastCostPathTree{ - + protected static final Logger log = LogManager.getLogger(LeastCostPathTreeExtended.class); - + private Map, NodeDataExtended> nodeDataExt = null; private RoadPricingScheme scheme = null; - + /** * constructor * @param controler Controler, to get the RoadPricingScheme if available @@ -75,13 +75,13 @@ public LeastCostPathTreeExtended(final TravelTime tt, final TravelDisutility td, } /** - * + * * @param network * @param origin * @param time */ public final void calculateExtended(final Network network, final Node origin, final double time) { - + this.nodeDataExt = new ConcurrentHashMap, NodeDataExtended>((int) (network.getNodes().size() * 1.1), 0.95f); if(this.nodeDataExt.get(origin.getId()) == null){ NodeDataExtended nde = new NodeDataExtended(); @@ -89,17 +89,17 @@ public final void calculateExtended(final Network network, final Node origin, fi nde.toll = 0.; this.nodeDataExt.put(origin.getId(), nde); } - + calculate(network, origin, time); } - + /** - * @param link - * @param currTime + * @param link + * @param currTime */ @Override protected final void additionalComputationsHook( final Link link, final double currTime ) { - + Node fromNode = link.getFromNode(); // get current distance and toll so far NodeDataExtended nde = nodeDataExt.get( fromNode.getId() ); @@ -113,10 +113,10 @@ protected final void additionalComputationsHook( final Link link, final double c if(cost != null) toll = cost.amount; } - + double visitDistance = currDistance + link.getLength(); double visitToll = currToll + toll; - + // put new nodes into nodeDataExtended Node toNode = link.getToNode(); NodeDataExtended ndeNew = this.nodeDataExt.get( toNode.getId() ); @@ -126,19 +126,19 @@ protected final void additionalComputationsHook( final Link link, final double c } ndeNew.visit(visitDistance, visitToll); } - + // //////////////////////////////////////////////////////////////////// // get methods // //////////////////////////////////////////////////////////////////// - + public final Map, NodeDataExtended> getTreeExtended() { return this.nodeDataExt; } - + // //////////////////////////////////////////////////////////////////// // inner classes // //////////////////////////////////////////////////////////////////// - + public static class NodeDataExtended { private double distance = 0.; // meter private double toll = 0.; // money @@ -161,11 +161,11 @@ public final double getToll() { return this.toll; } } - + // //////////////////////////////////////////////////////////////////// - // testing + // testing // //////////////////////////////////////////////////////////////////// - + /** * for testing * @param args @@ -173,13 +173,13 @@ public final double getToll() { public static void main(String args[]){ // create temp output dir String tmpOutputLocation = TempDirectoryUtil.createCustomTempDirectory("test"); - + // create network Network network = LeastCostPathTreeExtended.createTriangularNetwork(); // create scenario Config config = ConfigUtils.createConfig(); // set last iteration and output - ControlerConfigGroup controlerCG = (ControlerConfigGroup) config.getModule(ControlerConfigGroup.GROUP_NAME); + ControllerConfigGroup controlerCG = (ControllerConfigGroup) config.getModule(ControllerConfigGroup.GROUP_NAME); controlerCG.setLastIteration( 1 ); controlerCG.setOutputDirectory( tmpOutputLocation ); // set scenario @@ -190,7 +190,7 @@ public static void main(String args[]){ controler.run(); // init lcpte LeastCostPathTreeExtended lcpte = new LeastCostPathTreeExtended(controler.getLinkTravelTimes(), controler.createTravelDisutilityCalculator(), (RoadPricingSchemeImpl) controler.getScenario().getScenarioElement(RoadPricingScheme.ELEMENT_NAME)); - + // contains all network nodes Map, ? extends Node> networkNodesMap = network.getNodes(); Id originNodeID = Id.create(1, Node.class); @@ -201,15 +201,15 @@ public static void main(String args[]){ double disutility = lcpte.getTree().get( destinationNodeId ).getCost(); double distance = lcpte.getTreeExtended().get( destinationNodeId ).getDistance(); double toll = lcpte.getTreeExtended().get( destinationNodeId ).getToll(); - + log.info("Time = " + time); - log.info("Disutility = " + disutility); + log.info("Disutility = " + disutility); log.info("Distance = " + distance ); log.info("Toll = " + toll); - + TempDirectoryUtil.cleanUpCustomTempDirectories(); } - + /** * creating a test network * the path 1,2,4 has a total length of 1000m with a free speed travel time of 10m/s @@ -226,12 +226,12 @@ private static Network createTriangularNetwork() { * / \ * / \ *(1)-------(3)-------(4) - *(50m,0.1m/s)(50m,0.1m/s) + *(50m,0.1m/s)(50m,0.1m/s) */ MutableScenario scenario = (MutableScenario) ScenarioUtils.createScenario(ConfigUtils.createConfig()); Network network = (Network) scenario.getNetwork(); - + // add nodes Node node1 = NetworkUtils.createAndAddNode(network, Id.create(1, Node.class), new Coord(0, 0)); Node node2 = NetworkUtils.createAndAddNode(network, Id.create(2, Node.class), new Coord(50, 100)); @@ -251,8 +251,8 @@ private static Network createTriangularNetwork() { final Node fromNode3 = node3; final Node toNode3 = node4; NetworkUtils.createAndAddLink(network,Id.create(4, Link.class), fromNode3, toNode3, 50.0, 0.1, 3600.0, (double) 1 ); - + return network; } - + } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/LeastCostPathTreeTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/LeastCostPathTreeTest.java index fcd995bd7b7..23d32279ec6 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/LeastCostPathTreeTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/LeastCostPathTreeTest.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Map; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Node; @@ -24,9 +24,9 @@ public class LeastCostPathTreeTest { Scenario scenario; - + @Test - public void testRouteChoiceTestSpanningTree(){ + void testRouteChoiceTestSpanningTree(){ this.scenario = new ScenarioBuilder(ConfigUtils.createConfig()).setNetwork(CreateTestNetwork.createTriangularNetwork()).build() ; compareRouteChoices(); } @@ -55,11 +55,11 @@ private void compareRouteChoices(){ printResults(arrivalTime, travelTime); // travel time = cost = (50s+50s) = 100s // check route (visited nodes should be 1,2,4) List> spTimeVisitedNodes = getVisitedNodes(lcptTime, destination, "Travel Time"); - Assert.assertTrue( containsNode(spTimeVisitedNodes, Id.create("2", Node.class))); + Assertions.assertTrue( containsNode(spTimeVisitedNodes, Id.create("2", Node.class))); // check travel duration - Assert.assertTrue( travelTime == 100 ); + Assertions.assertTrue( travelTime == 100 ); // check travel time - Assert.assertTrue( arrivalTime - departureTime == 100 ); + Assertions.assertTrue( arrivalTime - departureTime == 100 ); lcptDistance.calculate(this.scenario.getNetwork(), origin, departureTime); double arrivalTimeTD = lcptDistance.getTree().get( destination.getId() ).getTime(); @@ -67,11 +67,11 @@ private void compareRouteChoices(){ printResults(arrivalTimeTD, travelDistance); // travel time = 1000s, cost = (50m+50m) = 100m // check route ( visited nodes should be 1,3,4) List> spDistenceVisitedNodes = getVisitedNodes(lcptDistance, destination, "Travel Distance"); - Assert.assertTrue( containsNode(spDistenceVisitedNodes, Id.create("3", Node.class))); + Assertions.assertTrue( containsNode(spDistenceVisitedNodes, Id.create("3", Node.class))); // check travel distance - Assert.assertTrue( travelDistance == 100 ); + Assertions.assertTrue( travelDistance == 100 ); // check travel time - Assert.assertTrue( arrivalTimeTD - departureTime == 1000 ); + Assertions.assertTrue( arrivalTimeTD - departureTime == 1000 ); } private void printResults(double tt, double tc){ diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/grid/SpatialGridTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/grid/SpatialGridTest.java index b9f82d4cfa1..74bae0a5363 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/grid/SpatialGridTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/grid/SpatialGridTest.java @@ -1,8 +1,8 @@ package org.matsim.contrib.accessibility.grid; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.accessibility.SpatialGrid; import org.matsim.contrib.matrixbasedptrouter.utils.BoundingBox; @@ -11,13 +11,14 @@ public class SpatialGridTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); private double cellSize = 10.; - @Test public void testSpatialGrid() { + @Test + void testSpatialGrid() { // get network Network network = CreateTestNetwork.createTestNetwork(); @@ -31,11 +32,11 @@ public class SpatialGridTest { // get number of rows int rows = testGrid.getNumRows(); double numOfExpectedRows = ((nbb.getYMax() - nbb.getYMin()) / cellSize) + 1; - Assert.assertTrue(rows == numOfExpectedRows); + Assertions.assertTrue(rows == numOfExpectedRows); // get number of columns int cols = testGrid.getNumCols(0); double numOfExpectedCols = ((nbb.getXMax() - nbb.getXMin()) / cellSize) + 1; - Assert.assertTrue(cols == numOfExpectedCols); + Assertions.assertTrue(cols == numOfExpectedCols); } } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulas2Test.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulas2Test.java index b561798a16d..f7e6672c053 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulas2Test.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulas2Test.java @@ -22,9 +22,9 @@ */ package org.matsim.contrib.accessibility.logsumComputations; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; /** @@ -33,12 +33,12 @@ */ public class CompareLogsumFormulas2Test { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - - @Test public void testLogsumFormulas(){ + @Test + void testLogsumFormulas(){ double walkTravelTime2Network = 2.; // 2min double travelTimeOnNetwork = 6.; // 6min @@ -66,7 +66,7 @@ public class CompareLogsumFormulas2Test { double Sum2 =PreFactor * AggregationSum; System.out.println(Sum2); - Assert.assertTrue( Sum1 == Sum2 ); + Assertions.assertTrue( Sum1 == Sum2 ); } } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulasTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulasTest.java index 8c85aabbe9f..19501ebb49f 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulasTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/CompareLogsumFormulasTest.java @@ -22,9 +22,9 @@ */ package org.matsim.contrib.accessibility.logsumComputations; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; /** @@ -33,8 +33,8 @@ */ public class CompareLogsumFormulasTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); /** * underlying network @@ -47,7 +47,8 @@ public class CompareLogsumFormulasTest { * cjk3 */ - @Test public void testLogsumFormulas(){ + @Test + void testLogsumFormulas(){ double betaWalkTT = -2.; double betaWalkTD = -1.; @@ -72,7 +73,7 @@ public class CompareLogsumFormulasTest { double Ai = computeLogsum(betaWalkTT, betaWalkTD, cik1TT, cik2TT, cik3TT, cik1TD, cik2TD, cik3TD); double Ai2 =computeTransformedLogsum(betaWalkTT, betaWalkTD, cijTT, cjk1TT, cjk2TT, cjk3TT, cijTD, cjk1TD, cjk2TD, cjk3TD); - Assert.assertTrue( Ai == Ai2 ); + Assertions.assertTrue( Ai == Ai2 ); } /** diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/ComputeLogsumFormulas3Test.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/ComputeLogsumFormulas3Test.java index 81eb7bc3254..1b35497b3c7 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/ComputeLogsumFormulas3Test.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/logsumComputations/ComputeLogsumFormulas3Test.java @@ -22,9 +22,9 @@ */ package org.matsim.contrib.accessibility.logsumComputations; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; /** @@ -33,8 +33,8 @@ */ public class ComputeLogsumFormulas3Test { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); /** * underlying network @@ -48,7 +48,8 @@ public class ComputeLogsumFormulas3Test { */ @SuppressWarnings("static-method") - @Test public void testLogsumFormulas(){ + @Test + void testLogsumFormulas(){ double betaWalkTT = -10. / 3600.0; // [util/sec] double betaWalkTD = -10.; // [util/meter] @@ -100,7 +101,7 @@ public class ComputeLogsumFormulas3Test { // double expNewVhj= Math.exp( VhjNew ); // double expNewVhk= expNewVhj * sumExpVjk; - Assert.assertTrue(VhjOld == VhjNew); // old accessibility computation == new accessibility computation + Assertions.assertTrue(VhjOld == VhjNew); // old accessibility computation == new accessibility computation /////// // NEW @@ -112,7 +113,7 @@ public class ComputeLogsumFormulas3Test { double dummyExp1 = Math.exp( dummyVijCar + dummyVhiWalk ); double dummyExp2 = Math.exp( dummyVijCar ) * Math.exp( dummyVhiWalk ); - Assert.assertEquals(dummyExp1,dummyExp2,1.e-10); // exp(VijCar + VijWalk) == exp(VijCar) * exp(VijWalk) + Assertions.assertEquals(dummyExp1,dummyExp2,1.e-10); // exp(VijCar + VijWalk) == exp(VijCar) * exp(VijWalk) } } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/AccessibilityIntegrationTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/AccessibilityIntegrationTest.java index fa3e94febc8..25b3a4598eb 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/AccessibilityIntegrationTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/AccessibilityIntegrationTest.java @@ -27,10 +27,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.locationtech.jts.geom.Envelope; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; @@ -49,7 +49,7 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.FacilitiesConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; @@ -74,11 +74,11 @@ public class AccessibilityIntegrationTest { private static final Logger LOG = LogManager.getLogger(AccessibilityIntegrationTest.class); - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); - @Ignore + @Disabled @Test - public void testRunAccessibilityExample() { + void testRunAccessibilityExample() { Config config = ConfigUtils.loadConfig("./examples/RunAccessibilityExample/config.xml"); AccessibilityConfigGroup accConfig = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class); @@ -101,15 +101,15 @@ public void startRow(String[] row) { if (x == 50) { if (y == 50) { - Assert.assertEquals("Wrong work accessibility value at x=" + x + ", y=" + y + ":", 2.1486094237531126, value, utils.EPSILON); + Assertions.assertEquals(2.1486094237531126, value, utils.EPSILON, "Wrong work accessibility value at x=" + x + ", y=" + y + ":"); } else if (y == 150){ - Assert.assertEquals("Wrong work accessibility value at x=" + x + ", y=" + y + ":", 2.1766435716006005, value, utils.EPSILON); + Assertions.assertEquals(2.1766435716006005, value, utils.EPSILON, "Wrong work accessibility value at x=" + x + ", y=" + y + ":"); } } else if (x == 150) { if (y == 50) { - Assert.assertEquals("Wrong work accessibility value at x=" + x + ", y=" + y + ":", 2.1486094237531126, value, utils.EPSILON); + Assertions.assertEquals(2.1486094237531126, value, utils.EPSILON, "Wrong work accessibility value at x=" + x + ", y=" + y + ":"); } else if (y == 150){ - Assert.assertEquals("Wrong work accessibility value at x=" + x + ", y=" + y + ":", 2.2055702759681273, value, utils.EPSILON); + Assertions.assertEquals(2.2055702759681273, value, utils.EPSILON, "Wrong work accessibility value at x=" + x + ", y=" + y + ":"); } } } @@ -119,7 +119,7 @@ public void startRow(String[] row) { @Test - public void testWithBoundingBoxConfigFile() { + void testWithBoundingBoxConfigFile() { Config config = ConfigUtils.loadConfig(utils.getInputDirectory() + "config.xml"); AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class) ; @@ -132,14 +132,14 @@ public void testWithBoundingBoxConfigFile() { acg.setUseParallelization(false); ModeParams ptParams = new ModeParams(TransportMode.transit_walk); - config.planCalcScore().addModeParams(ptParams); + config.scoring().addModeParams(ptParams); MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class) ; - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setRoutingRandomness(0.); final Scenario sc = ScenarioUtils.loadScenario(config); - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); Controler controler = new Controler(sc); @@ -159,7 +159,7 @@ public void install() { @Test - public void testWithBoundingBox() { + void testWithBoundingBox() { final Config config = createTestConfig(); double min = 0.; // Values for bounding box usually come from a config file @@ -171,13 +171,13 @@ public void testWithBoundingBox() { acg.setBoundingBoxTop(max); acg.setBoundingBoxLeft(min); acg.setBoundingBoxRight(max); - - config.plansCalcRoute().setRoutingRandomness(0.); + + config.routing().setRoutingRandomness(0.); final Scenario sc = createTestScenario(config); MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class ) ; - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); Controler controler = new Controler(sc); @@ -197,7 +197,7 @@ public void install() { @Test - public void testWithBoundingBoxUsingOpportunityWeights() { + void testWithBoundingBoxUsingOpportunityWeights() { final Config config = createTestConfig(); double min = 0.; // Values for bounding box usually come from a config file @@ -213,11 +213,11 @@ public void testWithBoundingBoxUsingOpportunityWeights() { acg.setUseOpportunityWeights(true); acg.setWeightExponent(2.); - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setRoutingRandomness(0.); final Scenario sc = createTestScenarioUsingOpportunityWeights(config) ; MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class ) ; - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); Controler controler = new Controler(sc); @@ -237,14 +237,14 @@ public void install() { @Test - public void testWithExtentDeterminedByNetwork() { + void testWithExtentDeterminedByNetwork() { final Config config = createTestConfig() ; - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setRoutingRandomness(0.); final Scenario sc = createTestScenario(config) ; MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class ) ; - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); Controler controler = new Controler(sc); @@ -264,14 +264,14 @@ public void install() { @Test - public void testWithExtentDeterminedShapeFile() { + void testWithExtentDeterminedShapeFile() { Config config = createTestConfig() ; File f = new File(this.utils.getInputDirectory() + "shapefile.shp"); // shape file completely covers the road network if(!f.exists()){ LOG.error("Shape file not found! testWithExtentDeterminedShapeFile could not be tested..."); - Assert.assertTrue(f.exists()); + Assertions.assertTrue(f.exists()); } final AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class); @@ -280,11 +280,11 @@ public void testWithExtentDeterminedShapeFile() { // acg.setShapeFileCellBasedAccessibility(url.getPath()); // yyyyyy todo acg.setShapeFileCellBasedAccessibility(f.getAbsolutePath()); - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setRoutingRandomness(0.); final Scenario sc = createTestScenario(config) ; MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class ) ; - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); Controler controler = new Controler(sc); @@ -304,14 +304,14 @@ public void install() { @Test - public void testWithPredefinedMeasuringPoints() { + void testWithPredefinedMeasuringPoints() { Config config = createTestConfig() ; File f = new File(this.utils.getInputDirectory() + "measuringPoints.xml"); if(!f.exists()){ LOG.error("Facilities file with measuring points not found! testWithMeasuringPointsInFacilitiesFile could not be performed..."); - Assert.assertTrue(f.exists()); + Assertions.assertTrue(f.exists()); } Scenario measuringPointsSc = ScenarioUtils.createScenario(ConfigUtils.createConfig()); @@ -329,10 +329,10 @@ public void testWithPredefinedMeasuringPoints() { final Scenario sc = createTestScenario(config) ; MatrixBasedPtRouterConfigGroup mbConfig = ConfigUtils.addOrGetModule(config, MatrixBasedPtRouterConfigGroup.class ) ; - final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.plansCalcRoute(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; + final PtMatrix ptMatrix = PtMatrix.createPtMatrix(config.routing(), BoundingBox.createBoundingBox(sc.getNetwork()), mbConfig) ; sc.addScenarioElement(PtMatrix.NAME, ptMatrix); - - config.plansCalcRoute().setRoutingRandomness(0.); + + config.routing().setRoutingRandomness(0.); Controler controler = new Controler(sc); @@ -350,16 +350,16 @@ public void install() { } - @Ignore + @Disabled @Test - public void testWithFile(){ + void testWithFile(){ /*TODO Complete - JWJ, Dec'16 */ Config config = createTestConfig(); File f = new File(this.utils.getInputDirectory() + "pointFile.csv"); if(!f.exists()){ LOG.error("Point file not found! testWithFile could not be tested..."); - Assert.assertTrue(f.exists()); + Assertions.assertTrue(f.exists()); } final AccessibilityConfigGroup acg = ConfigUtils.addOrGetModule(config, AccessibilityConfigGroup.class); @@ -409,7 +409,7 @@ private Config createTestConfig() { config.transit().setVehiclesFile(utils.getClassInputDirectory() + "vehicles.xml"); ModeParams ptParams = new ModeParams(TransportMode.transit_walk); - config.planCalcScore().addModeParams(ptParams); + config.scoring().addModeParams(ptParams); MatrixBasedPtRouterConfigGroup mbConfig = new MatrixBasedPtRouterConfigGroup(); mbConfig.setPtStopsInputFile(utils.getClassInputDirectory() + "ptStops.csv"); @@ -419,9 +419,9 @@ private Config createTestConfig() { mbConfig.setUsingTravelTimesAndDistances(true); config.addModule(mbConfig); - config.controler().setLastIteration(0); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); return config; } @@ -598,12 +598,12 @@ public void finish() { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { // commented values are before (a) Marcel's change of the QuadTree in Oct'18, (b) change in TravelTimeCalculator in Apr'21 - case "freespeed": Assert.assertEquals(2.207441799716032, value, MatsimTestUtils.EPSILON); break; // (a) 2.1486094237531126 - case TransportMode.car: Assert.assertEquals(2.2058369602991204, value, MatsimTestUtils.EPSILON); break; // (a) 2.1482840466191093 (b) 2.205836861444427 - case TransportMode.bike: Assert.assertEquals(2.2645288908389554, value, MatsimTestUtils.EPSILON); break; // (a) 2.2257398663221 - case TransportMode.walk: Assert.assertEquals(1.8697283849051263, value, MatsimTestUtils.EPSILON); break; // (a) 1.70054725728361 - case TransportMode.pt: Assert.assertEquals(2.1581641260040683, value, MatsimTestUtils.EPSILON); break; - case "matrixBasedPt": Assert.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 + case "freespeed": Assertions.assertEquals(2.207441799716032, value, MatsimTestUtils.EPSILON); break; // (a) 2.1486094237531126 + case TransportMode.car: Assertions.assertEquals(2.2058369602991204, value, MatsimTestUtils.EPSILON); break; // (a) 2.1482840466191093 (b) 2.205836861444427 + case TransportMode.bike: Assertions.assertEquals(2.2645288908389554, value, MatsimTestUtils.EPSILON); break; // (a) 2.2257398663221 + case TransportMode.walk: Assertions.assertEquals(1.8697283849051263, value, MatsimTestUtils.EPSILON); break; // (a) 1.70054725728361 + case TransportMode.pt: Assertions.assertEquals(2.1581641260040683, value, MatsimTestUtils.EPSILON); break; + case "matrixBasedPt": Assertions.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 } } } @@ -611,12 +611,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(2.207441799716032, value, MatsimTestUtils.EPSILON); break; // (a) 2.1766435716006005 - case TransportMode.car: Assert.assertEquals(2.207441960299121, value, MatsimTestUtils.EPSILON); break; // (a) 2.176238564675181 (b) 2.207441799716032 - case TransportMode.bike: Assert.assertEquals(2.2645288908389554, value, MatsimTestUtils.EPSILON); break; // (a) 2.2445468698643367 - case TransportMode.walk: Assert.assertEquals(1.8697283849051263, value, MatsimTestUtils.EPSILON); break; // (a) 1.7719146868026079 - case TransportMode.pt: Assert.assertEquals(2.1581641260040683, value, MatsimTestUtils.EPSILON); break; // (a) 2.057596373646452 - case "matrixBasedPt": Assert.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 + case "freespeed": Assertions.assertEquals(2.207441799716032, value, MatsimTestUtils.EPSILON); break; // (a) 2.1766435716006005 + case TransportMode.car: Assertions.assertEquals(2.207441960299121, value, MatsimTestUtils.EPSILON); break; // (a) 2.176238564675181 (b) 2.207441799716032 + case TransportMode.bike: Assertions.assertEquals(2.2645288908389554, value, MatsimTestUtils.EPSILON); break; // (a) 2.2445468698643367 + case TransportMode.walk: Assertions.assertEquals(1.8697283849051263, value, MatsimTestUtils.EPSILON); break; // (a) 1.7719146868026079 + case TransportMode.pt: Assertions.assertEquals(2.1581641260040683, value, MatsimTestUtils.EPSILON); break; // (a) 2.057596373646452 + case "matrixBasedPt": Assertions.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 } } } @@ -626,12 +626,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(2.235503385314382, value, MatsimTestUtils.EPSILON); break; // (a) 2.1486094237531126 - case TransportMode.car: Assert.assertEquals(2.23550352057971, value, MatsimTestUtils.EPSILON); break; // (a) 2.1482840466191093 (b) 2.235503385314382 - case TransportMode.bike: Assert.assertEquals(2.2833435568892395, value, MatsimTestUtils.EPSILON); break; // (a) 2.2257398663221 - case TransportMode.walk: Assert.assertEquals(1.9418539664691532, value, MatsimTestUtils.EPSILON); break; // (a) 1.70054725728361 - case TransportMode.pt: Assert.assertEquals(2.0032465393091434, value, MatsimTestUtils.EPSILON); break; - case "matrixBasedPt": Assert.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 + case "freespeed": Assertions.assertEquals(2.235503385314382, value, MatsimTestUtils.EPSILON); break; // (a) 2.1486094237531126 + case TransportMode.car: Assertions.assertEquals(2.23550352057971, value, MatsimTestUtils.EPSILON); break; // (a) 2.1482840466191093 (b) 2.235503385314382 + case TransportMode.bike: Assertions.assertEquals(2.2833435568892395, value, MatsimTestUtils.EPSILON); break; // (a) 2.2257398663221 + case TransportMode.walk: Assertions.assertEquals(1.9418539664691532, value, MatsimTestUtils.EPSILON); break; // (a) 1.70054725728361 + case TransportMode.pt: Assertions.assertEquals(2.0032465393091434, value, MatsimTestUtils.EPSILON); break; + case "matrixBasedPt": Assertions.assertEquals(1.6542905235735796, value, MatsimTestUtils.EPSILON); break; // (a) 0.461863556339195 } } } @@ -639,12 +639,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(2.235503385314382, value, MatsimTestUtils.EPSILON); break; // (a) 2.2055702759681273 - case TransportMode.car: Assert.assertEquals(2.23550352057971, value, MatsimTestUtils.EPSILON); break; // (a) 2.2052225231109226 (b) 2.235503385314382 - case TransportMode.bike: Assert.assertEquals(2.2833435568892395, value, MatsimTestUtils.EPSILON); break; // (a) 2.2637376515333636 - case TransportMode.walk: Assert.assertEquals(1.9418539664691532, value, MatsimTestUtils.EPSILON); break; // (a) 1.851165291193725 - case TransportMode.pt: Assert.assertEquals(2.0032465393091434, value, MatsimTestUtils.EPSILON); break; // (a) 1.9202710265495115 - case "matrixBasedPt": Assert.assertEquals(1.5073890466447624, value, MatsimTestUtils.EPSILON); break; // (a) 0.624928280738513 + case "freespeed": Assertions.assertEquals(2.235503385314382, value, MatsimTestUtils.EPSILON); break; // (a) 2.2055702759681273 + case TransportMode.car: Assertions.assertEquals(2.23550352057971, value, MatsimTestUtils.EPSILON); break; // (a) 2.2052225231109226 (b) 2.235503385314382 + case TransportMode.bike: Assertions.assertEquals(2.2833435568892395, value, MatsimTestUtils.EPSILON); break; // (a) 2.2637376515333636 + case TransportMode.walk: Assertions.assertEquals(1.9418539664691532, value, MatsimTestUtils.EPSILON); break; // (a) 1.851165291193725 + case TransportMode.pt: Assertions.assertEquals(2.0032465393091434, value, MatsimTestUtils.EPSILON); break; // (a) 1.9202710265495115 + case "matrixBasedPt": Assertions.assertEquals(1.5073890466447624, value, MatsimTestUtils.EPSILON); break; // (a) 0.624928280738513 } } } @@ -656,12 +656,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(3.5937361608359226, value, MatsimTestUtils.EPSILON); break; // (a) 3.534903784873003 - case TransportMode.car: Assert.assertEquals(3.592131321419011, value, MatsimTestUtils.EPSILON); break; // (a) 3.534578407739 (b) 3.592131222564318 - case TransportMode.bike: Assert.assertEquals(3.650823251958846, value, MatsimTestUtils.EPSILON); break; // (a) 3.6120342274419914 - case TransportMode.walk: Assert.assertEquals(3.256022746025017, value, MatsimTestUtils.EPSILON); break; // (a) 3.086841618403501 - case TransportMode.pt: Assert.assertEquals(3.5444584871239586, value, MatsimTestUtils.EPSILON); break; - case "matrixBasedPt": Assert.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 + case "freespeed": Assertions.assertEquals(3.5937361608359226, value, MatsimTestUtils.EPSILON); break; // (a) 3.534903784873003 + case TransportMode.car: Assertions.assertEquals(3.592131321419011, value, MatsimTestUtils.EPSILON); break; // (a) 3.534578407739 (b) 3.592131222564318 + case TransportMode.bike: Assertions.assertEquals(3.650823251958846, value, MatsimTestUtils.EPSILON); break; // (a) 3.6120342274419914 + case TransportMode.walk: Assertions.assertEquals(3.256022746025017, value, MatsimTestUtils.EPSILON); break; // (a) 3.086841618403501 + case TransportMode.pt: Assertions.assertEquals(3.5444584871239586, value, MatsimTestUtils.EPSILON); break; + case "matrixBasedPt": Assertions.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 } } } @@ -669,12 +669,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(3.5937361608359226, value, MatsimTestUtils.EPSILON); break; // (a) 3.562937932720491 - case TransportMode.car: Assert.assertEquals(3.5937363214190112, value, MatsimTestUtils.EPSILON); break; // (a) 3.5625329257950717 (b) 3.5937361608359226 - case TransportMode.bike: Assert.assertEquals(3.650823251958846, value, MatsimTestUtils.EPSILON); break; // (a) 3.6308412309842275 - case TransportMode.walk: Assert.assertEquals(3.256022746025017, value, MatsimTestUtils.EPSILON); break; // (a) 3.1582090479224982 - case TransportMode.pt: Assert.assertEquals(3.5444584871239586, value, MatsimTestUtils.EPSILON); break; // (a) 3.443890734766343 - case "matrixBasedPt": Assert.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 + case "freespeed": Assertions.assertEquals(3.5937361608359226, value, MatsimTestUtils.EPSILON); break; // (a) 3.562937932720491 + case TransportMode.car: Assertions.assertEquals(3.5937363214190112, value, MatsimTestUtils.EPSILON); break; // (a) 3.5625329257950717 (b) 3.5937361608359226 + case TransportMode.bike: Assertions.assertEquals(3.650823251958846, value, MatsimTestUtils.EPSILON); break; // (a) 3.6308412309842275 + case TransportMode.walk: Assertions.assertEquals(3.256022746025017, value, MatsimTestUtils.EPSILON); break; // (a) 3.1582090479224982 + case TransportMode.pt: Assertions.assertEquals(3.5444584871239586, value, MatsimTestUtils.EPSILON); break; // (a) 3.443890734766343 + case "matrixBasedPt": Assertions.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 } } } @@ -684,12 +684,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(3.621797746434273, value, MatsimTestUtils.EPSILON); break; // (a) 3.534903784873003 - case TransportMode.car: Assert.assertEquals(3.621797881699601, value, MatsimTestUtils.EPSILON); break; // (a) 3.534578407739 (b) 3.621797746434273 - case TransportMode.bike: Assert.assertEquals(3.66963791800913, value, MatsimTestUtils.EPSILON); break; // (a) 3.6120342274419914 - case TransportMode.walk: Assert.assertEquals(3.328148327589044, value, MatsimTestUtils.EPSILON); break; // (a) 3.086841618403501 - case TransportMode.pt: Assert.assertEquals(3.389540900429034, value, MatsimTestUtils.EPSILON); break; - case "matrixBasedPt": Assert.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 + case "freespeed": Assertions.assertEquals(3.621797746434273, value, MatsimTestUtils.EPSILON); break; // (a) 3.534903784873003 + case TransportMode.car: Assertions.assertEquals(3.621797881699601, value, MatsimTestUtils.EPSILON); break; // (a) 3.534578407739 (b) 3.621797746434273 + case TransportMode.bike: Assertions.assertEquals(3.66963791800913, value, MatsimTestUtils.EPSILON); break; // (a) 3.6120342274419914 + case TransportMode.walk: Assertions.assertEquals(3.328148327589044, value, MatsimTestUtils.EPSILON); break; // (a) 3.086841618403501 + case TransportMode.pt: Assertions.assertEquals(3.389540900429034, value, MatsimTestUtils.EPSILON); break; + case "matrixBasedPt": Assertions.assertEquals(3.0405848846934704, value, MatsimTestUtils.EPSILON); break; // (a) 1.8481579174590859 } } } @@ -697,12 +697,12 @@ else if (tuple.getFirst().getCoord().getY() == 150.) { for (String mode : accessibilitiesMap.get(tuple).keySet()) { double value = accessibilitiesMap.get(tuple).get(mode); switch (mode) { - case "freespeed": Assert.assertEquals(3.621797746434273, value, MatsimTestUtils.EPSILON); break; // (a) 3.5918646370880176 - case TransportMode.car: Assert.assertEquals(3.621797881699601, value, MatsimTestUtils.EPSILON); break; // (a) 3.591516884230813 (b) 3.621797746434273 - case TransportMode.bike: Assert.assertEquals(3.66963791800913, value, MatsimTestUtils.EPSILON); break; // (a) 3.6500320126532544 - case TransportMode.walk: Assert.assertEquals(3.328148327589044, value, MatsimTestUtils.EPSILON); break; // (a) 3.2374596523136154 - case TransportMode.pt: Assert.assertEquals(3.389540900429034, value, MatsimTestUtils.EPSILON); break; // (a) 3.3065653876694023 - case "matrixBasedPt": Assert.assertEquals(2.893683407764653, value, MatsimTestUtils.EPSILON); break; // (a) 2.0112226418584043 + case "freespeed": Assertions.assertEquals(3.621797746434273, value, MatsimTestUtils.EPSILON); break; // (a) 3.5918646370880176 + case TransportMode.car: Assertions.assertEquals(3.621797881699601, value, MatsimTestUtils.EPSILON); break; // (a) 3.591516884230813 (b) 3.621797746434273 + case TransportMode.bike: Assertions.assertEquals(3.66963791800913, value, MatsimTestUtils.EPSILON); break; // (a) 3.6500320126532544 + case TransportMode.walk: Assertions.assertEquals(3.328148327589044, value, MatsimTestUtils.EPSILON); break; // (a) 3.2374596523136154 + case TransportMode.pt: Assertions.assertEquals(3.389540900429034, value, MatsimTestUtils.EPSILON); break; // (a) 3.3065653876694023 + case "matrixBasedPt": Assertions.assertEquals(2.893683407764653, value, MatsimTestUtils.EPSILON); break; // (a) 2.0112226418584043 } } } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/NetworkUtilTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/NetworkUtilTest.java index 405bc54c3e9..cf03d50fa9d 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/NetworkUtilTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/NetworkUtilTest.java @@ -21,9 +21,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -39,14 +39,14 @@ * @author dziemke */ public class NetworkUtilTest { - + private static final Logger log = LogManager.getLogger(NetworkUtilTest.class); - - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); - + + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); + @Test - public void testNetworkUtil() { + void testNetworkUtil() { /* create a sample network: * * (e) (f) @@ -62,10 +62,10 @@ public void testNetworkUtil() { * * The network contains an exactly horizontal, an exactly vertical, an exactly diagonal * and another link with no special slope to also test possible special cases. - * + * * why is that a "special case"? in a normal network all sort of slopes are *normally* present. dz, feb'16 */ - + Network network = NetworkUtils.createNetwork(); Node node1 = NetworkUtils.createAndAddNode(network, Id.create("1", Node.class), new Coord((double) 0, (double) 0)); Node node2 = NetworkUtils.createAndAddNode(network, Id.create("2", Node.class), new Coord((double) 0, (double) 1000)); @@ -76,7 +76,7 @@ public void testNetworkUtil() { Link link2 = NetworkUtils.createAndAddLink(network, Id.create("2", Link.class), node2, node3, 1500, 1, 3600, 1); Link link3 = NetworkUtils.createAndAddLink(network, Id.create("3", Link.class), node3, node4, 1000, 1, 3600, 1); Link link4 = NetworkUtils.createAndAddLink(network, Id.create("4", Link.class), node4, node5, 2800, 1, 3600, 1); - + Coord a = new Coord(100., 0.); Coord b = new Coord(100., 100.); Coord c = new Coord(100., 1000.); @@ -86,122 +86,122 @@ public void testNetworkUtil() { Coord g = new Coord(2300., 2000.); Coord h = new Coord(1700., 1000.); Coord i = new Coord(0., 1200.); - - + + Distances distanceA11 = NetworkUtil.getDistances2NodeViaGivenLink(a, link1, node1); - Assert.assertEquals("distanceA11.getDistancePoint2Road()", 100., distanceA11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceA11.getDistanceRoad2Node()", 0., distanceA11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(100., distanceA11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceA11.getDistancePoint2Road()"); + Assertions.assertEquals(0., distanceA11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceA11.getDistanceRoad2Node()"); + Coord projectionA11 = CoordUtils.orthogonalProjectionOnLineSegment(link1.getFromNode().getCoord(), link1.getToNode().getCoord(), a); - Assert.assertEquals("projectionA11.getX()", 0., projectionA11.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionA11.getY()", 0., projectionA11.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(0., projectionA11.getX(), MatsimTestUtils.EPSILON, "projectionA11.getX()"); + Assertions.assertEquals(0., projectionA11.getY(), MatsimTestUtils.EPSILON, "projectionA11.getY()"); + + Distances distanceB11 = NetworkUtil.getDistances2NodeViaGivenLink(b, link1, node1); - Assert.assertEquals("distanceB11.getDistancePoint2Road()", 100., distanceB11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceB11.getDistanceRoad2Node()", 100., distanceB11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(100., distanceB11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceB11.getDistancePoint2Road()"); + Assertions.assertEquals(100., distanceB11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceB11.getDistanceRoad2Node()"); + Coord projectionB11 = CoordUtils.orthogonalProjectionOnLineSegment(link1.getFromNode().getCoord(), link1.getToNode().getCoord(), b); - Assert.assertEquals("projectionB11.getX()", 0., projectionB11.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionB11.getY()", 100., projectionB11.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(0., projectionB11.getX(), MatsimTestUtils.EPSILON, "projectionB11.getX()"); + Assertions.assertEquals(100., projectionB11.getY(), MatsimTestUtils.EPSILON, "projectionB11.getY()"); + + Distances distanceB12 = NetworkUtil.getDistances2NodeViaGivenLink(b, link1, node2); - Assert.assertEquals("distanceB12.getDistancePoint2Road()", 100., distanceB12.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceB12.getDistanceRoad2Node()", 900., distanceB12.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(100., distanceB12.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceB12.getDistancePoint2Road()"); + Assertions.assertEquals(900., distanceB12.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceB12.getDistanceRoad2Node()"); + Coord projectionB12 = CoordUtils.orthogonalProjectionOnLineSegment(link1.getFromNode().getCoord(), link1.getToNode().getCoord(), b); - Assert.assertEquals("projectionB12.getX()", 0., projectionB12.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionB12.getY()", 100., projectionB12.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(0., projectionB12.getX(), MatsimTestUtils.EPSILON, "projectionB12.getX()"); + Assertions.assertEquals(100., projectionB12.getY(), MatsimTestUtils.EPSILON, "projectionB12.getY()"); + + Distances distanceC11 = NetworkUtil.getDistances2NodeViaGivenLink(c, link1, node1); - Assert.assertEquals("distanceC11.getDistancePoint2Road()", 100., distanceC11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceC11.getDistanceRoad2Node()", 1000., distanceC11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(100., distanceC11.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceC11.getDistancePoint2Road()"); + Assertions.assertEquals(1000., distanceC11.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceC11.getDistanceRoad2Node()"); + Coord projectionC11 = CoordUtils.orthogonalProjectionOnLineSegment(link1.getFromNode().getCoord(), link1.getToNode().getCoord(), c); - Assert.assertEquals("projectionC11.getX()", 0., projectionC11.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionC11.getY()", 1000., projectionC11.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(0., projectionC11.getX(), MatsimTestUtils.EPSILON, "projectionC11.getX()"); + Assertions.assertEquals(1000., projectionC11.getY(), MatsimTestUtils.EPSILON, "projectionC11.getY()"); + + Distances distanceC12 = NetworkUtil.getDistances2NodeViaGivenLink(c, link1, node2); - Assert.assertEquals("distanceC12.getDistancePoint2Road()", 100., distanceC12.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceC12.getDistanceRoad2Node()", 0., distanceC12.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(100., distanceC12.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceC12.getDistancePoint2Road()"); + Assertions.assertEquals(0., distanceC12.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceC12.getDistanceRoad2Node()"); + Coord projectionC12 = CoordUtils.orthogonalProjectionOnLineSegment(link1.getFromNode().getCoord(), link1.getToNode().getCoord(), c); - Assert.assertEquals("projectionC12.getX()", 0., projectionC12.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionC12.getY()", 1000., projectionC12.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(0., projectionC12.getX(), MatsimTestUtils.EPSILON, "projectionC12.getX()"); + Assertions.assertEquals(1000., projectionC12.getY(), MatsimTestUtils.EPSILON, "projectionC12.getY()"); + + Distances distanceC22 = NetworkUtil.getDistances2NodeViaGivenLink(c, link2, node2); - Assert.assertEquals("distanceC22.getDistancePoint2Road()", Math.sqrt(2.) / 2. * 100., distanceC22.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceC22.getDistanceRoad2Node()", Math.sqrt(2.) / 2. * 100., distanceC22.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(2.) / 2. * 100., distanceC22.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceC22.getDistancePoint2Road()"); + Assertions.assertEquals(Math.sqrt(2.) / 2. * 100., distanceC22.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceC22.getDistanceRoad2Node()"); + Coord projectionC22 = CoordUtils.orthogonalProjectionOnLineSegment(link2.getFromNode().getCoord(), link2.getToNode().getCoord(), c); - Assert.assertEquals("projectionC22.getX()", 50., projectionC22.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionC22.getY()", 1050., projectionC22.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(50., projectionC22.getX(), MatsimTestUtils.EPSILON, "projectionC22.getX()"); + Assertions.assertEquals(1050., projectionC22.getY(), MatsimTestUtils.EPSILON, "projectionC22.getY()"); + + Distances distanceC23 = NetworkUtil.getDistances2NodeViaGivenLink(c, link2, node3); - Assert.assertEquals("distanceC23.getDistancePoint2Road()", Math.sqrt(2.) / 2. * 100., distanceC23.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceC23.getDistanceRoad2Node()", Math.sqrt(2) * 1000. - Math.sqrt(2.) / 2. * 100., distanceC23.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(2.) / 2. * 100., distanceC23.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceC23.getDistancePoint2Road()"); + Assertions.assertEquals(Math.sqrt(2) * 1000. - Math.sqrt(2.) / 2. * 100., distanceC23.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceC23.getDistanceRoad2Node()"); + Coord projectionC23 = CoordUtils.orthogonalProjectionOnLineSegment(link2.getFromNode().getCoord(), link2.getToNode().getCoord(), c); - Assert.assertEquals("projectionC23.getX()", 50., projectionC23.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionC23.getY()", 1050., projectionC23.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(50., projectionC23.getX(), MatsimTestUtils.EPSILON, "projectionC23.getX()"); + Assertions.assertEquals(1050., projectionC23.getY(), MatsimTestUtils.EPSILON, "projectionC23.getY()"); + + Distances distanceD22 = NetworkUtil.getDistances2NodeViaGivenLink(d, link2, node2); - Assert.assertEquals("distanceD22.getDistancePoint2Road()", Math.sqrt(2.) / 2. * 100.0, distanceD22.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceD22.getDistanceRoad2Node()", Math.sqrt(2.) / 2. * 100.0 + Math.sqrt(2) * 200., distanceD22.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(2.) / 2. * 100.0, distanceD22.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceD22.getDistancePoint2Road()"); + Assertions.assertEquals(Math.sqrt(2.) / 2. * 100.0 + Math.sqrt(2) * 200., distanceD22.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceD22.getDistanceRoad2Node()"); + Coord projectionD22 = CoordUtils.orthogonalProjectionOnLineSegment(link2.getFromNode().getCoord(), link2.getToNode().getCoord(), d); - Assert.assertEquals("projectionD22.getX()", 250., projectionD22.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionD22.getY()", 1250., projectionD22.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(250., projectionD22.getX(), MatsimTestUtils.EPSILON, "projectionD22.getX()"); + Assertions.assertEquals(1250., projectionD22.getY(), MatsimTestUtils.EPSILON, "projectionD22.getY()"); + + Distances distanceD23 = NetworkUtil.getDistances2NodeViaGivenLink(d, link2, node3); - Assert.assertEquals("distanceD23.getDistancePoint2Road()", Math.sqrt(2.)/2.*100.0, distanceD23.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceD23.getDistanceRoad2Node()", Math.sqrt(2.)/2.*100.0 + Math.sqrt(2) * 700., distanceD23.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(2.)/2.*100.0, distanceD23.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceD23.getDistancePoint2Road()"); + Assertions.assertEquals(Math.sqrt(2.)/2.*100.0 + Math.sqrt(2) * 700., distanceD23.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceD23.getDistanceRoad2Node()"); + Coord projectionD23 = CoordUtils.orthogonalProjectionOnLineSegment(link2.getFromNode().getCoord(), link2.getToNode().getCoord(), d); - Assert.assertEquals("projectionD23.getX()", 250., projectionD23.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionD23.getY()", 1250., projectionD23.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(250., projectionD23.getX(), MatsimTestUtils.EPSILON, "projectionD23.getX()"); + Assertions.assertEquals(1250., projectionD23.getY(), MatsimTestUtils.EPSILON, "projectionD23.getY()"); + + Distances distanceE33 = NetworkUtil.getDistances2NodeViaGivenLink(e, link3, node3); - Assert.assertEquals("distanceE33.getDistancePoint2Road()", 100.0, distanceE33.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceE33.getDistanceRoad2Node()", 300.0, distanceE33.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(100.0, distanceE33.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceE33.getDistancePoint2Road()"); + Assertions.assertEquals(300.0, distanceE33.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceE33.getDistanceRoad2Node()"); Coord projectionE33 = CoordUtils.orthogonalProjectionOnLineSegment(link3.getFromNode().getCoord(), link3.getToNode().getCoord(), e); - Assert.assertEquals("projectionE33.getX()", 1300., projectionE33.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionE33.getY()", 2000., projectionE33.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(1300., projectionE33.getX(), MatsimTestUtils.EPSILON, "projectionE33.getX()"); + Assertions.assertEquals(2000., projectionE33.getY(), MatsimTestUtils.EPSILON, "projectionE33.getY()"); + + Distances distanceE34 = NetworkUtil.getDistances2NodeViaGivenLink(e, link3, node4); - Assert.assertEquals("distanceE34.getDistancePoint2Road()", 100.0, distanceE34.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceE34.getDistanceRoad2Node()", 700.0, distanceE34.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(100.0, distanceE34.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceE34.getDistancePoint2Road()"); + Assertions.assertEquals(700.0, distanceE34.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceE34.getDistanceRoad2Node()"); Coord projectionE34 = CoordUtils.orthogonalProjectionOnLineSegment(link3.getFromNode().getCoord(), link3.getToNode().getCoord(), e); - Assert.assertEquals("projectionE34.getX()", 1300., projectionE34.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionE34.getY()", 2000., projectionE34.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(1300., projectionE34.getX(), MatsimTestUtils.EPSILON, "projectionE34.getX()"); + Assertions.assertEquals(2000., projectionE34.getY(), MatsimTestUtils.EPSILON, "projectionE34.getY()"); + + Distances distanceF33 = NetworkUtil.getDistances2NodeViaGivenLink(f, link3, node3); - Assert.assertEquals("distanceF33.getDistancePoint2Road()", Math.sqrt(Math.pow(100, 2) + Math.pow(300, 2)), distanceF33.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceF33.getDistanceRoad2Node()", 1000., distanceF33.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(Math.pow(100, 2) + Math.pow(300, 2)), distanceF33.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceF33.getDistancePoint2Road()"); + Assertions.assertEquals(1000., distanceF33.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceF33.getDistanceRoad2Node()"); + Coord projectionF33 = CoordUtils.orthogonalProjectionOnLineSegment(link3.getFromNode().getCoord(), link3.getToNode().getCoord(), e); - Assert.assertEquals("projectionF33.getX()", 1300., projectionF33.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionF33.getY()", 2000., projectionF33.getY(), MatsimTestUtils.EPSILON); - - + Assertions.assertEquals(1300., projectionF33.getX(), MatsimTestUtils.EPSILON, "projectionF33.getX()"); + Assertions.assertEquals(2000., projectionF33.getY(), MatsimTestUtils.EPSILON, "projectionF33.getY()"); + + Distances distanceF34 = NetworkUtil.getDistances2NodeViaGivenLink(f, link3, node4); - Assert.assertEquals("distanceF34.getDistancePoint2Road()", Math.sqrt(Math.pow(100, 2) + Math.pow(300, 2)), distanceF34.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON); - Assert.assertEquals("distanceF34.getDistanceRoad2Node()", 0., distanceF34.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON); - + Assertions.assertEquals(Math.sqrt(Math.pow(100, 2) + Math.pow(300, 2)), distanceF34.getDistancePoint2Intersection(), MatsimTestUtils.EPSILON, "distanceF34.getDistancePoint2Road()"); + Assertions.assertEquals(0., distanceF34.getDistanceIntersection2Node(), MatsimTestUtils.EPSILON, "distanceF34.getDistanceRoad2Node()"); + Coord projectionF34 = CoordUtils.orthogonalProjectionOnLineSegment(link3.getFromNode().getCoord(), link3.getToNode().getCoord(), f); - Assert.assertEquals("projectionF34.getX()", 2000., projectionF34.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals("projectionF34.getY()", 2000., projectionF34.getY(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2000., projectionF34.getX(), MatsimTestUtils.EPSILON, "projectionF34.getX()"); + Assertions.assertEquals(2000., projectionF34.getY(), MatsimTestUtils.EPSILON, "projectionF34.getY()"); } -} \ No newline at end of file +} diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyAccessibilityTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyAccessibilityTest.java index bb5bcc2d5e7..8c1e52924b4 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyAccessibilityTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyAccessibilityTest.java @@ -23,10 +23,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -58,10 +57,10 @@ public class TinyAccessibilityTest { private static final Logger LOG = LogManager.getLogger(TinyAccessibilityTest.class); - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void runFromEvents() { + void runFromEvents() { final Config config = createTestConfig(); double min = 0.; // Values for bounding box usually come from a config file @@ -87,7 +86,7 @@ public void runFromEvents() { } @Test - public void testWithBoundingBox() { + void testWithBoundingBox() { final Config config = createTestConfig(); double min = 0.; // Values for bounding box usually come from a config file @@ -122,11 +121,11 @@ private Config createTestConfig() { acg.setComputingAccessibilityForMode(Modes4Accessibility.freespeed, true); acg.setComputingAccessibilityForMode(Modes4Accessibility.car, true); - config.controler().setLastIteration(0); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setRoutingRandomness(0.); return config; } @@ -263,20 +262,20 @@ public void finish() { LOG.warn("CHECK X = " + tuple.getFirst().getCoord().getX() + " -- Y = " + tuple.getFirst().getCoord().getY() + " -- car value = " + accessibilitiesMap.get(tuple).get(TransportMode.car)); if (tuple.getFirst().getCoord().getX() == 50.) { if (tuple.getFirst().getCoord().getY() == 50.) { - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(-0.017240250823867296, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017240250823867296, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); } else if (tuple.getFirst().getCoord().getY() == 150.) { - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(-0.017240250823867296, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017240250823867296, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); } } if (tuple.getFirst().getCoord().getX() == 150.) { if (tuple.getFirst().getCoord().getY() == 50.) { - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.27582980607476704, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.27582980607476704, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); } else if (tuple.getFirst().getCoord().getY() == 150.) { - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.27582980607476704, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.27582980607476704, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); } } } diff --git a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyMultimodalAccessibilityTest.java b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyMultimodalAccessibilityTest.java index c2abfc8df95..43574962078 100644 --- a/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyMultimodalAccessibilityTest.java +++ b/contribs/accessibility/src/test/java/org/matsim/contrib/accessibility/run/TinyMultimodalAccessibilityTest.java @@ -21,10 +21,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -65,11 +65,12 @@ public class TinyMultimodalAccessibilityTest { private static final Logger LOG = LogManager.getLogger(TinyMultimodalAccessibilityTest.class); - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); + // non-deterministic presumably because of multi-threading. kai, sep'19 @Test - @Ignore // non-deterministic presumably because of multi-threading. kai, sep'19 - public void testWithBoundingBox() { + @Disabled + void testWithBoundingBox() { final Config config = createTestConfig(); double min = 0.; // Values for bounding box usually come from a config file @@ -105,9 +106,9 @@ private Config createTestConfig() { acg.setComputingAccessibilityForMode(Modes4Accessibility.pt, true); acg.setUseParallelization(false); - config.controler().setLastIteration(0); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); return config; } @@ -309,24 +310,24 @@ public void finish() { LOG.warn("CHECK X = " + tuple.getFirst().getCoord().getX() + " -- Y = " + tuple.getFirst().getCoord().getY() + " -- car value = " + accessibilitiesMap.get(tuple).get(TransportMode.car)); if (tuple.getFirst().getCoord().getX() == 50.) { if (tuple.getFirst().getCoord().getY() == 50.) { - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.0020510618020555325, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0020510618020555325, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); } else if (tuple.getFirst().getCoord().getY() == 150.) { - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); - Assert.assertEquals(-0.04152005026781742, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.017248522428805767, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.04152005026781742, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); } } if (tuple.getFirst().getCoord().getX() == 150.) { if (tuple.getFirst().getCoord().getY() == 50.) { - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.25069951470887114, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.25069951470887114, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); } else if (tuple.getFirst().getCoord().getY() == 150.) { - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); - Assert.assertEquals(0.25069951470887114, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get("freespeed"), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.2758252376673665, accessibilitiesMap.get(tuple).get(TransportMode.car), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.25069951470887114, accessibilitiesMap.get(tuple).get(TransportMode.pt), MatsimTestUtils.EPSILON); } } } diff --git a/contribs/accidents/src/main/java/org/matsim/contrib/accidents/AccidentWriter.java b/contribs/accidents/src/main/java/org/matsim/contrib/accidents/AccidentWriter.java index 7476fab2e96..8f0b09a8ae2 100644 --- a/contribs/accidents/src/main/java/org/matsim/contrib/accidents/AccidentWriter.java +++ b/contribs/accidents/src/main/java/org/matsim/contrib/accidents/AccidentWriter.java @@ -41,14 +41,14 @@ class AccidentWriter { private static String convertSecondToHHMMSSString(int nSecondTime) { return LocalTime.MIN.plusSeconds(nSecondTime).toString(); } - + public void write(Scenario scenario, IterationEndsEvent event, Map, AccidentLinkInfo> linkId2info, AnalysisEventHandler analzyer) { AccidentsConfigGroup accidentsCfg = (AccidentsConfigGroup) scenario.getConfig().getModules().get(AccidentsConfigGroup.GROUP_NAME); - + double timeBinSize = scenario.getConfig().travelTimeCalculator().getTraveltimeBinSize(); - + //File with Linkinfo for Tests - File linkInfoFile = new File(scenario.getConfig().controler().getOutputDirectory() + "ITERS/it." + event.getIteration() + "/" + scenario.getConfig().controler().getRunId() + "." + event.getIteration() + ".linkInfo.csv"); + File linkInfoFile = new File(scenario.getConfig().controller().getOutputDirectory() + "ITERS/it." + event.getIteration() + "/" + scenario.getConfig().controller().getRunId() + "." + event.getIteration() + ".linkInfo.csv"); BufferedWriter linkInformation = null; try { linkInformation = new BufferedWriter (new FileWriter(linkInfoFile)); @@ -62,7 +62,7 @@ public void write(Scenario scenario, IterationEndsEvent event, Map, Acc } linkInformation.write("demandPerDay ;"); linkInformation.newLine(); - + for (AccidentLinkInfo info : linkId2info.values()) { double demandPerDay = 0.0; linkInformation.write(info.getLinkId().toString()); @@ -77,15 +77,15 @@ public void write(Scenario scenario, IterationEndsEvent event, Map, Acc linkInformation.write(Double.toString(demand)); linkInformation.write(";"); } - linkInformation.write(Double.toString(demandPerDay)); + linkInformation.write(Double.toString(demandPerDay)); linkInformation.newLine(); } linkInformation.close(); } catch (IOException e3) { e3.printStackTrace(); } - - File accidentCostsBVWPFile = new File(scenario.getConfig().controler().getOutputDirectory() + "ITERS/it." + event.getIteration() + "/" + scenario.getConfig().controler().getRunId() + "." + event.getIteration() + ".accidentCosts_BVWP.csv"); + + File accidentCostsBVWPFile = new File(scenario.getConfig().controller().getOutputDirectory() + "ITERS/it." + event.getIteration() + "/" + scenario.getConfig().controller().getRunId() + "." + event.getIteration() + ".accidentCosts_BVWP.csv"); BufferedWriter accidentCostsBVWP = null; try { accidentCostsBVWP = new BufferedWriter (new FileWriter(accidentCostsBVWPFile)); @@ -100,7 +100,7 @@ public void write(Scenario scenario, IterationEndsEvent event, Map, Acc accidentCostsBVWP.write("Costs per Day [EUR] ;"); accidentCostsBVWP.write("Costs per Year [EUR] ;"); accidentCostsBVWP.newLine(); - + } catch (IOException e1) { e1.printStackTrace(); } @@ -109,7 +109,7 @@ public void write(Scenario scenario, IterationEndsEvent event, Map, Acc nf.setMaximumFractionDigits(2); nf.setGroupingUsed(false); - for (AccidentLinkInfo info : linkId2info.values()) { + for (AccidentLinkInfo info : linkId2info.values()) { double accidentCostsPerDay_BVWP = 0.0; double accidentCostsPerYear_BVWP = 0.0; @@ -123,12 +123,12 @@ public void write(Scenario scenario, IterationEndsEvent event, Map, Acc } catch (IOException e1) { e1.printStackTrace(); } - + for (double endTime = timeBinSize ; endTime <= scenario.getConfig().travelTimeCalculator().getMaxTime(); endTime = endTime + timeBinSize ) { - + double time = (endTime - timeBinSize/2.); int timeBinNr = (int) (time / timeBinSize); - + if (linkComputationMethod.toString().equals( AccidentsConfigGroup.AccidentsComputationMethod.BVWP.toString() )){ accidentCostsPerDay_BVWP += info.getTimeSpecificInfo().get(timeBinNr).getAccidentCosts(); try { diff --git a/contribs/accidents/src/main/java/org/matsim/contrib/accidents/runExample/RunAccidents.java b/contribs/accidents/src/main/java/org/matsim/contrib/accidents/runExample/RunAccidents.java index b9fe07dc88c..a25d3512e71 100644 --- a/contribs/accidents/src/main/java/org/matsim/contrib/accidents/runExample/RunAccidents.java +++ b/contribs/accidents/src/main/java/org/matsim/contrib/accidents/runExample/RunAccidents.java @@ -44,44 +44,44 @@ public class RunAccidents { private static final Logger log = LogManager.getLogger(RunAccidents.class); - - public static void main(String[] args) throws IOException { + + public static void main(String[] args) throws IOException { RunAccidents main = new RunAccidents(); main.run(); } private void run() throws MalformedURLException, IOException { log.info("Loading scenario..."); - + String configFile = "path/to/configFile.xml"; - + Config config = ConfigUtils.loadConfig(configFile ); - + AccidentsConfigGroup accidentsSettings = ConfigUtils.addOrGetModule(config, AccidentsConfigGroup.class); accidentsSettings.setEnableAccidentsModule(true); - + final Scenario scenario = ScenarioUtils.loadScenario(config); - + // Preprocess network AccidentsNetworkModification networkModification = new AccidentsNetworkModification(scenario); - + String[] tunnelLinks = readCSVFile("tunnelLinksCSVfile"); String[] planfreeLinks = readCSVFile("planfreeLinksCSVfile"); - + networkModification.setLinkAttributsBasedOnOSMFile("osmlandUseFile", "EPSG:31468" , tunnelLinks, planfreeLinks ); - + Controler controler = new Controler(scenario); controler.addOverridingModule(new AccidentsModule()); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + + controler.getConfig().controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); controler.run(); } - + private String[] readCSVFile(String csvFile) { ArrayList> links = new ArrayList<>(); BufferedReader br = IOUtils.getBufferedReader(csvFile); - + String line = null; try { line = br.readLine(); @@ -92,7 +92,7 @@ private String[] readCSVFile(String csvFile) { try { int countWarning = 0; while ((line = br.readLine()) != null) { - + String[] columns = line.split(";"); Id linkId = null; for (int column = 0; column < columns.length; column++) { @@ -105,7 +105,7 @@ private String[] readCSVFile(String csvFile) { log.warn("This message is only given once."); } countWarning++; - } + } } log.info("Adding link ID " + linkId); links.add(linkId); @@ -113,7 +113,7 @@ private String[] readCSVFile(String csvFile) { } catch (IOException e) { e.printStackTrace(); } - + String[] linkIDsArray = (String[]) links.toArray(); return linkIDsArray ; } diff --git a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/BvwpAccidentsCostComputationTest.java b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/BvwpAccidentsCostComputationTest.java index 9acd427bef7..3cb595ee1e6 100644 --- a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/BvwpAccidentsCostComputationTest.java +++ b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/BvwpAccidentsCostComputationTest.java @@ -2,8 +2,8 @@ import java.util.ArrayList; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -12,7 +12,7 @@ import org.matsim.api.core.v01.network.Node; import org.matsim.core.network.NetworkUtils; import org.matsim.testcases.MatsimTestUtils; -; + /** * @author ikaddoura, mmayobre @@ -20,9 +20,9 @@ * */ public class BvwpAccidentsCostComputationTest { - + @Test - public void test1() { + void test1() { Network network = NetworkUtils.createNetwork(); NetworkFactory factory = network.getFactory(); @@ -40,11 +40,11 @@ public void test1() { list.add(2, 2); //2 Lanes double costs = AccidentCostComputationBVWP.computeAccidentCosts(4820, link1, list); - Assert.assertEquals("wrong cost", 1772.13863066011, costs, MatsimTestUtils.EPSILON); + Assertions.assertEquals(1772.13863066011, costs, MatsimTestUtils.EPSILON, "wrong cost"); } - + @Test - public void test2() { + void test2() { Network network = NetworkUtils.createNetwork(); NetworkFactory factory = network.getFactory(); @@ -62,11 +62,11 @@ public void test2() { list.add(2, 2); //2 Lanes double costs = AccidentCostComputationBVWP.computeAccidentCosts(1000, link1, list); - Assert.assertEquals("wrong cost", 23.165, costs, MatsimTestUtils.EPSILON); + Assertions.assertEquals(23.165, costs, MatsimTestUtils.EPSILON, "wrong cost"); } - + @Test - public void test3() { + void test3() { Network network = NetworkUtils.createNetwork(); NetworkFactory factory = network.getFactory(); @@ -84,6 +84,6 @@ public void test3() { list.add(2, 3); //2 Lanes double costs = AccidentCostComputationBVWP.computeAccidentCosts(1000, link1, list); - Assert.assertEquals("wrong cost", 101.53, costs, MatsimTestUtils.EPSILON); + Assertions.assertEquals(101.53, costs, MatsimTestUtils.EPSILON, "wrong cost"); } } diff --git a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTest.java b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTest.java index 3fa83d471d3..f07d1d8d5f9 100644 --- a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTest.java +++ b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTest.java @@ -3,9 +3,9 @@ import java.io.BufferedReader; import java.io.IOException; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.accidents.AccidentsConfigGroup.AccidentsComputationMethod; @@ -19,57 +19,57 @@ /** * @author ikaddoura, mmayobre - * - * + * + * */ public class RunTest { - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); - + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); + @Test - public void test1() { + void test1() { String configFile = utils.getPackageInputDirectory() + "/trial_scenario/trial_scenario_config.xml"; String outputDirectory = utils.getOutputDirectory(); String runId = "run1"; - + Config config = ConfigUtils.loadConfig(configFile); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - - config.controler().setOutputDirectory(outputDirectory); - config.controler().setRunId(runId); - + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + + config.controller().setOutputDirectory(outputDirectory); + config.controller().setRunId(runId); + AccidentsConfigGroup accidentsSettings = ConfigUtils.addOrGetModule(config, AccidentsConfigGroup.class); accidentsSettings.setEnableAccidentsModule(true); - + final Scenario scenario = ScenarioUtils.loadScenario(config); - + // pre-process network for (Link link : scenario.getNetwork().getLinks().values()) { link.getAttributes().putAttribute(accidentsSettings.getAccidentsComputationMethodAttributeName(), AccidentsComputationMethod.BVWP.toString()); - + int numberOfLanesBVWP; if (link.getNumberOfLanes() > 4){ numberOfLanesBVWP = 4; } else { numberOfLanesBVWP = (int) link.getNumberOfLanes(); } - + if (link.getFreespeed() > 16.) { link.getAttributes().putAttribute( AccidentsConfigGroup.BVWP_ROAD_TYPE_ATTRIBUTE_NAME, "1,0," + numberOfLanesBVWP); } else { link.getAttributes().putAttribute( AccidentsConfigGroup.BVWP_ROAD_TYPE_ATTRIBUTE_NAME, "1,2," + numberOfLanesBVWP); - } + } } - + Controler controler = new Controler(scenario); - + controler.addOverridingModule(new AccidentsModule() ); - + controler.run(); - + BufferedReader br = IOUtils.getBufferedReader(outputDirectory + "ITERS/it.0/run1.0.accidentCosts_BVWP.csv"); - + String line = null; try { line = br.readLine(); @@ -80,27 +80,27 @@ public void test1() { try { int lineCounter = 0; while ((line = br.readLine()) != null) { - + String[] columns = line.split(";"); for (int column = 0; column < columns.length; column++) { - + if (lineCounter == 0 && column == 25) { double accidentCosts = Double.valueOf(columns[column]); - Assert.assertEquals("wrong accident costs", 10.38, accidentCosts , MatsimTestUtils.EPSILON); + Assertions.assertEquals(10.38, accidentCosts , MatsimTestUtils.EPSILON, "wrong accident costs"); } - + if (lineCounter == 1 && column == 25) { double accidentCosts = Double.valueOf(columns[column]); - Assert.assertEquals("wrong accident costs", 16.68, accidentCosts , MatsimTestUtils.EPSILON); + Assertions.assertEquals(16.68, accidentCosts , MatsimTestUtils.EPSILON, "wrong accident costs"); } - + } - + lineCounter++; } } catch (IOException e) { e.printStackTrace(); } - + } } diff --git a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTestEquil.java b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTestEquil.java index 3cd2bf28fe2..486baf7f3ec 100644 --- a/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTestEquil.java +++ b/contribs/accidents/src/test/java/org/matsim/contrib/accidents/RunTestEquil.java @@ -1,10 +1,11 @@ package org.matsim.contrib.accidents; import java.io.BufferedReader; -import java.io.IOException; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import java.io.IOException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -15,59 +16,59 @@ import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.io.IOUtils; -import org.matsim.testcases.MatsimTestUtils; - +import org.matsim.testcases.MatsimTestUtils; + public class RunTestEquil { - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); - - @Test - public void test1() { + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void test1() { String configFile = utils.getPackageInputDirectory() + "/equil_scenario/config.xml"; String outputDirectory = utils.getOutputDirectory(); String runId = "run1"; - + Config config = ConfigUtils.loadConfig( configFile ); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - - config.controler().setOutputDirectory( outputDirectory ); - config.controler().setRunId( runId ); - config.controler().setLastIteration(0); - + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + + config.controller().setOutputDirectory( outputDirectory ); + config.controller().setRunId( runId ); + config.controller().setLastIteration(0); + AccidentsConfigGroup accidentsSettings = ConfigUtils.addOrGetModule(config, AccidentsConfigGroup.class); accidentsSettings.setEnableAccidentsModule(true); - + final Scenario scenario = ScenarioUtils.loadScenario(config); Controler controler = new Controler (scenario); controler.addOverridingModule(new AccidentsModule() ); - - scenario.getNetwork().getLinks().get(Id.createLinkId("6")).setFreespeed(10); + + scenario.getNetwork().getLinks().get(Id.createLinkId("6")).setFreespeed(10); scenario.getNetwork().getLinks().get(Id.createLinkId("6")).setNumberOfLanes(3); - scenario.getNetwork().getLinks().get(Id.createLinkId("15")).setFreespeed(10); + scenario.getNetwork().getLinks().get(Id.createLinkId("15")).setFreespeed(10); scenario.getNetwork().getLinks().get(Id.createLinkId("15")).setNumberOfLanes(2); - + // pre-process network for (Link link : scenario.getNetwork().getLinks().values()) { link.getAttributes().putAttribute(accidentsSettings.getAccidentsComputationMethodAttributeName(), AccidentsComputationMethod.BVWP.toString()); - + int numberOfLanesBVWP; if (link.getNumberOfLanes() > 4){ numberOfLanesBVWP = 4; } else { numberOfLanesBVWP = (int) link.getNumberOfLanes(); } - + if (link.getFreespeed() > 16.) { link.getAttributes().putAttribute( AccidentsConfigGroup.BVWP_ROAD_TYPE_ATTRIBUTE_NAME, "1,0," + numberOfLanesBVWP); } else { link.getAttributes().putAttribute( AccidentsConfigGroup.BVWP_ROAD_TYPE_ATTRIBUTE_NAME, "1,2," + numberOfLanesBVWP); - } + } } - + controler.run(); - + BufferedReader br = IOUtils.getBufferedReader(outputDirectory + "ITERS/it.0/run1.0.accidentCosts_BVWP.csv"); - + String line = null; try { line = br.readLine(); @@ -78,17 +79,17 @@ public void test1() { try { int lineCounter = 0; while ((line = br.readLine()) != null) { - + String[] columns = line.split(";"); for (int column = 0; column < columns.length; column++) { - + // link 22 if (lineCounter == 1 && column == 121) { double accidentCosts = Double.valueOf(columns[column]); int agents = 100; int lengthKM = 35; double accidentCostsManualCalculation = (agents * lengthKM * 61.785) / 1000. * 10; - Assert.assertEquals("wrong accident costs", accidentCostsManualCalculation, accidentCosts , 0.01); + Assertions.assertEquals(accidentCostsManualCalculation, accidentCosts , 0.01, "wrong accident costs"); } // link 1 if (lineCounter == 11 && column == 121) { @@ -96,28 +97,28 @@ public void test1() { int agents = 100; int lengthKM = 10; double accidentCostsManualCalculation = (agents * lengthKM * 61.785) / 1000. * 10; - Assert.assertEquals("wrong accident costs", accidentCostsManualCalculation, accidentCosts , 0.01); + Assertions.assertEquals(accidentCostsManualCalculation, accidentCosts , 0.01, "wrong accident costs"); } - + // link 6 if (lineCounter == 16 && column == 121) { double accidentCosts = Double.valueOf(columns[column]); int agents = 100; int lengthKM = 10; double accidentCostsManualCalculation = (agents * lengthKM * 34.735) / 1000. * 10; - Assert.assertEquals("wrong accident costs", accidentCostsManualCalculation, accidentCosts , 0.01); - } - + Assertions.assertEquals(accidentCostsManualCalculation, accidentCosts , 0.01, "wrong accident costs"); + } + // link 15 if (lineCounter == 6 && column == 121) { double accidentCosts = Double.valueOf(columns[column]); int agents = 100; int lengthKM = 5; double accidentCostsManualCalculation = (agents * lengthKM * 31.63) / 1000. * 10; - Assert.assertEquals("wrong accident costs", accidentCostsManualCalculation, accidentCosts , 0.01); + Assertions.assertEquals(accidentCostsManualCalculation, accidentCosts , 0.01, "wrong accident costs"); } } - + lineCounter++; } } catch (IOException e) { diff --git a/contribs/analysis/pom.xml b/contribs/analysis/pom.xml index e164c142592..3894c728d93 100644 --- a/contribs/analysis/pom.xml +++ b/contribs/analysis/pom.xml @@ -20,19 +20,19 @@ proj4j 0.1.0
- - com.googlecode.json-simple - json-simple - 1.1.1 - - + + com.google.code.gson + gson + 2.10.1 + + org.apache.commons commons-math3 org.apache.httpcomponents.client5 httpclient5 - 5.2.1 + 5.3 diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/ActivitiesAnalyzer.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/ActivitiesAnalyzer.java index 39c5b49040b..bb4239c27c9 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/ActivitiesAnalyzer.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/ActivitiesAnalyzer.java @@ -39,11 +39,11 @@ import org.matsim.core.controler.listener.StartupListener; import org.matsim.core.utils.charts.XYLineChart; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; import java.awt.*; import java.io.BufferedWriter; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.*; import java.util.List; @@ -54,21 +54,21 @@ * * @author cdobler */ -public class ActivitiesAnalyzer implements ActivityStartEventHandler, ActivityEndEventHandler, +public class ActivitiesAnalyzer implements ActivityStartEventHandler, ActivityEndEventHandler, StartupListener, BeforeMobsimListener, IterationEndsListener { public static String defaultActivitiesFileName = "activityCounts"; - + private final boolean autoConfig; - + private double endTime = 30*3600; - + private String activitiesFileName = defaultActivitiesFileName; private final Set observedAgents; private boolean createGraphs; private final Map> activityCountData = new TreeMap>(); private final LinkedList overallCount = new LinkedList(); - + /** * This is how most people will probably will use this class. * It has to be created an registered as ControlerListener. @@ -76,56 +76,56 @@ public class ActivitiesAnalyzer implements ActivityStartEventHandler, ActivityEn * get paths to output files, ...). */ public ActivitiesAnalyzer() { - + this.autoConfig = true; this.createGraphs = true; this.observedAgents = null; - + reset(0); } - + public ActivitiesAnalyzer(String activitiesFileName, Set activityTypes, boolean createGraphs) { this(activitiesFileName, activityTypes, null, createGraphs); } - + public ActivitiesAnalyzer(String activitiesFileName, Set activityTypes, Set observedAgents, boolean createGraphs) { - + this.autoConfig = false; - + this.activitiesFileName = activitiesFileName; this.createGraphs = createGraphs; - + // use all activity defined in the set for (String activityType : activityTypes) { this.activityCountData.put(activityType, new LinkedList()); } - + if (observedAgents != null) { // make a copy to prevent people changing the set over the iterations - this.observedAgents = new HashSet(observedAgents); + this.observedAgents = new HashSet(observedAgents); } else this.observedAgents = null; - + reset(0); } - + public void setCreateGraphs(boolean createGraphs) { this.createGraphs = createGraphs; } - + public void setEndTime(double endTime) { this.endTime = endTime; } - + @Override public void handleEvent(ActivityEndEvent event) { - + if (observedAgents != null && !observedAgents.contains(event.getPersonId())) return; - + LinkedList list = this.activityCountData.get(event.getActType()); - + // ignore not observed activity types if (list == null) return; - + changeCount(event.getTime(), list, -1); changeCount(event.getTime(), this.overallCount, -1); } @@ -133,22 +133,22 @@ public void handleEvent(ActivityEndEvent event) { @Override public void handleEvent(ActivityStartEvent event) { - + if (observedAgents != null && !observedAgents.contains(event.getPersonId())) return; - + LinkedList list = this.activityCountData.get(event.getActType()); // ignore not observed activity types if (list == null) return; - + changeCount(event.getTime(), list, 1); changeCount(event.getTime(), this.overallCount, 1); } - + private void changeCount(double time, LinkedList list, int delta) { - + ActivityData activityData = list.getLast(); - + /* * If there is already another entry for the same time step, re-use it. * Otherwise create a new one. @@ -159,7 +159,7 @@ private void changeCount(double time, LinkedList list, int delta) list.add(new ActivityData(time, activityData.activityCount + delta)); } } - + @Override public void reset(final int iter) { for (List list : this.activityCountData.values()) { @@ -169,40 +169,40 @@ public void reset(final int iter) { this.overallCount.clear(); this.overallCount.add(new ActivityData(0.0, 0)); } - + @Override public void notifyStartup(StartupEvent event) { - + MatsimServices controler = event.getServices(); - + if (autoConfig) { // use all activity types defined in the config - Set activityTypes = new TreeSet(event.getServices().getConfig().planCalcScore().getActivityTypes()); + Set activityTypes = new TreeSet(event.getServices().getConfig().scoring().getActivityTypes()); for (String activityType : activityTypes) { this.activityCountData.put(activityType, new LinkedList()); } - + controler.getEvents().addHandler(this); } } - + @Override public void notifyBeforeMobsim(BeforeMobsimEvent event) { - + ActivityData overallActivityData = this.overallCount.getLast(); for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { - + if (this.observedAgents != null && !this.observedAgents.contains(person.getId())) continue; - + Plan plan = person.getSelectedPlan(); Activity firstActivity = (Activity) plan.getPlanElements().get(0); LinkedList list = activityCountData.get(firstActivity.getType()); - + // ignore not observed activity types if (list == null) continue; - + ActivityData activityData = list.getLast(); activityData.activityCount += 1; overallActivityData.activityCount += 1; @@ -211,19 +211,19 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { @Override public void notifyIterationEnds(IterationEndsEvent event) { - + OutputDirectoryHierarchy outputDirectoryHierarchy = event.getServices().getControlerIO(); - + try { for (String activityType : this.activityCountData.keySet()) { String fileName = outputDirectoryHierarchy.getIterationFilename(event.getIteration(), this.activitiesFileName + "_" + activityType + ".txt"); BufferedWriter activitiesWriter = IOUtils.getBufferedWriter(fileName); - + activitiesWriter.write("TIME"); activitiesWriter.write("\t"); activitiesWriter.write(activityType.toUpperCase()); activitiesWriter.write("\n"); - + List list = this.activityCountData.get(activityType); for (ActivityData activityData : list) { activitiesWriter.write(String.valueOf(activityData.time)); @@ -231,18 +231,18 @@ public void notifyIterationEnds(IterationEndsEvent event) { activitiesWriter.write(String.valueOf(activityData.activityCount)); activitiesWriter.write("\n"); } - + activitiesWriter.flush(); activitiesWriter.close(); } } catch (IOException e) { throw new UncheckedIOException(e); } - + if (this.createGraphs) { // create chart when data of more than one iteration is available. XYLineChart chart; - + /* * number of performed activities */ @@ -250,7 +250,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { for (String activityType : this.activityCountData.keySet()) { List list = this.activityCountData.get(activityType); int length = list.size(); - + double[] times = new double[length * 2 - 1]; double[] counts = new double[length * 2 - 1]; Iterator iter = list.iterator(); @@ -287,13 +287,13 @@ public void notifyIterationEnds(IterationEndsEvent event) { i += 2; } chart.addSeries("overall", times, counts); - + NumberAxis domainAxis = (NumberAxis) chart.getChart().getXYPlot().getDomainAxis(); domainAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 11)); domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); domainAxis.setAutoRange(false); domainAxis.setRange(0, endTime / 3600.0); - + chart.addMatsimLogo(); String fileName = outputDirectoryHierarchy.getIterationFilename(event.getIteration(), this.activitiesFileName + ".png"); chart.saveAsPng(fileName, 800, 600); @@ -301,7 +301,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { } private static class ActivityData { - + public final double time; public int activityCount; @@ -311,4 +311,4 @@ public ActivityData(double time, int activityCount) { } } -} \ No newline at end of file +} diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/TripsAnalyzer.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/TripsAnalyzer.java index e5ad1a32205..390adb131b9 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/TripsAnalyzer.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/christoph/TripsAnalyzer.java @@ -22,6 +22,7 @@ import java.io.BufferedWriter; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -45,7 +46,6 @@ import org.matsim.core.controler.listener.StartupListener; import org.matsim.core.utils.charts.XYLineChart; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; /** * Calculates: @@ -53,7 +53,7 @@ * - average leg travel time over all modes * - number of trips per mode * - number of trips over all modes - * + * * @author cdobler */ public class TripsAnalyzer implements PersonDepartureEventHandler, PersonArrivalEventHandler, @@ -63,23 +63,23 @@ public class TripsAnalyzer implements PersonDepartureEventHandler, PersonArrival public static String defaultDurationsFileName = "tripDurations"; private final boolean autoConfig; - + private final Set sortedModes = new TreeSet(); private final Set observedAgents; private final Map departureTimes = new HashMap(); private final Map> legTravelTimes = new HashMap>(); - + private String tripsFileName; private String durationsFileName; private boolean createGraphs; - + private BufferedWriter tripsWriter; private BufferedWriter durationWriter; - + private double[][] tripsHistory; private double[][] durationHistory; private int minIteration; - + /** * This is how most people will probably will use this class. * It has to be created an registered as ControlerListener. @@ -87,47 +87,47 @@ public class TripsAnalyzer implements PersonDepartureEventHandler, PersonArrival * get paths to output files, ...). */ public TripsAnalyzer() { - + this.autoConfig = true; this.createGraphs = true; - + // modes which are analyzed by default this.sortedModes.add(TransportMode.bike); this.sortedModes.add(TransportMode.car); this.sortedModes.add(TransportMode.pt); this.sortedModes.add(TransportMode.ride); this.sortedModes.add(TransportMode.walk); - + this.observedAgents = null; } - + public TripsAnalyzer(String tripsFileName, String durationsFileName, Set modes, boolean createGraphs) { this(tripsFileName, durationsFileName, modes, null, createGraphs); } - + public TripsAnalyzer(String tripsFileName, String durationsFileName, Set modes, Set observedAgents, boolean createGraphs) { this.autoConfig = false; - + this.tripsFileName = tripsFileName; this.durationsFileName = durationsFileName; this.sortedModes.addAll(modes); if (observedAgents != null) { // make a copy to prevent people changing the set over the iterations - this.observedAgents = new HashSet(observedAgents); + this.observedAgents = new HashSet(observedAgents); } else this.observedAgents = null; this.createGraphs = createGraphs; } - + public void setCreateGraphs(boolean createGraphs) { this.createGraphs = createGraphs; } - + public Set getModes() { return this.sortedModes; } - + @Override public void reset(int iteration) { for(List modeTravelTime : legTravelTimes.values()) { @@ -137,12 +137,12 @@ public void reset(int iteration) { @Override public void handleEvent(PersonArrivalEvent event) { - + if (observedAgents != null && !observedAgents.contains(event.getPersonId())) return; - + Double departureTime = departureTimes.remove(event.getPersonId()); if (departureTime == null) throw new RuntimeException("No departure time for agent " + event.getPersonId() + " was found!"); - + double travelTime = event.getTime() - departureTime; String mode = event.getLegMode(); List modeTravelTimes = legTravelTimes.get(mode); @@ -159,16 +159,16 @@ public void handleEvent(PersonDepartureEvent event) { public void notifyStartup(final StartupEvent event) { MatsimServices controler = event.getServices(); - this.minIteration = controler.getConfig().controler().getFirstIteration(); - int maxIter = controler.getConfig().controler().getLastIteration(); + this.minIteration = controler.getConfig().controller().getFirstIteration(); + int maxIter = controler.getConfig().controller().getLastIteration(); int iterations = maxIter - this.minIteration; this.tripsHistory = new double[this.sortedModes.size() + 1][iterations + 1]; - this.durationHistory = new double[this.sortedModes.size() + 1][iterations + 1]; - + this.durationHistory = new double[this.sortedModes.size() + 1][iterations + 1]; + if (autoConfig) { this.tripsFileName = event.getServices().getControlerIO().getOutputFilename(defaultTripsFileName); this.durationsFileName = event.getServices().getControlerIO().getOutputFilename(defaultDurationsFileName); - + controler.getEvents().addHandler(this); } @@ -183,7 +183,7 @@ public void notifyStartup(final StartupEvent event) { this.tripsWriter.write(mode.toUpperCase()); this.durationWriter.write("\t"); this.durationWriter.write(mode.toUpperCase()); - + this.legTravelTimes.put(mode, new LinkedList()); } this.tripsWriter.write("\t"); @@ -192,12 +192,12 @@ public void notifyStartup(final StartupEvent event) { this.durationWriter.write("\t"); this.durationWriter.write("OVERALL"); this.durationWriter.write("\n"); - + } catch (IOException e) { throw new UncheckedIOException(e); } } - + @Override public void notifyIterationEnds(IterationEndsEvent event) { try { @@ -205,7 +205,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { this.tripsWriter.write(String.valueOf(iteration)); this.durationWriter.write(String.valueOf(iteration)); int index = iteration - this.minIteration; - + int i = 0; int overallTrips = 0; double overallTravelTime = 0.0; @@ -213,7 +213,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { List modeTravelTimes = legTravelTimes.get(mode); double sumTravelTimes = 0.0; for (double travelTime : modeTravelTimes) sumTravelTimes += travelTime; - + int modeTrips = modeTravelTimes.size(); overallTrips += modeTrips; overallTravelTime += sumTravelTimes; @@ -221,19 +221,19 @@ public void notifyIterationEnds(IterationEndsEvent event) { double averageTravelTime = sumTravelTimes / modeTrips; this.tripsHistory[i][index] = modeTrips; this.durationHistory[i][index] = averageTravelTime; - + this.tripsWriter.write("\t"); this.tripsWriter.write(String.valueOf(modeTrips)); this.durationWriter.write("\t"); this.durationWriter.write(String.valueOf(averageTravelTime)); - + i++; } - + double averageTravelTime = overallTravelTime / overallTrips; this.tripsHistory[sortedModes.size()][index] = overallTrips; this.durationHistory[sortedModes.size()][index] = averageTravelTime; - + this.tripsWriter.write("\t"); this.tripsWriter.write(String.valueOf(overallTrips)); this.tripsWriter.write("\n"); @@ -250,26 +250,26 @@ public void notifyIterationEnds(IterationEndsEvent event) { } catch (IOException e) { throw new RuntimeException(e); } - + if (this.createGraphs && event.getIteration() != this.minIteration) { int index = event.getIteration() - this.minIteration; // create chart when data of more than one iteration is available. XYLineChart chart; - + double[] iterations = new double[index + 1]; for (int i = 0; i <= index; i++) { iterations[i] = i + this.minIteration; } double[] values = new double[index + 1]; - + int i; - + /* * average leg duration */ chart = new XYLineChart("Average Leg Travel Times Statistics", "iteration", "time"); - + i = 0; for (String mode : sortedModes) { System.arraycopy(this.durationHistory[i], 0, values, 0, index + 1); @@ -278,15 +278,15 @@ public void notifyIterationEnds(IterationEndsEvent event) { } System.arraycopy(this.durationHistory[i], 0, values, 0, index + 1); chart.addSeries("overall", iterations, values); - + chart.addMatsimLogo(); chart.saveAsPng(this.durationsFileName + ".png", 800, 600); - + /* * number of trips */ chart = new XYLineChart("Number of Trips per Mode Statistics", "iteration", "number of trips"); - + i = 0; for (String mode : sortedModes) { System.arraycopy(this.tripsHistory[i], 0, values, 0, index + 1); @@ -295,7 +295,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { } System.arraycopy(this.tripsHistory[i], 0, values, 0, index + 1); chart.addSeries("overall", iterations, values); - + chart.addMatsimLogo(); chart.saveAsPng(this.tripsFileName + ".png", 800, 600); } @@ -306,7 +306,7 @@ public void notifyShutdown(ShutdownEvent event) { try { if (this.tripsWriter != null) { this.tripsWriter.flush(); - this.tripsWriter.close(); + this.tripsWriter.close(); } if (this.durationWriter != null) { this.durationWriter.flush(); diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandler.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandler.java index 3bde897e73c..ad1e9cfe938 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandler.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandler.java @@ -43,13 +43,13 @@ import org.matsim.core.router.TripStructureUtils.Trip; import org.matsim.core.utils.geometry.CoordUtils; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; import org.matsim.utils.objectattributes.ObjectAttributes; import org.matsim.utils.objectattributes.ObjectAttributesXmlWriter; import org.matsim.vehicles.Vehicle; import java.io.BufferedWriter; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.*; import java.util.Map.Entry; @@ -100,7 +100,7 @@ enum StatType { private Vehicle2DriverEventHandler delegate = new Vehicle2DriverEventHandler() ; - // general trip counter. Would, in theory, not necessary to do this per StatType, but I find it too brittle + // general trip counter. Would, in theory, not necessary to do this per StatType, but I find it too brittle // to avoid under- or over-counting with respect to loops. // private final Map legCount = new TreeMap() ; diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/RunKNEventsAnalyzer.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/RunKNEventsAnalyzer.java index 205cf58ba3b..462943c36f4 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/RunKNEventsAnalyzer.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/kai/RunKNEventsAnalyzer.java @@ -37,70 +37,70 @@ public class RunKNEventsAnalyzer { public static void main(String[] args) { - + if ( args.length < 3 ) { System.out.println("Usage: cmd eventsFile popFile netFile [popAttrFile] [tollFile] [futureTollFile]. Aborting ..." ) ; System.exit(-1); } - + String eventsFilename = args[0] ; String populationFilename = args[1] ; String networkFilename = args[2] ; - + String popAttrFilename = null ; if ( args.length > 3 && args[3]!=null ) { popAttrFilename = args[3] ; } - + String tollFilename = null ; if ( args.length > 4 && args[4]!=null ) { tollFilename = args[4] ; } - + String otherLinksFilename = null ; if ( args.length > 5 && args[5]!=null ) { otherLinksFilename = args[5] ; } - + // === Config config = ConfigUtils.createConfig() ; - + String[] modes ={"car","commercial"}; config.qsim().setMainModes( Arrays.asList(modes) ); - config.plansCalcRoute().setNetworkModes(Arrays.asList(modes)); - + config.routing().setNetworkModes(Arrays.asList(modes)); + config.network().setInputFile( networkFilename ); config.plans().setInputFile( populationFilename ); config.plans().setInputPersonAttributeFile( popAttrFilename ); ConfigUtils.addOrGetModule(config, RoadPricingConfigGroup.GROUP_NAME, RoadPricingConfigGroup.class).setTollLinksFile(tollFilename); // === - + Scenario scenario = ScenarioUtils.loadScenario(config) ; // ((ScenarioImpl)scenario).createVehicleContainer() ; // GautengControler_subpopulations.createVehiclePerPerson(scenario); - + // === - + EventsManager events = new EventsManagerImpl() ; - + Vehicle2DriverEventHandler vehicle2Driver = new Vehicle2DriverEventHandler(); events.addHandler(vehicle2Driver); - + final KNAnalysisEventsHandler.Builder builder = new KNAnalysisEventsHandler.Builder(scenario) ; builder.setOtherTollLinkFile( otherLinksFilename ); final KNAnalysisEventsHandler calcLegTimes = builder.build(); - + events.addHandler( calcLegTimes ); - + new MatsimEventsReader(events).readFile(eventsFilename) ; - -// String myDate = date.getYear() + "-" + date.getMonthOfYear() + "-" + date.getDayOfMonth() + "-" + + +// String myDate = date.getYear() + "-" + date.getMonthOfYear() + "-" + date.getDayOfMonth() + "-" + // date.getHourOfDay() + "h" + minute ; String myDate = "" ; - + calcLegTimes.writeStats(myDate + "_stats_"); } diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidator.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidator.java index b8aa76c34e1..7d35886428d 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidator.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidator.java @@ -1,11 +1,11 @@ package org.matsim.contrib.analysis.vsp.traveltimedistance; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import org.matsim.api.core.v01.Coord; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.geometry.CoordinateTransformation; @@ -20,6 +20,7 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Locale; +import java.util.Optional; public class GoogleMapRouteValidator implements TravelTimeDistanceValidator { private static final Logger log = LogManager.getLogger(GoogleMapRouteValidator.class); @@ -51,9 +52,6 @@ public Tuple getTravelTime(NetworkTrip trip) { @Override public Tuple getTravelTime(Coord fromCoord, Coord toCoord, double departureTime, String tripId) { - long travelTime = 0; - long distance = 0; - double adjustedDepartureTime = calculateGoogleDepartureTime(departureTime); Coord from = ct.transform(fromCoord); Coord to = ct.transform(toCoord); @@ -71,32 +69,46 @@ public Tuple getTravelTime(Coord fromCoord, Coord toCoord, doubl "&origins=" + df.format(from.getY()) + "%2C" + df.format(from.getX()) + "&key=" + apiAccessKey; + log.info(urlString); + + Optional> result; try { - log.info(urlString); URL url = new URL(urlString); - try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) { - JSONParser jp = new JSONParser(); - JSONObject jsonObject = (JSONObject) jp.parse(in); - JSONArray rows = (JSONArray) jsonObject.get("rows"); - if (!rows.isEmpty()) { - JSONArray elements = (JSONArray) ((JSONObject) rows.get(0)).get("elements"); - JSONObject results = (JSONObject) elements.get(0); - if (results.containsKey("distance")) { - JSONObject distanceResults = (JSONObject) results.get("distance"); - distance = (long) distanceResults.get("value"); - } - if (results.containsKey("duration_in_traffic")) { - JSONObject timeResults = (JSONObject) results.get("duration_in_traffic"); - travelTime = (long) timeResults.get("value"); - } - } - } - } catch (IOException | ParseException e) { + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + result = readFromJson(in); + } catch (IOException e) { log.error("The contents on the URL cannot be read properly. Please check your API or check the contents on URL manually", e); + result = Optional.empty(); } - return new Tuple<>((double) travelTime, (double) distance); + return result.orElse(new Tuple<>(0.0, 0.0)); } + Optional> readFromJson(BufferedReader reader) throws IOException { + JsonElement jsonElement = JsonParser.parseReader(reader); + if(!jsonElement.isJsonObject()){ + return Optional.empty(); + } + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonArray rows = jsonObject.getAsJsonArray("rows"); + + if (rows.isEmpty()) { + return Optional.empty(); + } + + JsonObject results = rows.get(0).getAsJsonObject().get("elements").getAsJsonArray().get(0).getAsJsonObject(); + + if (!results.has("distance") && !results.has("duration_in_traffic")) { + return Optional.empty(); + } + + JsonObject distanceResults = results.get("distance").getAsJsonObject(); + double distance = distanceResults.get("value").getAsDouble(); + JsonObject timeResults = results.get("duration_in_traffic").getAsJsonObject(); + double travelTime = timeResults.get("value").getAsDouble(); + + return Optional.of(new Tuple<>(travelTime, distance)); + } + private double calculateGoogleDepartureTime(double departureTime) { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate googleDate0 = LocalDate.parse("1970-01-01", dateTimeFormatter); diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidator.java b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidator.java index 9af9cff72c9..b437d7dffb8 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidator.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidator.java @@ -28,13 +28,14 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; +import java.util.Optional; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; import org.matsim.api.core.v01.Coord; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.geometry.CoordinateTransformation; @@ -91,9 +92,6 @@ public Tuple getTravelTime(NetworkTrip trip) { @Override public Tuple getTravelTime(Coord fromCoord, Coord toCoord, double departureTime, String tripId) { - long travelTime = 0; - long distance = 0; - Coord from = transformation.transform(fromCoord); Coord to = transformation.transform(toCoord); @@ -110,36 +108,48 @@ public Tuple getTravelTime(Coord fromCoord, Coord toCoord, doubl log.info(urlString); + Optional> result; try { URL url = new URL(urlString); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); - JSONParser jp = new JSONParser(); - JSONObject jsonObject = (JSONObject) jp.parse(in); - JSONArray routes = (JSONArray) jsonObject.get("routes"); - - if (!routes.isEmpty()) { - JSONObject route = (JSONObject) routes.get(0); - JSONArray sections = (JSONArray) route.get("sections"); - JSONObject section = (JSONObject) sections.get(0); - JSONObject summary = (JSONObject) section.get("summary"); - travelTime = (long) summary.get("duration"); - distance = (long) summary.get("length"); - if (writeDetailedFiles) { - String filename = outputPath + "/" + tripId + ".json.gz"; - BufferedWriter bw = IOUtils.getBufferedWriter(filename); - bw.write(jsonObject.toString()); - bw.flush(); - bw.close(); - } - } - - in.close(); + result = readFromJson(in, tripId); } catch (MalformedURLException e) { log.error("URL is not working. Please check your API key", e); - } catch (IOException | ParseException e) { + result = Optional.empty(); + } catch (IOException e) { log.error("Cannot read the content on the URL properly. Please manually check the URL", e); + result = Optional.empty(); } - return new Tuple((double) travelTime, (double) distance); + return result.orElse(new Tuple<>(0.0, 0.0)); } + Optional> readFromJson(BufferedReader reader, String tripId) throws IOException { + JsonElement jsonElement = JsonParser.parseReader(reader); + if(!jsonElement.isJsonObject()){ + return Optional.empty(); + } + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonArray routes = jsonObject.getAsJsonArray("routes"); + + if(routes.isEmpty()){ + return Optional.empty(); + } + + JsonObject route = routes.get(0).getAsJsonObject(); + JsonArray sections = route.get("sections").getAsJsonArray(); + JsonObject section = sections.get(0).getAsJsonObject(); + JsonObject summary = section.get("summary").getAsJsonObject(); + double travelTime = summary.get("duration").getAsDouble(); + double distance = summary.get("length").getAsDouble(); + if (writeDetailedFiles) { + String filename = outputPath + "/" + tripId + ".json.gz"; + BufferedWriter bw = IOUtils.getBufferedWriter(filename); + bw.write(jsonObject.toString()); + bw.flush(); + bw.close(); + } + reader.close(); + return Optional.of(new Tuple<>(travelTime, distance)); + } + } diff --git a/contribs/analysis/src/main/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiaries.java b/contribs/analysis/src/main/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiaries.java index 403f4d0bdb5..436cb4c800f 100644 --- a/contribs/analysis/src/main/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiaries.java +++ b/contribs/analysis/src/main/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiaries.java @@ -51,7 +51,7 @@ public static void main(String[] args) { printHelp(); try { config = ConfigUtils.loadConfig(args[0]); - outputDirectory = config.controler().getOutputDirectory(); + outputDirectory = config.controller().getOutputDirectory(); eventsFileName = args[1]; diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/PersonIntersectAreaFilterTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/PersonIntersectAreaFilterTest.java index 2c856118e92..aed33926f02 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/PersonIntersectAreaFilterTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/PersonIntersectAreaFilterTest.java @@ -20,13 +20,13 @@ package org.matsim.contrib.analysis.filters.population; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.HashMap; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -51,11 +51,12 @@ */ public class PersonIntersectAreaFilterTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - @Test public void testFilter() throws Exception { + @Test + void testFilter() throws Exception { /* create a simple network where agents can drive from the lower left * to the upper right */ Network network = NetworkUtils.createNetwork(); @@ -113,25 +114,25 @@ public class PersonIntersectAreaFilterTest { aoi.clear(); aoi.put(link2.getId(), link2); filter = new PersonIntersectAreaFilter(null, aoi, network); - assertTrue("test route through aoi", filter.judge(person)); + assertTrue(filter.judge(person), "test route through aoi"); // test departure link aoi.clear(); aoi.put(link0.getId(), link0); filter = new PersonIntersectAreaFilter(null, aoi, network); - assertTrue("test departure link as aoi", filter.judge(person)); + assertTrue(filter.judge(person), "test departure link as aoi"); // test arrival link aoi.clear(); aoi.put(link5.getId(), link5); filter = new PersonIntersectAreaFilter(null, aoi, network); - assertTrue("test arrival link as aoi", filter.judge(person)); + assertTrue(filter.judge(person), "test arrival link as aoi"); // test route outside aoi aoi.clear(); aoi.put(link4.getId(), link4); filter = new PersonIntersectAreaFilter(null, aoi, network); - assertFalse("test route outside aoi", filter.judge(person)); + assertFalse(filter.judge(person), "test route outside aoi"); // prepare bee-line tests leg.setMode(TransportMode.walk); @@ -141,21 +142,21 @@ public class PersonIntersectAreaFilterTest { aoi.clear(); aoi.put(link2.getId(), link2); filter = new PersonIntersectAreaFilter(null, aoi, network); - assertFalse("test bee-line without alternative aoi", filter.judge(person)); + assertFalse(filter.judge(person), "test bee-line without alternative aoi"); // test bee-line with too small alternative aoi aoi.clear(); aoi.put(link2.getId(), link2); filter = new PersonIntersectAreaFilter(null, aoi, network); filter.setAlternativeAOI(new Coord((double) 100, (double) 0), 20.0); - assertFalse("test bee-line with too small alternative aoi", filter.judge(person)); + assertFalse(filter.judge(person), "test bee-line with too small alternative aoi"); // test bee-line with big enough alternative aoi aoi.clear(); aoi.put(link2.getId(), link2); filter = new PersonIntersectAreaFilter(null, aoi, network); filter.setAlternativeAOI(new Coord((double) 100, (double) 0), 80.0); - assertTrue("test bee-line with big enough alternative aoi", filter.judge(person)); + assertTrue(filter.judge(person), "test bee-line with big enough alternative aoi"); } diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/RouteLinkFilterTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/RouteLinkFilterTest.java index 01f4b00a334..c434dca8a24 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/RouteLinkFilterTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/filters/population/RouteLinkFilterTest.java @@ -20,11 +20,11 @@ package org.matsim.contrib.analysis.filters.population; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -50,11 +50,12 @@ public class RouteLinkFilterTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - @Test public void testRouteLinkFilter() { + @Test + void testRouteLinkFilter() { // used to set the default dtd-location utils.loadConfig((String)null); Population population = getTestPopulation(); diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandlerTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandlerTest.java index 8d6e64b29f9..67352fcabbf 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandlerTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/kai/KNAnalysisEventsHandlerTest.java @@ -22,12 +22,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -55,10 +55,10 @@ public class KNAnalysisEventsHandlerTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - // yy this test is probably not doing anything with respect to some of the newer statistics, such as money. kai, mar'14 + // yy this test is probably not doing anything with respect to some of the newer statistics, such as money. kai, mar'14 public static final String BASE_FILE_NAME = "stats_"; public final Id DEFAULT_PERSON_ID = Id.create(123, Person.class); @@ -68,7 +68,7 @@ public class KNAnalysisEventsHandlerTest { private Population population = null ; private Network network = null ; - @Before + @BeforeEach public void setUp() throws Exception { scenario = ScenarioUtils.createScenario(ConfigUtils.createConfig()); @@ -101,15 +101,15 @@ public void setUp() throws Exception { this.network.addLink(link); } - @After + @AfterEach public void tearDown() throws Exception { this.population = null; this.network = null; } - @Test - @Ignore - public void testNoEvents() { + @Test + @Disabled + void testNoEvents() { KNAnalysisEventsHandler testee = new KNAnalysisEventsHandler(this.scenario); @@ -121,10 +121,10 @@ public void testNoEvents() { this.runTest(testee); } - @Test - @Ignore - public void testAveraging() { - // yy this test is probably not doing anything with respect to some of the newer statistics, such as money. kai, mar'14 + @Test + @Disabled + void testAveraging() { + // yy this test is probably not doing anything with respect to some of the newer statistics, such as money. kai, mar'14 KNAnalysisEventsHandler testee = new KNAnalysisEventsHandler(this.scenario); @@ -172,7 +172,7 @@ protected void runTest(KNAnalysisEventsHandler calcLegTimes) { LogManager.getLogger(this.getClass()).info( "comparing " + str ); final long expectedChecksum = CRCChecksum.getCRCFromFile(utils.getInputDirectory() + str); final long actualChecksum = CRCChecksum.getCRCFromFile(utils.getOutputDirectory() + str); - Assert.assertEquals("Output files differ.", expectedChecksum, actualChecksum); + Assertions.assertEquals(expectedChecksum, actualChecksum, "Output files differ."); } } diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/GridTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/GridTest.java index a3253515666..804de493d3a 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/GridTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/GridTest.java @@ -1,17 +1,17 @@ package org.matsim.contrib.analysis.spatial; -import static org.junit.Assert.assertEquals; - import java.util.Collection; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; public class GridTest { - @Test - public void initializeSquareGrid() { + @Test + void initializeSquareGrid() { final String testValue = "Test-value"; Grid grid = new SquareGrid<>(2, () -> testValue, SpatialTestUtils.createRect(10, 10)); @@ -23,8 +23,8 @@ public void initializeSquareGrid() { values.forEach(value -> assertEquals(testValue, value.getValue())); } - @Test - public void initializeHexagonalGrid() { + @Test + void initializeHexagonalGrid() { final String testValue = "test-value"; Grid grid = new HexagonalGrid<>(2, () -> testValue, SpatialTestUtils.createRect(10, 10)); @@ -38,8 +38,8 @@ public void initializeHexagonalGrid() { values.forEach(value -> assertEquals(testValue, value.getValue())); } - @Test - public void getArea_squareGrid() { + @Test + void getArea_squareGrid() { final double horizontalDistance = 2; final double expected = 2 * 2; // area of square is d^2 @@ -49,8 +49,8 @@ public void getArea_squareGrid() { assertEquals(expected, grid.getCellArea(), 0.0001); } - @Test - public void getArea_HexagonalGrid() { + @Test + void getArea_HexagonalGrid() { // actually area of hexagon is r^2 * sqrt(3)/2 final double horizontalDistance = 2; @@ -65,8 +65,8 @@ public void getArea_HexagonalGrid() { assertEquals(expected5, grid5.getCellArea(), 0.0001); } - @Test - public void getValue_withExactCoord() { + @Test + void getValue_withExactCoord() { final String testValue = "initialValue"; final Coordinate expectedCoordinate = new Coordinate(2, 1+Math.sqrt(3)); @@ -77,8 +77,8 @@ public void getValue_withExactCoord() { assertEquals(expectedCoordinate, result.getCoordinate()); } - @Test - public void getValue_closeCoordinate() { + @Test + void getValue_closeCoordinate() { final String testValue = "initialValue"; Grid grid = new HexagonalGrid<>(2, () -> testValue, SpatialTestUtils.createRect(10, 10)); @@ -89,8 +89,8 @@ public void getValue_closeCoordinate() { assertEquals(new Coordinate(2, 1+Math.sqrt(3)), result.getCoordinate()); } - @Test - public void getValue_coordOutsideOfGrid() { + @Test + void getValue_coordOutsideOfGrid() { final String testValue = "initialValue"; Grid grid = new HexagonalGrid<>(2, () -> testValue, SpatialTestUtils.createRect(10, 10)); @@ -100,8 +100,8 @@ public void getValue_coordOutsideOfGrid() { assertEquals(new Coordinate(8, 1 + 5*Math.sqrt(3)), result.getCoordinate()); } - @Test - public void getValues() { + @Test + void getValues() { final String testValue = "initialValue"; Grid grid = new HexagonalGrid<>(2, () -> testValue, SpatialTestUtils.createRect(10, 10)); diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/SpatialInterpolationTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/SpatialInterpolationTest.java index 49e3f8e4a8a..1fe102d3534 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/SpatialInterpolationTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/spatial/SpatialInterpolationTest.java @@ -1,15 +1,14 @@ package org.matsim.contrib.analysis.spatial; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; public class SpatialInterpolationTest { - @Test - public void calculateWeightFromLine() { + @Test + void calculateWeightFromLine() { final Coordinate from = new Coordinate(1, 1); final Coordinate to = new Coordinate(4, 5); @@ -22,33 +21,37 @@ public void calculateWeightFromLine() { assertEquals(0.0011109434390476694, weight, 0.001); } - @Test(expected = IllegalArgumentException.class) - public void calculateWeightFromLine_invalidSmoothingRadius() { + @Test + void calculateWeightFromLine_invalidSmoothingRadius() { + assertThrows(IllegalArgumentException.class, () -> { - final Coordinate from = new Coordinate(0, 1); - final Coordinate to = new Coordinate(10, 1); - final Coordinate cellCentroid = new Coordinate(5, 1); - final double smoothingRadius = 0; + final Coordinate from = new Coordinate(0, 1); + final Coordinate to = new Coordinate(10, 1); + final Coordinate cellCentroid = new Coordinate(5, 1); + final double smoothingRadius = 0; - double weight = SpatialInterpolation.calculateWeightFromLine(from, to, cellCentroid, smoothingRadius); + double weight = SpatialInterpolation.calculateWeightFromLine(from, to, cellCentroid, smoothingRadius); - fail("smoothing radius <= 0 should cause exception"); - } + fail("smoothing radius <= 0 should cause exception"); + }); + } - @Test(expected = IllegalArgumentException.class) - public void calculateWeightFromPoint_invalidSmoothingRadius() { + @Test + void calculateWeightFromPoint_invalidSmoothingRadius() { + assertThrows(IllegalArgumentException.class, () -> { - final Coordinate source = new Coordinate(10, 10); - final Coordinate centroid = new Coordinate(10, 10); - final double smoothingRadius = 0; + final Coordinate source = new Coordinate(10, 10); + final Coordinate centroid = new Coordinate(10, 10); + final double smoothingRadius = 0; - double weight = SpatialInterpolation.calculateWeightFromPoint(source, centroid, smoothingRadius); + double weight = SpatialInterpolation.calculateWeightFromPoint(source, centroid, smoothingRadius); - fail("smoothing radius <= 0 should cause exception"); - } + fail("smoothing radius <= 0 should cause exception"); + }); + } - @Test - public void calculateWeightFromPoint() { + @Test + void calculateWeightFromPoint() { final Coordinate point = new Coordinate(5, 5); final Coordinate cell = new Coordinate (9, 5); diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/time/TimeBinMapTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/time/TimeBinMapTest.java index a15b076f567..13e5e7f291c 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/time/TimeBinMapTest.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/time/TimeBinMapTest.java @@ -1,15 +1,15 @@ package org.matsim.contrib.analysis.time; -import org.junit.Test; - import java.util.Map; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; public class TimeBinMapTest { - @Test - public void getTimeBin() { + @Test + void getTimeBin() { TimeBinMap> map = new TimeBinMap<>(10); @@ -18,8 +18,8 @@ public void getTimeBin() { assertEquals(10, bin.getStartTime(), 0.001); } - @Test - public void getTimeBinWithStartTime() { + @Test + void getTimeBinWithStartTime() { TimeBinMap> map = new TimeBinMap<>(10, 20); @@ -28,18 +28,20 @@ public void getTimeBinWithStartTime() { assertEquals(20, bin.getStartTime(), 0.001); } - @Test(expected = IllegalArgumentException.class) - public void getTimeInvalidTime_exception() { + @Test + void getTimeInvalidTime_exception() { + assertThrows(IllegalArgumentException.class, () -> { - TimeBinMap> map = new TimeBinMap<>(10, 20); + TimeBinMap> map = new TimeBinMap<>(10, 20); - TimeBinMap.TimeBin> bin = map.getTimeBin(19); + TimeBinMap.TimeBin> bin = map.getTimeBin(19); - assertEquals(20, bin.getStartTime(), 0.001); - } + assertEquals(20, bin.getStartTime(), 0.001); + }); + } - @Test - public void getMultipleTimeBins() { + @Test + void getMultipleTimeBins() { TimeBinMap> map = new TimeBinMap<>(10); @@ -55,8 +57,8 @@ public void getMultipleTimeBins() { assertEquals(30, fourth.getStartTime(), 0.001); } - @Test - public void getEndOfLastTimeBucket() { + @Test + void getEndOfLastTimeBucket() { TimeBinMap> map = new TimeBinMap<>(10); @@ -68,8 +70,8 @@ public void getEndOfLastTimeBucket() { assertEquals(120, map.getEndTimeOfLastBin(), 0.0001); } - @Test - public void getAllTimeBins() { + @Test + void getAllTimeBins() { TimeBinMap> map = new TimeBinMap<>(10); @@ -81,8 +83,8 @@ public void getAllTimeBins() { assertEquals(4, map.getTimeBins().size()); } - @Test - public void timeBin_setEntry() { + @Test + void timeBin_setEntry() { final String testValue = "some-value"; @@ -97,7 +99,7 @@ public void timeBin_setEntry() { } @Test - public void timeBin_getValue() { + void timeBin_getValue() { final String testValue = "some-value"; diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest.java new file mode 100644 index 00000000000..96b87268dc9 --- /dev/null +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest.java @@ -0,0 +1,32 @@ +package org.matsim.contrib.analysis.vsp.traveltimedistance; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.core.utils.collections.Tuple; +import org.matsim.testcases.MatsimTestUtils; + +import java.io.*; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GoogleMapRouteValidatorTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void testReadJson() throws IOException { + GoogleMapRouteValidator googleMapRouteValidator = getDummyValidator(); + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(utils.getClassInputDirectory() + "route.json"))); + Optional> result = googleMapRouteValidator.readFromJson(reader); + assertTrue(result.isPresent()); + assertEquals(413, result.get().getFirst(), MatsimTestUtils.EPSILON); + assertEquals(2464, result.get().getSecond(), MatsimTestUtils.EPSILON); + } + + //All values with null filled are not necessary for this test + private GoogleMapRouteValidator getDummyValidator() { + return new GoogleMapRouteValidator(utils.getOutputDirectory(), null, null, null, null); + } +} diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest.java b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest.java new file mode 100644 index 00000000000..bd95386c9a0 --- /dev/null +++ b/contribs/analysis/src/test/java/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest.java @@ -0,0 +1,39 @@ +package org.matsim.contrib.analysis.vsp.traveltimedistance; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.core.utils.collections.Tuple; +import org.matsim.testcases.MatsimTestUtils; + +import java.io.*; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +public class HereMapsRouteValidatorTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void testReadJson() throws IOException { + HereMapsRouteValidator hereMapsRouteValidator = getDummyValidator(false); + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(utils.getClassInputDirectory() + "route.json"))); + Optional> result = hereMapsRouteValidator.readFromJson(reader, null); + assertTrue(result.isPresent()); + assertEquals(394, result.get().getFirst(), MatsimTestUtils.EPSILON); + assertEquals(2745, result.get().getSecond(), MatsimTestUtils.EPSILON); + } + + @Test + void testWriteFile() throws IOException { + HereMapsRouteValidator hereMapsRouteValidator = getDummyValidator(true); + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(utils.getClassInputDirectory() + "route.json"))); + hereMapsRouteValidator.readFromJson(reader, "tripId"); + assertTrue(new File(utils.getOutputDirectory() + "tripId.json.gz").isFile()); + } + + //All values with null filled are not necessary for this test + private HereMapsRouteValidator getDummyValidator(boolean writeDetailedFiles) { + return new HereMapsRouteValidator(utils.getOutputDirectory(), null, null, null, null, writeDetailedFiles); + } +} diff --git a/contribs/analysis/src/test/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiariesIT.java b/contribs/analysis/src/test/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiariesIT.java index 2fd76b243bd..c3a4f24d7fd 100644 --- a/contribs/analysis/src/test/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiariesIT.java +++ b/contribs/analysis/src/test/java/org/matsim/contrib/travelsummary/events2traveldiaries/RunEventsToTravelDiariesIT.java @@ -18,20 +18,20 @@ * *********************************************************************** */ package org.matsim.contrib.travelsummary.events2traveldiaries; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; /** * @author nagel */ public class RunEventsToTravelDiariesIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - @SuppressWarnings("static-method") - @Test - public final void test() { + @SuppressWarnings("static-method") + @Test + final void test() { String[] str = {"../../examples/scenarios/equil/config.xml", "../../examples/scenarios/equil/output_events.xml.gz", "_test", utils.getOutputDirectory()}; // This goes through the file system (nothing to do with resource paths etc.) diff --git a/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest/route.json b/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest/route.json new file mode 100644 index 00000000000..14e61b35177 --- /dev/null +++ b/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/GoogleMapRouteValidatorTest/route.json @@ -0,0 +1,30 @@ +{ + "destination_addresses": [ + "Kaiserin-Augusta-Allee 104, 10553 Berlin, Germany" + ], + "origin_addresses": [ + "B2 135, 10623 Berlin, Germany" + ], + "rows": [ + { + "elements": [ + { + "distance": { + "text": "2.5 km", + "value": 2464 + }, + "duration": { + "text": "7 mins", + "value": 400 + }, + "duration_in_traffic": { + "text": "7 mins", + "value": 413 + }, + "status": "OK" + } + ] + } + ], + "status": "OK" +} \ No newline at end of file diff --git a/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest/route.json b/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest/route.json new file mode 100644 index 00000000000..2dfdae5e032 --- /dev/null +++ b/contribs/analysis/test/input/org/matsim/contrib/analysis/vsp/traveltimedistance/HereMapsRouteValidatorTest/route.json @@ -0,0 +1,49 @@ +{ + "routes": [ + { + "id": "ed5396be-8f97-4c25-a373-a019da78b696", + "sections": [ + { + "id": "5f0ff311-d1d0-4a6a-a631-1c59fd5eaee4", + "type": "vehicle", + "departure": { + "time": "2023-12-11T10:00:00+01:00", + "place": { + "type": "place", + "location": { + "lat": 52.5127381, + "lng": 13.3268076 + }, + "originalLocation": { + "lat": 52.512638, + "lng": 13.326826 + } + } + }, + "arrival": { + "time": "2023-12-11T10:06:34+01:00", + "place": { + "type": "place", + "location": { + "lat": 52.5258281, + "lng": 13.3209817 + }, + "originalLocation": { + "lat": 52.5256489, + "lng": 13.320944 + } + } + }, + "summary": { + "duration": 394, + "length": 2745, + "baseDuration": 325 + }, + "transport": { + "mode": "car" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java index ff3b129cd80..89086cb00d3 100644 --- a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java +++ b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java @@ -6,7 +6,6 @@ import org.matsim.application.options.CrsOptions; import org.matsim.application.options.InputOptions; import org.matsim.application.options.OutputOptions; -import org.matsim.application.options.ShpOptions; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.scenario.ScenarioUtils; @@ -129,8 +128,8 @@ public static Scenario loadScenario(String runId, Path runDirectory, CrsOptions Config config = ConfigUtils.createConfig(); config.global().setCoordinateSystem(crs.getInputCRS()); - config.controler().setOutputDirectory(runDirectory.toString()); - config.controler().setRunId(resolvedRunId); + config.controller().setOutputDirectory(runDirectory.toString()); + config.controller().setRunId(resolvedRunId); config.plans().setInputFile(populationFile.toString()); config.network().setInputFile(networkFile.toString()); diff --git a/contribs/application/src/main/java/org/matsim/application/MATSimApplication.java b/contribs/application/src/main/java/org/matsim/application/MATSimApplication.java index 85b7c057064..c1951c1b2a4 100644 --- a/contribs/application/src/main/java/org/matsim/application/MATSimApplication.java +++ b/contribs/application/src/main/java/org/matsim/application/MATSimApplication.java @@ -11,9 +11,10 @@ import org.matsim.application.commands.RunScenario; import org.matsim.application.commands.ShowGUI; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigAliases; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.config.groups.GlobalConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.Controler; @@ -177,13 +178,13 @@ public Integer call() throws Exception { } if (iterations > -1) - config.controler().setLastIteration(iterations); + config.controller().setLastIteration(iterations); if (output != null) - config.controler().setOutputDirectory(output.toString()); + config.controller().setOutputDirectory(output.toString()); if (runId != null) - config.controler().setRunId(runId); + config.controller().setRunId(runId); final Scenario scenario = createScenario(config); @@ -199,7 +200,7 @@ public Integer call() throws Exception { if (post != PostProcessOption.disabled) { - List commands = preparePostProcessing(Path.of(config.controler().getOutputDirectory()), config.controler().getRunId()); + List commands = preparePostProcessing(Path.of(config.controller().getOutputDirectory()), config.controller().getRunId()); for (MATSimAppCommand command : commands) { @@ -230,6 +231,9 @@ private static void applySpecs(Config config, Path specs) { ObjectMapper mapper = new ObjectMapper(new YAMLFactory() .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)); + ConfigAliases aliases = new ConfigAliases(); + Deque emptyStack = new ArrayDeque<>(); + try (BufferedReader reader = Files.newBufferedReader(specs)) { JsonNode node = mapper.readTree(reader); @@ -238,10 +242,10 @@ private static void applySpecs(Config config, Path specs) { while (fields.hasNext()) { Map.Entry field = fields.next(); - - ConfigGroup group = config.getModules().get(field.getKey()); + String configGroupName = aliases.resolveAlias(field.getKey(), emptyStack); + ConfigGroup group = config.getModules().get(configGroupName); if (group == null) { - log.warn("Config group not found: {}", field.getKey()); + log.warn("Config group not found: {}", configGroupName); continue; } @@ -313,7 +317,7 @@ protected List getCustomModules() { */ protected List getConfigurableModules() { return Lists.newArrayList( - new ControlerConfigGroup(), + new ControllerConfigGroup(), new GlobalConfigGroup(), new QSimConfigGroup() ); @@ -370,14 +374,14 @@ protected final void addRunOption(Config config, String option, Object value) { else postfix = "-" + option + "_" + value; - String outputDir = config.controler().getOutputDirectory(); + String outputDir = config.controller().getOutputDirectory(); if (outputDir.endsWith("/")) { - config.controler().setOutputDirectory(outputDir.substring(0, outputDir.length() - 1) + postfix + "/"); + config.controller().setOutputDirectory(outputDir.substring(0, outputDir.length() - 1) + postfix + "/"); } else - config.controler().setOutputDirectory(outputDir + postfix); + config.controller().setOutputDirectory(outputDir + postfix); // dot should not be part of run id - config.controler().setRunId(config.controler().getRunId() + postfix.replace(".", "")); + config.controller().setRunId(config.controller().getRunId() + postfix.replace(".", "")); } /** diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java index f273c87adfe..eca4eee1e0b 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java @@ -142,8 +142,8 @@ private Config prepareConfig() { config.transit().setTransitScheduleFile(ApplicationUtils.matchInput("transitSchedule", input.getRunDirectory()).toAbsolutePath().toString()); config.transit().setVehiclesFile(ApplicationUtils.matchInput("transitVehicles", input.getRunDirectory()).toAbsolutePath().toString()); config.plans().setInputFile(null); - config.parallelEventHandling().setNumberOfThreads(null); - config.parallelEventHandling().setEstimatedNumberOfEvents(null); + config.eventsManager().setNumberOfThreads(null); + config.eventsManager().setEstimatedNumberOfEvents(null); config.global().setNumberOfThreads(1); return config; diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionByVehicleCategory.java b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionByVehicleCategory.java index 7b02f55fa53..20bf17af5c6 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionByVehicleCategory.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionByVehicleCategory.java @@ -135,8 +135,8 @@ public Integer call() throws Exception { config.transit().setVehiclesFile(globFile(runDirectory, runId, "transitVehicles")); config.global().setCoordinateSystem(crs.getInputCRS()); config.plans().setInputFile(null); - config.parallelEventHandling().setNumberOfThreads(null); - config.parallelEventHandling().setEstimatedNumberOfEvents(null); + config.eventsManager().setNumberOfThreads(null); + config.eventsManager().setEstimatedNumberOfEvents(null); config.global().setNumberOfThreads(1); EmissionsConfigGroup eConfig = ConfigUtils.addOrGetModule(config, EmissionsConfigGroup.class); diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java index 964ce79c6a8..3e99b052194 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java @@ -71,7 +71,7 @@ public Integer call() throws Exception { if (!runDirectory.endsWith("/")) runDirectory = runDirectory + "/"; config.global().setCoordinateSystem(crs.getInputCRS()); - config.controler().setRunId(runId); + config.controller().setRunId(runId); if (!runId.equals("")) { config.network().setInputFile(runDirectory + runId + ".output_network.xml.gz"); config.plans().setInputFile(runDirectory + runId + ".output_plans.xml.gz"); @@ -79,7 +79,7 @@ public Integer call() throws Exception { config.network().setInputFile(runDirectory + "output_network.xml.gz"); config.plans().setInputFile(runDirectory + "output_plans.xml.gz"); } - config.controler().setOutputDirectory(runDirectory); + config.controller().setOutputDirectory(runDirectory); // adjust the default noise parameters NoiseConfigGroup noiseParameters = ConfigUtils.addOrGetModule(config, NoiseConfigGroup.class); diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java index 9ff85eb7b67..35f11ab09d6 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java @@ -92,6 +92,7 @@ public Integer call() throws Exception { Table persons = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("persons.csv"))) .columnTypesPartial(Map.of("person", ColumnType.TEXT)) + .sample(false) .separator(';').build()); int total = persons.rowCount(); @@ -132,6 +133,7 @@ public Integer call() throws Exception { Table trips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("trips.csv"))) .columnTypesPartial(columnTypes) + .sample(false) .separator(';').build()); diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/CountComparisonAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/CountComparisonAnalysis.java index 42985e22beb..adc9a86f435 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/CountComparisonAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/CountComparisonAnalysis.java @@ -1,5 +1,7 @@ package org.matsim.application.analysis.traffic; +import it.unimi.dsi.fastutil.ints.Int2DoubleMap; +import it.unimi.dsi.fastutil.ints.Int2DoubleOpenHashMap; import org.matsim.analysis.VolumesAnalyzer; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -13,10 +15,7 @@ import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.events.EventsUtils; import org.matsim.core.network.NetworkUtils; -import org.matsim.counts.Count; -import org.matsim.counts.Counts; -import org.matsim.counts.MatsimCountsReader; -import org.matsim.counts.Volume; +import org.matsim.counts.*; import picocli.CommandLine; import tech.tablesaw.api.*; import tech.tablesaw.selection.Selection; @@ -29,7 +28,7 @@ @CommandLine.Command(name = "count-comparison", description = "Produces comparisons of observed and simulated counts.") @CommandSpec(requireEvents = true, requireCounts = true, requireNetwork = true, - produces = {"count_comparison_by_hour.csv", "count_comparison_daily.csv", "count_comparison_quality.csv", "count_error_by_hour.csv"}) + produces = {"count_comparison_by_hour.csv", "count_comparison_daily.csv", "count_comparison_quality.csv", "count_error_by_hour.csv"}) public class CountComparisonAnalysis implements MATSimAppCommand { @CommandLine.Mixin @@ -47,7 +46,7 @@ public class CountComparisonAnalysis implements MATSimAppCommand { @CommandLine.Option(names = "--labels", split = ",", description = "Labels for quality categories", defaultValue = "major under,under,ok,over,major over") private List labels; - @CommandLine.Option(names = "--transport-mode", description = "Mode to analyze", split = ",", defaultValue = TransportMode.car) + @CommandLine.Option(names = {"--network-mode", "--transport-mode"}, description = "Mode(s) to analyze", split = ",", defaultValue = TransportMode.car) private Set modes; public static void main(String[] args) { @@ -65,6 +64,9 @@ private static String cut(double relError, List errorGroups, List counts, Network network, VolumesAnalyzer Map, ? extends Link> links = network.getLinks(); Table byHour = Table.create( - StringColumn.create("link_id"), - StringColumn.create("name"), - StringColumn.create("road_type"), - IntColumn.create("hour"), - DoubleColumn.create("observed_traffic_volume"), - DoubleColumn.create("simulated_traffic_volume") + StringColumn.create("link_id"), + StringColumn.create("name"), + StringColumn.create("road_type"), + IntColumn.create("hour"), + DoubleColumn.create("observed_traffic_volume"), + DoubleColumn.create("simulated_traffic_volume") ); Table dailyTrafficVolume = Table.create(StringColumn.create("link_id"), - StringColumn.create("name"), - StringColumn.create("road_type"), - DoubleColumn.create("observed_traffic_volume"), - DoubleColumn.create("simulated_traffic_volume") + StringColumn.create("name"), + StringColumn.create("road_type"), + DoubleColumn.create("observed_traffic_volume"), + DoubleColumn.create("simulated_traffic_volume") ); - for (Map.Entry, Count> entry : counts.getCounts().entrySet()) { + for (Map.Entry, MeasurementLocation> entry : counts.getMeasureLocations().entrySet()) { Id key = entry.getKey(); - Map countVolume = entry.getValue().getVolumes(); - String name = entry.getValue().getCsLabel(); + + Int2DoubleMap countVolume = aggregateObserved(entry.getValue(), modes); + + String name = entry.getValue().getDisplayName(); Link link = links.get(key); String type = NetworkUtils.getHighwayType(link); @@ -134,9 +138,9 @@ private Table writeOutput(Counts counts, Network network, VolumesAnalyzer continue; Optional opt = modes.stream() - .map(mode -> volumes.getVolumesForLink(key, mode)) - .filter(Objects::nonNull) - .reduce(CountComparisonAnalysis::sum); + .map(mode -> volumes.getVolumesForLink(key, mode)) + .filter(Objects::nonNull) + .reduce(CountComparisonAnalysis::sum); int[] volumesForLink; if (countVolume.isEmpty() || opt.isEmpty()) { @@ -148,12 +152,13 @@ private Table writeOutput(Counts counts, Network network, VolumesAnalyzer double simulatedTrafficVolumeByDay = 0; double observedTrafficVolumeByDay = 0; - if (countVolume.size() == 24) { + // Hourly values are present + if (countVolume.size() > 1 || !countVolume.containsKey(24)) { - for (int hour = 1; hour < 25; hour++) { + for (int hour = 0; hour < 24; hour++) { - double observedTrafficVolumeAtHour = countVolume.get(hour).getValue(); - double simulatedTrafficVolumeAtHour = (double) volumesForLink[hour - 1] / this.sample.getSample(); + double observedTrafficVolumeAtHour = countVolume.get(hour); + double simulatedTrafficVolumeAtHour = (double) volumesForLink[hour] / this.sample.getSample(); simulatedTrafficVolumeByDay += simulatedTrafficVolumeAtHour; observedTrafficVolumeByDay += observedTrafficVolumeAtHour; @@ -162,12 +167,15 @@ private Table writeOutput(Counts counts, Network network, VolumesAnalyzer row.setString("link_id", key.toString()); row.setString("name", name); row.setString("road_type", type); - row.setInt("hour", hour - 1); + row.setInt("hour", hour); row.setDouble("observed_traffic_volume", observedTrafficVolumeAtHour); row.setDouble("simulated_traffic_volume", simulatedTrafficVolumeAtHour); } - } else - observedTrafficVolumeByDay = countVolume.values().stream().mapToDouble(Volume::getValue).sum(); + } else { + // Get the daily values + observedTrafficVolumeByDay = countVolume.get(24); + simulatedTrafficVolumeByDay = Arrays.stream(volumesForLink).sum() / this.sample.getSample(); + } Row row = dailyTrafficVolume.appendRow(); row.setString("link_id", key.toString()); @@ -178,12 +186,12 @@ private Table writeOutput(Counts counts, Network network, VolumesAnalyzer } DoubleColumn relError = dailyTrafficVolume.doubleColumn("simulated_traffic_volume") - .divide(dailyTrafficVolume.doubleColumn("observed_traffic_volume")) - .setName("rel_error"); + .divide(dailyTrafficVolume.doubleColumn("observed_traffic_volume")) + .setName("rel_error"); StringColumn qualityLabel = relError.copy() - .map(err -> cut(err, limits, labels), ColumnType.STRING::create) - .setName("quality"); + .map(err -> cut(err, limits, labels), ColumnType.STRING::create) + .setName("quality"); dailyTrafficVolume.addColumns(relError, qualityLabel); @@ -220,20 +228,47 @@ private Table writeOutput(Counts counts, Network network, VolumesAnalyzer return byHour; } + /** + * Aggregate observed counts by hour. Starting at 0. + */ + private static Int2DoubleMap aggregateObserved(MeasurementLocation m, Set modes) { + + Int2DoubleOpenHashMap map = new Int2DoubleOpenHashMap(); + + for (String mode : modes) { + Measurable volumes = m.getVolumesForMode(mode); + if (volumes == null) + continue; + + if (volumes.supportsHourlyAggregate()) { + for (int i = 0; i < 24; i++) { + OptionalDouble v = volumes.aggregateAtHour(i); + if (v.isPresent()) + map.mergeDouble(i, v.getAsDouble(), Double::sum); + } + } else { + // Daily value is stored under separate key + map.mergeDouble(24, volumes.aggregateDaily(), Double::sum); + } + } + + return map; + } + private void writeErrorMetrics(Table byHour, Path path) { byHour.addColumns( - byHour.doubleColumn("simulated_traffic_volume").subtract(byHour.doubleColumn("observed_traffic_volume")).setName("error") + byHour.doubleColumn("simulated_traffic_volume").subtract(byHour.doubleColumn("observed_traffic_volume")).setName("error") ); byHour.addColumns( - byHour.doubleColumn("error").abs().setName("abs_error") + byHour.doubleColumn("error").abs().setName("abs_error") ); DoubleColumn relError = byHour.doubleColumn("abs_error") - .multiply(100) - .divide(byHour.doubleColumn("observed_traffic_volume")) - .setName("rel_error"); + .multiply(100) + .divide(byHour.doubleColumn("observed_traffic_volume")) + .setName("rel_error"); // Cut-off at Max error relError = relError.set(relError.isMissing(), 1000d); diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/SampleValidationRoutes.java b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/SampleValidationRoutes.java index da7a70673d6..168bf28499e 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/SampleValidationRoutes.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/SampleValidationRoutes.java @@ -24,8 +24,8 @@ import org.matsim.application.options.OutputOptions; import org.matsim.application.options.ShpOptions; import org.matsim.core.network.NetworkUtils; -import org.matsim.core.router.FastDijkstraFactory; import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility; +import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.scenario.ProjectionUtils; import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; @@ -156,7 +156,7 @@ public Integer call() throws Exception { FreeSpeedTravelTime tt = new FreeSpeedTravelTime(); OnlyTimeDependentTravelDisutility util = new OnlyTimeDependentTravelDisutility(tt); - LeastCostPathCalculator router = new FastDijkstraFactory(false).createPathCalculator(network, util, tt); + LeastCostPathCalculator router = new SpeedyALTFactory().createPathCalculator(network, util, tt); List routes = sampleRoutes(network, router, rnd); diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/TravelTimeComparison.java b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/TravelTimeComparison.java index 5947ce4231b..3c22fc678a3 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/TravelTimeComparison.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/TravelTimeComparison.java @@ -11,15 +11,14 @@ import org.matsim.application.options.OutputOptions; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.events.EventsUtils; -import org.matsim.core.router.FastDijkstraFactory; import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility; +import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.TravelTime; import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; import org.matsim.core.trafficmonitoring.TravelTimeCalculator; import org.matsim.core.utils.io.IOUtils; import picocli.CommandLine; -import scala.util.parsing.combinator.testing.Str; import tech.tablesaw.api.ColumnType; import tech.tablesaw.api.DoubleColumn; import tech.tablesaw.api.Row; @@ -81,8 +80,8 @@ public Integer call() throws Exception { OnlyTimeDependentTravelDisutility util = new OnlyTimeDependentTravelDisutility(tt); - LeastCostPathCalculator congestedRouter = new FastDijkstraFactory(false).createPathCalculator(network, util, tt); - LeastCostPathCalculator freeflowRouter = new FastDijkstraFactory(false).createPathCalculator(network, new OnlyTimeDependentTravelDisutility(fs), fs); + LeastCostPathCalculator congestedRouter = new SpeedyALTFactory().createPathCalculator(network, util, tt); + LeastCostPathCalculator freeflowRouter = new SpeedyALTFactory().createPathCalculator(network, new OnlyTimeDependentTravelDisutility(fs), fs); data.addColumns( DoubleColumn.create("simulated", data.rowCount()), diff --git a/contribs/application/src/main/java/org/matsim/application/options/ScenarioOptions.java b/contribs/application/src/main/java/org/matsim/application/options/ScenarioOptions.java index 551a42b4e07..d916b288139 100644 --- a/contribs/application/src/main/java/org/matsim/application/options/ScenarioOptions.java +++ b/contribs/application/src/main/java/org/matsim/application/options/ScenarioOptions.java @@ -23,7 +23,7 @@ public class ScenarioOptions { private String scenarioArgs; @CommandLine.Option(names = "--population", description = "Path to input population") - private Path populationPath; + private String populationPath; private Config config; @@ -35,7 +35,7 @@ public Config getConfig() { config = ConfigUtils.loadConfig(configPath); if (populationPath != null) - config.plans().setInputFile(populationPath.toString()); + config.plans().setInputFile(populationPath); } return config; diff --git a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java index d4c7b45342f..a541548a7d9 100644 --- a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java +++ b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java @@ -7,9 +7,7 @@ import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.shapefile.ShapefileDataStoreFactory; import org.geotools.referencing.CRS; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.Envelope; -import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.*; import org.locationtech.jts.index.strtree.AbstractNode; import org.locationtech.jts.index.strtree.Boundable; import org.locationtech.jts.index.strtree.ItemBoundable; @@ -18,22 +16,30 @@ import org.matsim.api.core.v01.Coord; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.core.utils.geometry.transformations.IdentityTransformation; import org.matsim.core.utils.geometry.transformations.TransformationFactory; import org.matsim.core.utils.gis.ShapeFileReader; +import org.matsim.core.utils.io.IOUtils; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; -import javax.annotation.Nullable; import picocli.CommandLine; + +import javax.annotation.Nullable; import java.io.IOException; import java.io.UncheckedIOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.charset.Charset; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; /** * Reusable class for shape file options. @@ -42,10 +48,15 @@ */ public final class ShpOptions { + /** + * Special value for {@link #createIndex(String, String)} to use the same crs as the shape file. + */ + public static final String SAME_CRS = "same_crs"; + private static final Logger log = LogManager.getLogger(ShpOptions.class); @CommandLine.Option(names = "--shp", description = "Optional path to shape file used for filtering", required = false) - private Path shp; + private String shp; @CommandLine.Option(names = "--shp-crs", description = "Overwrite coordinate system of the shape file") private String shpCrs; @@ -60,22 +71,72 @@ public ShpOptions() { * Constructor to use shape options manually. */ public ShpOptions(Path shp, @Nullable String shpCrs, @Nullable Charset shpCharset) { + this.shp = shp == null ? null : shp.toString(); + this.shpCrs = shpCrs; + this.shpCharset = shpCharset; + } + + /** + * Constructor to use shape options manually. + */ + public ShpOptions(String shp, @Nullable String shpCrs, @Nullable Charset shpCharset) { this.shp = shp; this.shpCrs = shpCrs; this.shpCharset = shpCharset; } + /** + * Opens datastore to a shape-file. + */ + public static ShapefileDataStore openDataStore(String shp) throws IOException { + + FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory(); + + URL url = IOUtils.resolveFileOrResource(shp); + + ShapefileDataStore ds; + if (shp.endsWith(".shp")) + ds = (ShapefileDataStore) factory.createDataStore(url); + else if (shp.endsWith(".zip")) { + + // Zip files will only work with local files + URI uri; + try (ZipInputStream zip = new ZipInputStream(IOUtils.getInputStream(url))) { + + ZipEntry entry; + while ((entry = zip.getNextEntry()) != null) { + if (entry.getName().endsWith(".shp")) + break; + } + + if (entry == null) + throw new IllegalArgumentException("No .shp file found in the zip."); + + log.info("Using {} from {}", entry.getName(), shp); + uri = new URI("jar:" + url + "!/" + entry.getName()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Could not create URI for zip file: " + url, e); + } + + ds = (ShapefileDataStore) factory.createDataStore(uri.toURL()); + } else { + throw new IllegalArgumentException("Shape file must either be .zip or .shp, but was: " + shp); + } + + return ds; + } + /** * Return whether a shape was set. */ public boolean isDefined() { - return shp != null && !shp.toString().isBlank() && !shp.toString().equals("none"); + return shp != null && !shp.isBlank() && !shp.equals("none"); } /** * Get the provided input crs. */ - public Path getShapeFile() { + public String getShapeFile() { return shp; } @@ -94,8 +155,6 @@ public String getShapeCrs() { public List readFeatures() { if (shp == null) throw new IllegalStateException("Shape file path not specified"); - if (!Files.exists(shp)) - throw new IllegalStateException(String.format("Shape file %s does not exists", shp)); try { ShapefileDataStore ds = openDataStore(shp); @@ -108,57 +167,33 @@ public List readFeatures() { } } - /** - * Opens datastore to a shape-file. - */ - public static ShapefileDataStore openDataStore(Path shp) throws IOException { - - FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory(); - - ShapefileDataStore ds; - if (shp.toString().endsWith(".shp")) - ds = (ShapefileDataStore) factory.createDataStore(shp.toUri().toURL()); - else if (shp.toString().endsWith(".zip")) { - - FileSystem fs = FileSystems.newFileSystem(shp, ClassLoader.getSystemClassLoader()); - Optional match = Files.walk(fs.getPath("/")) - .filter(p -> p.toString().endsWith(".shp")) - .findFirst(); - - if (match.isEmpty()) - throw new IllegalArgumentException("No .shp file found in the zip."); - - log.info("Using {} from {}", match.get(), shp); - ds = (ShapefileDataStore) factory.createDataStore(match.get().toUri().toURL()); - } else { - throw new IllegalArgumentException("Shape file must either be .zip or .shp, but was: " + shp); - } - - return ds; - } - /** * Return the union of all geometries in the shape file. */ public Geometry getGeometry() { Collection features = readFeatures(); - if (features.size() < 1) { + if (features.isEmpty()) { throw new IllegalStateException("There is no feature in the shape file. Aborting..."); } - Geometry geometry = (Geometry) features.iterator().next().getDefaultGeometry(); - if (features.size() > 1) { - for (SimpleFeature simpleFeature : features) { - if (simpleFeature.getDefaultGeometry() == null) { - log.warn("Features {} has no geometry", simpleFeature); - continue; - } - Geometry subArea = (Geometry) simpleFeature.getDefaultGeometry(); - geometry = geometry.union(subArea); - } + if (features.size() == 1) { + return (Geometry) features.iterator().next().getDefaultGeometry(); + } + + GeometryFactory factory = ((Geometry) features.iterator().next().getDefaultGeometry()).getFactory(); + + GeometryCollection geometryCollection = (GeometryCollection) factory.buildGeometry( + features.stream() + .filter(f -> f.getDefaultGeometry() != null) + .map(f -> (Geometry) f.getDefaultGeometry()).toList() + ); + + if (geometryCollection.isEmpty()) { + throw new IllegalStateException("There are noe geometries in the shape file."); } - return geometry; + + return geometryCollection.union(); } /** @@ -172,15 +207,18 @@ public Index createIndex(String queryCRS, String attr, Set filter) { if (!isDefined()) throw new IllegalStateException("Shape file path not specified"); - if (!Files.exists(shp)) - throw new IllegalStateException(String.format("Shape file %s does not exists", shp)); if (queryCRS == null) throw new IllegalArgumentException("Query crs must not be null!"); - CoordinateTransformation ct = TransformationFactory.getCoordinateTransformation(queryCRS, detectCRS()); - try { - return new Index(ct, attr, filter); + ShapefileDataStore ds = openDataStoreAndSetCRS(); + CoordinateTransformation ct; + if (queryCRS.equals(SAME_CRS)) + ct = new IdentityTransformation(); + else { + ct = TransformationFactory.getCoordinateTransformation(queryCRS, shpCrs); + } + return new Index(ct, ds, attr, filter); } catch (IOException e) { throw new UncheckedIOException(e); } @@ -195,6 +233,15 @@ public Index createIndex(String queryCRS, String attr) { return createIndex(queryCRS, attr, null); } + /** + * Create an index without a filter and the same query crs as the shape file. + * + * @see #createIndex(String, String) + */ + public Index createIndex(String attr) { + return createIndex(SAME_CRS, attr, null); + } + /** * Create a coordinate transformation to the shape file crs. Tries to autodetect the crs of the shape file. */ @@ -220,6 +267,25 @@ private String detectCRS() { return shpCrs; } + /** + * Open the shape file for processing and set the crs if not already specified. + */ + private ShapefileDataStore openDataStoreAndSetCRS() throws IOException { + ShapefileDataStore ds = openDataStore(shp); + + if (shpCrs == null) { + try { + CoordinateReferenceSystem crs = ds.getSchema().getCoordinateReferenceSystem(); + shpCrs = "EPSG:" + CRS.lookupEpsgCode(crs, true); + log.info("Using detected crs for {}: {}", shp, shpCrs); + } catch (FactoryException | NullPointerException e) { + throw new IllegalStateException("Could not determine crs of the shape file. Try to specify it manually using --shp-crs.", e); + } + } + + return ds; + } + /** * Create an inverse coordinate transformation from the shape file crs. Tries to autodetect the crs of the shape file. */ @@ -242,10 +308,7 @@ public final class Index { * @param ct coordinate transform from query to target crs * @param attr attribute for the result of {@link #query(Coord)} */ - Index(CoordinateTransformation ct, String attr, @Nullable Set filter) - throws IOException { - ShapefileDataStore ds = openDataStore(shp); - + Index(CoordinateTransformation ct, ShapefileDataStore ds, String attr, @Nullable Set filter) throws IOException { if (shpCharset != null) ds.setCharset(shpCharset); @@ -316,11 +379,10 @@ public boolean contains(Coord coord) { return false; } - /** * Return all features in the index. */ - public List getAll() { + public List getAllFeatures() { List result = new ArrayList<>(); itemsTree(result, index.getRoot()); @@ -346,6 +408,14 @@ private void itemsTree(List list, AbstractNode node) { public int size() { return index.size(); } + + /** + * Return underlying shp file. Should be used carefully. + */ + public ShpOptions getShp() { + return ShpOptions.this; + } + } } diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/ShapeFileTextLookup.java b/contribs/application/src/main/java/org/matsim/application/prepare/ShapeFileTextLookup.java index 6242e889061..1be1a71eed1 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/ShapeFileTextLookup.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/ShapeFileTextLookup.java @@ -59,15 +59,10 @@ public Integer call() throws Exception { return 1; } - if (shp.getShapeFile() == null) { + if (!shp.isDefined()) { throw new IllegalArgumentException("Shape file must be given!"); } - if (!Files.exists(shp.getShapeFile())) { - log.error("Shape file {} does not exists", shp.getShapeFile()); - return 1; - } - List features = shp.readFeatures(); Map map = new HashMap<>(); diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/counts/CreateCountsFromBAStData.java b/contribs/application/src/main/java/org/matsim/application/prepare/counts/CreateCountsFromBAStData.java index 1018c9e0696..dd02f6572ee 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/counts/CreateCountsFromBAStData.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/counts/CreateCountsFromBAStData.java @@ -21,9 +21,10 @@ import org.matsim.core.utils.geometry.geotools.MGC; import org.matsim.core.utils.geometry.transformations.TransformationFactory; import org.matsim.core.utils.io.IOUtils; -import org.matsim.counts.Count; import org.matsim.counts.Counts; import org.matsim.counts.CountsWriter; +import org.matsim.counts.Measurable; +import org.matsim.counts.MeasurementLocation; import picocli.CommandLine; import java.io.BufferedReader; @@ -56,43 +57,29 @@ @CommandLine.Command(name = "counts-from-bast", description = "Creates MATSim from BASt Stundenwerte.txt") public class CreateCountsFromBAStData implements MATSimAppCommand { - @CommandLine.Option(names = "--network", description = "path to MATSim network", required = true) - private String network; - + private static final Logger log = LogManager.getLogger(CreateCountsFromBAStData.class); @CommandLine.Option(names = "--road-types", description = "Define on which roads counts are created") private final List roadTypes = List.of("motorway", "primary", "trunk"); - + @CommandLine.Mixin + private final ShpOptions shp = new ShpOptions(); + @CommandLine.Mixin + private final CountsOption counts = new CountsOption(); + @CommandLine.Mixin + private final CrsOptions crs = new CrsOptions("EPSG:25832"); + @CommandLine.Option(names = "--network", description = "path to MATSim network", required = true) + private String network; @CommandLine.Option(names = "--primary-data", description = "path to BASt Bundesstraßen-'Stundenwerte'-.txt file", required = true) private Path primaryData; - @CommandLine.Option(names = "--motorway-data", description = "path to BASt Bundesautobahnen-'Stundenwerte'-.txt file", required = true) private Path motorwayData; - @CommandLine.Option(names = "--station-data", description = "path to default BASt count station .csv", required = true) private Path stationData; - @CommandLine.Option(names = "--search-range", description = "range for the buffer around count stations, in which links are queried", defaultValue = "50") private double searchRange; - @CommandLine.Option(names = "--year", description = "Year of counts", required = true) private int year; - - @CommandLine.Option(names = "--car-output", description = "output car counts path", defaultValue = "car-counts-from-bast.xml.gz") - private Path carOutput; - - @CommandLine.Option(names = "--freight-output", description = "output freight counts path", defaultValue = "freight-counts-from-bast.xml.gz") - private Path freightOutput; - - @CommandLine.Mixin - private final ShpOptions shp = new ShpOptions(); - - @CommandLine.Mixin - private final CountsOption counts = new CountsOption(); - - @CommandLine.Mixin - private final CrsOptions crs = new CrsOptions("EPSG:25832"); - - private static final Logger log = LogManager.getLogger(CreateCountsFromBAStData.class); + @CommandLine.Option(names = "--output", description = "Output counts path", defaultValue = "counts-from-bast.xml.gz") + private Path output; public static void main(String[] args) { new CreateCountsFromBAStData().execute(args); @@ -111,21 +98,23 @@ public Integer call() { readHourlyTrafficVolume(motorwayData, stations); log.info("+++++++ Map aggregated traffic volumes to count stations +++++++"); - Counts miv = new Counts<>(); - Counts freight = new Counts<>(); - stations.values().forEach(station -> mapTrafficVolumeToCount(station, miv, freight)); - miv.setYear(year); - freight.setYear(year); + Counts mmCounts = new Counts<>(); + mmCounts.setYear(year); + mmCounts.setName("BASt Counts"); + mmCounts.setSource("Bundesanstalt für Straßenwesen"); + mmCounts.setDescription("Aggregated daily traffic volumes for car and freight traffic."); + + stations.values().forEach(station -> mapTrafficVolumeToCount(station, mmCounts)); + + log.info("+++++++ Write MATSim counts to {} +++++++", output); + new CountsWriter(mmCounts).write(output.toString()); - log.info("+++++++ Write MATSim counts to {} and {} +++++++", carOutput, freightOutput); - new CountsWriter(miv).write(carOutput.toString()); - new CountsWriter(freight).write(freightOutput.toString()); return 0; } - private void mapTrafficVolumeToCount(BAStCountStation station, Counts miv, Counts freight) { + private void mapTrafficVolumeToCount(BAStCountStation station, Counts counts) { if (!station.hasMatchedLink()) return; @@ -135,18 +124,21 @@ private void mapTrafficVolumeToCount(BAStCountStation station, Counts miv, return; } - Count mivCount = miv.createAndAddCount(station.getMatchedLink().getId(), station.getName() + "_" + station.getDirection()); - Count freightCount = freight.createAndAddCount(station.getMatchedLink().getId(), station.getName() + "_" + station.getDirection()); + MeasurementLocation multiModeCount = counts.createAndAddMeasureLocation(station.getMatchedLink().getId(), station.getName() + "_" + station.getDirection()); + + Measurable carVolume = multiModeCount.createVolume(TransportMode.car); + Measurable freightVolume = multiModeCount.createVolume(TransportMode.truck); var mivTrafficVolumes = station.getMivTrafficVolume(); var freightTrafficVolumes = station.getFreightTrafficVolume(); for (String hour : mivTrafficVolumes.keySet()) { - - if (hour.startsWith("0")) hour.replace("0", ""); int h = Integer.parseInt(hour); - mivCount.createVolume(h, mivTrafficVolumes.get(hour)); - freightCount.createVolume(h, freightTrafficVolumes.get(hour)); + Double mivAtHour = mivTrafficVolumes.get(hour); + Double freightAtHour = freightTrafficVolumes.get(hour); + + carVolume.setAtHour(h, mivAtHour); + freightVolume.setAtHour(h, freightAtHour); } } @@ -194,31 +186,31 @@ private void readHourlyTrafficVolume(Path pathToDisaggregatedData, Map keys = stations.keySet().stream() - .map(key -> key.replaceAll("_1", "").replaceAll("_2", "")) - .collect(Collectors.toSet()); + .map(key -> key.replaceAll("_1", "").replaceAll("_2", "")) + .collect(Collectors.toSet()); // Filter for weekday Tuesday-Wednesday preFilteredRecords = StreamSupport.stream(records.spliterator(), false) - .filter(row -> keys.contains(row.get("Zst"))) - .filter(row -> { - int day; - try { - day = Integer.parseInt(row.get("Wotag").replace(" ", "")); - } catch (NumberFormatException e) { - log.warn("Error parsing week day number: {}", row.get("Wotag")); - return false; - } - return day > 1 && day < 5; - }) - .collect(Collectors.toList()); + .filter(row -> keys.contains(row.get("Zst"))) + .filter(row -> { + int day; + try { + day = Integer.parseInt(row.get("Wotag").replace(" ", "")); + } catch (NumberFormatException e) { + log.warn("Error parsing week day number: {}", row.get("Wotag")); + return false; + } + return day > 1 && day < 5; + }) + .collect(Collectors.toList()); if (preFilteredRecords == null || preFilteredRecords.isEmpty()) { log.warn("Records read from {} don't contain the stations ... ", pathToDisaggregatedData); @@ -228,8 +220,8 @@ private void readHourlyTrafficVolume(Path pathToDisaggregatedData, Map stationIds = preFilteredRecords.stream() - .map(row -> row.get("Zst")) - .collect(Collectors.toSet()); + .map(row -> row.get("Zst")) + .collect(Collectors.toSet()); for (String number : stationIds) { BAStCountStation direction1 = stations.get(number + "_1"); @@ -244,12 +236,12 @@ private void readHourlyTrafficVolume(Path pathToDisaggregatedData, Map allEntriesOfStation = preFilteredRecords.stream() - .filter(row -> row.get("Zst").equals(number)).toList(); + .filter(row -> row.get("Zst").equals(number)).toList(); for (String hour : hours) { var hourlyTrafficVolumes = allEntriesOfStation.stream() - .filter(row -> row.get("Stunde").replace("\"", "") - .equals(hour)).toList(); + .filter(row -> row.get("Stunde").replace("\"", "") + .equals(hour)).toList(); if (hourlyTrafficVolumes.isEmpty()) { log.warn("No volume for station {} at hour {}", direction1.getName(), hour); @@ -258,12 +250,12 @@ private void readHourlyTrafficVolume(Path pathToDisaggregatedData, Map Double.parseDouble(row.get(mivCol1))) - .sum(); + .mapToDouble(row -> Double.parseDouble(row.get(mivCol1))) + .sum(); double sumMiv2 = hourlyTrafficVolumes.stream() - .mapToDouble(row -> Double.parseDouble(row.get(mivCol2))) - .sum(); + .mapToDouble(row -> Double.parseDouble(row.get(mivCol2))) + .sum(); double meanMiv1 = sumMiv1 / divisor; double meanMiv2 = sumMiv2 / divisor; @@ -273,12 +265,12 @@ private void readHourlyTrafficVolume(Path pathToDisaggregatedData, Map Double.parseDouble(row.get(freightCol1))) - .sum(); + .mapToDouble(row -> Double.parseDouble(row.get(freightCol1))) + .sum(); double sumFreight2 = hourlyTrafficVolumes.stream() - .mapToDouble(row -> Double.parseDouble(row.get(freightCol2))) - .sum(); + .mapToDouble(row -> Double.parseDouble(row.get(freightCol2))) + .sum(); double meanFreight1 = sumFreight1 / divisor; double meanFreight2 = sumFreight2 / divisor; @@ -382,12 +374,12 @@ private Map readBAStCountStations(Path pathToAggregate try (BufferedReader reader = Files.newBufferedReader(pathToAggregatedData, StandardCharsets.ISO_8859_1)) { CSVParser records = CSVFormat - .Builder.create() - .setAllowMissingColumnNames(true) - .setDelimiter(';') - .setHeader() - .build() - .parse(reader); + .Builder.create() + .setAllowMissingColumnNames(true) + .setDelimiter(';') + .setHeader() + .build() + .parse(reader); for (CSVRecord row : records) { @@ -417,7 +409,7 @@ private Map readBAStCountStations(Path pathToAggregate Set ignored = counts.getIgnored(); final Predicate optFilter = station -> !ignored.contains(station.getId().replaceAll("_1", "") - .replaceAll("_2", "")); + .replaceAll("_2", "")); final Predicate shpFilter; if (shp.getShapeFile() != null) { @@ -430,9 +422,9 @@ private Map readBAStCountStations(Path pathToAggregate // Return filtered map with id as key and station as value return stations.stream() - .filter(optFilter.and(shpFilter)) - .collect(Collectors.toMap( - BAStCountStation::getId, Function.identity() - )); + .filter(optFilter.and(shpFilter)) + .collect(Collectors.toMap( + BAStCountStation::getId, Function.identity() + )); } } diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/freight/optimization/DetermineAverageTruckLoad.java b/contribs/application/src/main/java/org/matsim/application/prepare/freight/optimization/DetermineAverageTruckLoad.java index 6dd30f93606..8318bef7292 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/freight/optimization/DetermineAverageTruckLoad.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/freight/optimization/DetermineAverageTruckLoad.java @@ -6,8 +6,6 @@ import org.apache.commons.csv.CSVRecord; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.checkerframework.checker.units.qual.C; -import org.locationtech.jts.geom.Geometry; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Identifiable; @@ -16,7 +14,6 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.CrsOptions; -import org.matsim.application.options.ShpOptions; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.network.NetworkUtils; @@ -28,7 +25,6 @@ import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; import org.matsim.core.utils.geometry.CoordUtils; import org.matsim.core.utils.geometry.CoordinateTransformation; -import org.matsim.core.utils.geometry.geotools.MGC; import org.matsim.core.utils.geometry.transformations.TransformationFactory; import org.matsim.core.utils.gis.ShapeFileReader; import org.opengis.feature.simple.SimpleFeature; @@ -37,7 +33,6 @@ import java.io.FileWriter; import java.io.IOException; import java.net.URI; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -342,7 +337,7 @@ private boolean checkIfTripIsRelevant(String mode, String from, String to, Strin private LeastCostPathCalculator createRouter(Network network) { Config config = ConfigUtils.createConfig(); - config.plansCalcRoute().setRoutingRandomness(0); + config.routing().setRoutingRandomness(0); TravelTime travelTime = new FreeSpeedTravelTime(); TravelDisutility travelDisutility = new RandomizingTimeDistanceTravelDisutilityFactory (TransportMode.car, config).createTravelDisutility(travelTime); diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/freight/tripExtraction/ExtractRelevantFreightTrips.java b/contribs/application/src/main/java/org/matsim/application/prepare/freight/tripExtraction/ExtractRelevantFreightTrips.java index 870cd1be48f..196e114634c 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/freight/tripExtraction/ExtractRelevantFreightTrips.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/freight/tripExtraction/ExtractRelevantFreightTrips.java @@ -82,7 +82,7 @@ public Integer call() throws Exception { config.network().setInputFile(networkPath.toString()); Scenario outputScenario = ScenarioUtils.loadScenario(config); config.plans().setInputFile(freightDataDirectory.toString()); - config.plansCalcRoute().setRoutingRandomness(0); + config.routing().setRoutingRandomness(0); Scenario scenario = ScenarioUtils.loadScenario(config); Network network = scenario.getNetwork(); Population originalPlans = scenario.getPopulation(); diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateGeoJsonNetwork.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateGeoJsonNetwork.java index dc770d9c607..5d4a67851ff 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateGeoJsonNetwork.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateGeoJsonNetwork.java @@ -45,7 +45,7 @@ public class CreateGeoJsonNetwork implements MATSimAppCommand { @CommandLine.Option(names = "--match-id", description = "Pattern to filter links by id") private String matchId; - @CommandLine.Option(names = "--mode-filter", split = ",", defaultValue = "car", + @CommandLine.Option(names = "--mode-filter", split = ",", defaultValue = "car,freight,drt", description = "Only keep links if they have one of the specified modes. Specify 'none' to disable.") private Set modes; diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateNetworkFromSumo.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateNetworkFromSumo.java index 23672056f9d..b4a3521e48d 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateNetworkFromSumo.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateNetworkFromSumo.java @@ -74,7 +74,7 @@ public static void main(String[] args) { @Override public Integer call() throws Exception { - SumoNetworkConverter converter = SumoNetworkConverter.newInstance(input, output, shp.getShapeFile(), crs.getInputCRS(), crs.getTargetCRS(), freeSpeedFactor); + SumoNetworkConverter converter = SumoNetworkConverter.newInstance(input, output, Path.of(shp.getShapeFile()), crs.getInputCRS(), crs.getTargetCRS(), freeSpeedFactor); Network network = NetworkUtils.createNetwork(); Lanes lanes = LanesUtils.createLanesContainer(); diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSV.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSV.java index 591a895aa84..b8dc592921e 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSV.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSV.java @@ -27,10 +27,8 @@ 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.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.*; -import org.matsim.contrib.freight.carrier.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; @@ -236,7 +234,7 @@ public void setFixedNumberOfVehiclePerTypeAndLocation(int fixedNumberOfVehiclePe * Reads and create the carriers with reading the information from the csv file. * * @param scenario - * @param freightConfigGroup + * @param freightCarriersConfigGroup * @param csvLocationCarrier * @param polygonsInShape * @param defaultJspritIterations @@ -244,14 +242,14 @@ public void setFixedNumberOfVehiclePerTypeAndLocation(int fixedNumberOfVehiclePe * @param shapeCategory * @throws IOException */ - public static void readAndCreateCarrierFromCSV(Scenario scenario, FreightConfigGroup freightConfigGroup, + public static void readAndCreateCarrierFromCSV(Scenario scenario, FreightCarriersConfigGroup freightCarriersConfigGroup, Path csvLocationCarrier, Collection polygonsInShape, int defaultJspritIterations, CoordinateTransformation crsTransformationNetworkAndShape, String shapeCategory) throws IOException { Set allNewCarrierInformation = readCarrierInformation(csvLocationCarrier); - checkNewCarrier(allNewCarrierInformation, freightConfigGroup, scenario, polygonsInShape, shapeCategory); + checkNewCarrier(allNewCarrierInformation, freightCarriersConfigGroup, scenario, polygonsInShape, shapeCategory); log.info("The read carrier information from the csv are checked without errors."); - createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightConfigGroup, polygonsInShape, + createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, polygonsInShape, defaultJspritIterations, crsTransformationNetworkAndShape); } @@ -307,23 +305,23 @@ else if (!record.get("fleetSize").isBlank()) * Checks if the read carrier information are consistent. * * @param allNewCarrierInformation - * @param freightConfigGroup + * @param freightCarriersConfigGroup * @param scenario * @param polygonsInShape * @param shapeCategory */ static void checkNewCarrier(Set allNewCarrierInformation, - FreightConfigGroup freightConfigGroup, Scenario scenario, Collection polygonsInShape, String shapeCategory) { + FreightCarriersConfigGroup freightCarriersConfigGroup, Scenario scenario, Collection polygonsInShape, String shapeCategory) { - FreightUtils.addOrGetCarriers(scenario); + CarriersUtils.addOrGetCarriers(scenario); for (CarrierInformationElement carrierElement : allNewCarrierInformation) { - if (FreightUtils.getCarriers(scenario).getCarriers() + if (CarriersUtils.getCarriers(scenario).getCarriers() .containsKey(Id.create(carrierElement.getName(), Carrier.class))) throw new RuntimeException("The Carrier " + carrierElement.getName() + " being loaded from the csv is already in the given Carrier file. It is not possible to add to an existing Carrier. Please check!"); CarrierVehicleTypes carrierVehicleTypes = new CarrierVehicleTypes(); new CarrierVehicleTypeReader(carrierVehicleTypes) - .readFile(freightConfigGroup.getCarriersVehicleTypesFile()); + .readFile(freightCarriersConfigGroup.getCarriersVehicleTypesFile()); if (carrierElement.getVehicleTypes() != null) for (String type : carrierElement.getVehicleTypes()) { if (!carrierVehicleTypes.getVehicleTypes().containsKey(Id.create(type, VehicleType.class))) @@ -410,20 +408,20 @@ static void checkNewCarrier(Set allNewCarrierInformat * * @param scenario * @param allNewCarrierInformation - * @param freightConfigGroup + * @param freightCarriersConfigGroup * @param polygonsInShape * @param defaultJspritIterations * @param crsTransformationNetworkAndShape */ static void createNewCarrierAndAddVehicleTypes(Scenario scenario, - Set allNewCarrierInformation, FreightConfigGroup freightConfigGroup, + Set allNewCarrierInformation, FreightCarriersConfigGroup freightCarriersConfigGroup, Collection polygonsInShape, int defaultJspritIterations, CoordinateTransformation crsTransformationNetworkAndShape) { - Carriers carriers = FreightUtils.addOrGetCarriers(scenario); + Carriers carriers = CarriersUtils.addOrGetCarriers(scenario); CarrierVehicleTypes carrierVehicleTypes = new CarrierVehicleTypes(); - CarrierVehicleTypes usedCarrierVehicleTypes = FreightUtils.getCarrierVehicleTypes(scenario); - new CarrierVehicleTypeReader(carrierVehicleTypes).readFile(freightConfigGroup.getCarriersVehicleTypesFile()); + CarrierVehicleTypes usedCarrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); + new CarrierVehicleTypeReader(carrierVehicleTypes).readFile(freightCarriersConfigGroup.getCarriersVehicleTypesFile()); for (CarrierInformationElement singleNewCarrier : allNewCarrierInformation) { if (singleNewCarrier.getVehicleTypes() == null) { @@ -437,11 +435,11 @@ static void createNewCarrierAndAddVehicleTypes(Scenario scenario, if (carrierCapabilities.getFleetSize() == null && singleNewCarrier.getFleetSize() != null) carrierCapabilities.setFleetSize(singleNewCarrier.getFleetSize()); if (singleNewCarrier.getJspritIterations() > 0) - CarrierUtils.setJspritIterations(thisCarrier, singleNewCarrier.getJspritIterations()); + CarriersUtils.setJspritIterations(thisCarrier, singleNewCarrier.getJspritIterations()); } else { - thisCarrier = CarrierUtils.createCarrier(Id.create(singleNewCarrier.getName(), Carrier.class)); + thisCarrier = CarriersUtils.createCarrier(Id.create(singleNewCarrier.getName(), Carrier.class)); if (singleNewCarrier.getJspritIterations() > 0) - CarrierUtils.setJspritIterations(thisCarrier, singleNewCarrier.getJspritIterations()); + CarriersUtils.setJspritIterations(thisCarrier, singleNewCarrier.getJspritIterations()); carrierCapabilities = CarrierCapabilities.Builder.newInstance() .setFleetSize(singleNewCarrier.getFleetSize()).build(); carriers.addCarrier(thisCarrier); @@ -497,8 +495,8 @@ static void createNewCarrierAndAddVehicleTypes(Scenario scenario, thisCarrier.setCarrierCapabilities(carrierCapabilities); } for (Carrier carrier : carriers.getCarriers().values()) { - if (CarrierUtils.getJspritIterations(carrier) == Integer.MIN_VALUE) { - CarrierUtils.setJspritIterations(carrier, defaultJspritIterations); + if (CarriersUtils.getJspritIterations(carrier) == Integer.MIN_VALUE) { + CarriersUtils.setJspritIterations(carrier, defaultJspritIterations); log.warn("The jspritIterations are now set to the default value of " + defaultJspritIterations + " in this simulation!"); } 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 fa3357d473c..8c1f113a6d0 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java @@ -31,8 +31,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; -import org.matsim.contrib.freight.carrier.*; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.*; import org.matsim.core.network.NetworkUtils; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.geometry.geotools.MGC; @@ -648,7 +647,7 @@ else if (samplingOption.equals("changeDemandOnLocation")) { .setCapacityDemand(demandForThisLink).setServiceDuration(serviceTime) .setServiceStartTimeWindow(newDemandInformationElement.getFirstJobElementTimeWindow()) .build(); - FreightUtils.getCarriers(scenario).getCarriers() + CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices() .put(thisService.getId(), thisService); } @@ -688,7 +687,7 @@ else if (samplingOption.equals("changeDemandOnLocation")) { .setCapacityDemand(demandForThisLink).setServiceDuration(serviceTime) .setServiceStartTimeWindow(newDemandInformationElement.getFirstJobElementTimeWindow()) .build(); - FreightUtils.getCarriers(scenario).getCarriers().values().iterator().next().getServices() + CarriersUtils.getCarriers(scenario).getCarriers().values().iterator().next().getServices() .put(thisService.getId(), thisService); } distributedDemand = distributedDemand + demandForThisLink; @@ -740,7 +739,7 @@ else if (samplingOption.equals("changeDemandOnLocation")) { .setCapacityDemand(demandForThisLink).setServiceDuration(serviceTime) .setServiceStartTimeWindow(newDemandInformationElement.getFirstJobElementTimeWindow()) .build(); - FreightUtils.getCarriers(scenario).getCarriers() + CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices() .put(thisService.getId(), thisService); } @@ -919,7 +918,7 @@ else if (population == null) .setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup) .setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery) .build(); - FreightUtils.getCarriers(scenario).getCarriers() + CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments() .put(thisShipment.getId(), thisShipment); } @@ -1021,7 +1020,7 @@ else if (numberOfPickupLocations != null) { .setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup) .setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery) .build(); - FreightUtils.getCarriers(scenario).getCarriers() + CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)) .getShipments().put(thisShipment.getId(), thisShipment); } @@ -1078,7 +1077,7 @@ else if (numberOfPickupLocations != null) { .newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), demandForThisLink) .setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup) .setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery).build(); - FreightUtils.getCarriers(scenario).getCarriers() + CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments() .put(thisShipment.getId(), thisShipment); distributedDemand = distributedDemand + demandForThisLink; @@ -1103,10 +1102,10 @@ private static String createJobId(Scenario scenario, DemandInformationElement ne String newJobId; if (linkDelivery != null) { newJobId = "Shipment_" + linkPickup + "_" + linkDelivery; - if (FreightUtils.getCarriers(scenario).getCarriers() + if (CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments() .containsKey(Id.create(newJobId, CarrierShipment.class))) { - for (int x = 1; FreightUtils.getCarriers(scenario).getCarriers() + for (int x = 1; CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments() .containsKey(Id.create(newJobId, CarrierShipment.class)); x++) { newJobId = "Shipment_" + linkPickup + "_" + linkDelivery + "_" + x; @@ -1114,10 +1113,10 @@ private static String createJobId(Scenario scenario, DemandInformationElement ne } } else { newJobId = "Service_" + linkPickup; - if (FreightUtils.getCarriers(scenario).getCarriers() + if (CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices() .containsKey(Id.create(newJobId, CarrierShipment.class))) { - for (int x = 1; FreightUtils.getCarriers(scenario).getCarriers() + for (int x = 1; CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices() .containsKey(Id.create(newJobId, CarrierShipment.class)); x++) { newJobId = "Service_" + linkPickup + "_" + x; @@ -1143,7 +1142,7 @@ private static void reduceNumberOfJobsIfSameCharacteristics(Scenario scenario, if (newDemandInformationElement.getTypeOfDemand().equals("shipment")) { HashMap, CarrierShipment> shipmentsToRemove = new HashMap, CarrierShipment>(); ArrayList shipmentsToAdd = new ArrayList(); - Carrier thisCarrier = FreightUtils.getCarriers(scenario).getCarriers() + Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)); for (Id baseShipmentId : thisCarrier.getShipments().keySet()) { if (!shipmentsToRemove.containsKey(baseShipmentId)) { @@ -1194,7 +1193,7 @@ private static void reduceNumberOfJobsIfSameCharacteristics(Scenario scenario, if (newDemandInformationElement.getTypeOfDemand().equals("service")) { HashMap, CarrierService> servicesToRemove = new HashMap, CarrierService>(); ArrayList servicesToAdd = new ArrayList(); - Carrier thisCarrier = FreightUtils.getCarriers(scenario).getCarriers() + Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)); for (Id baseServiceId : thisCarrier.getServices().keySet()) { if (!servicesToRemove.containsKey(baseServiceId)) { diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java index 8eabf5ddb01..caec3bbf367 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java @@ -26,17 +26,17 @@ import org.matsim.api.core.v01.population.Population; import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierPlanWriter; -import org.matsim.contrib.freight.carrier.Carriers; -import org.matsim.contrib.freight.controler.CarrierModule; -import org.matsim.contrib.freight.controler.CarrierScoringFunctionFactory; -import org.matsim.contrib.freight.controler.FreightUtils; -import org.matsim.contrib.freight.usecases.chessboard.CarrierScoringFunctionFactoryImpl; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierPlanWriter; +import org.matsim.freight.carriers.CarriersUtils; +import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.controler.CarrierModule; +import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory; +import org.matsim.freight.carriers.usecases.chessboard.CarrierScoringFunctionFactoryImpl; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; @@ -196,7 +196,7 @@ public Integer call() throws IOException, InvalidAttributeValueException, Execut Collection polygonsInShape = null; shp = new ShpOptions(shapeFilePath, shapeCRS, null); - if (shp.getShapeFile() != null && Files.exists(shp.getShapeFile())) { + if (shp.isDefined()) { log.warn("Use of shpFile. Locations for the carriers and the demand only in shp: " + shp.getShapeFile()); polygonsInShape = shp.readFeatures(); crsTransformationFromNetworkToShape = shp.createTransformation(networkCRS); @@ -232,17 +232,17 @@ public Integer call() throws IOException, InvalidAttributeValueException, Execut private Config prepareConfig(int lastMATSimIteration, String coordinateSystem) { Config config = ConfigUtils.createConfig(); // ScenarioUtils.loadScenario(config); - config.controler().setOutputDirectory(outputLocation.toString()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - new OutputDirectoryHierarchy(config.controler().getOutputDirectory(), config.controler().getRunId(), - config.controler().getOverwriteFileSetting(), ControlerConfigGroup.CompressionType.gzip); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.overwriteExistingFiles); - config.controler().setLastIteration(lastMATSimIteration); + config.controller().setOutputDirectory(outputLocation.toString()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + new OutputDirectoryHierarchy(config.controller().getOutputDirectory(), config.controller().getRunId(), + config.controller().getOverwriteFileSetting(), ControllerConfigGroup.CompressionType.gzip); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.overwriteExistingFiles); + config.controller().setLastIteration(lastMATSimIteration); config.global().setRandomSeed(4177); config.global().setCoordinateSystem(coordinateSystem); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setTravelTimeSliceWidth(1800); - freightConfigGroup.setTimeWindowHandling(FreightConfigGroup.TimeWindowHandling.enforceBeginnings); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setTravelTimeSliceWidth(1800); + freightCarriersConfigGroup.setTimeWindowHandling(FreightCarriersConfigGroup.TimeWindowHandling.enforceBeginnings); return config; } @@ -281,11 +281,11 @@ private static void setNetworkAndNetworkChangeEvents(Config config, String netwo */ private static void prepareVehicles(Config config, String vehicleTypesFileLocation) { - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); if (Objects.equals(vehicleTypesFileLocation, "")) throw new RuntimeException("No path to the vehicleTypes selected"); else { - freightConfigGroup.setCarriersVehicleTypesFile(vehicleTypesFileLocation); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(vehicleTypesFileLocation); log.info("Get vehicleTypes from: " + vehicleTypesFileLocation); } } @@ -306,8 +306,8 @@ private void createCarrier(Scenario scenario, CarrierInputOptions selectedCarrie String carriersFileLocation, Path csvLocationCarrier, Collection polygonsInShape, int defaultJspritIterations, CoordinateTransformation crsTransformationNetworkAndShape) throws IOException { - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), - FreightConfigGroup.class); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); switch (selectedCarrierInputOption) { case addCSVDataToExistingCarrierFileData -> { // reads an existing carrier file and adds the information based on the read csv @@ -315,10 +315,10 @@ private void createCarrier(Scenario scenario, CarrierInputOptions selectedCarrie if (Objects.equals(carriersFileLocation, "")) throw new RuntimeException("No path to the carrier file selected"); else { - freightConfigGroup.setCarriersFile(carriersFileLocation); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + freightCarriersConfigGroup.setCarriersFile(carriersFileLocation); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); log.info("Load carriers from: " + carriersFileLocation); - CarrierReaderFromCSV.readAndCreateCarrierFromCSV(scenario, freightConfigGroup, csvLocationCarrier, + CarrierReaderFromCSV.readAndCreateCarrierFromCSV(scenario, freightCarriersConfigGroup, csvLocationCarrier, polygonsInShape, defaultJspritIterations, crsTransformationNetworkAndShape, shapeCategory); } } @@ -327,14 +327,14 @@ private void createCarrier(Scenario scenario, CarrierInputOptions selectedCarrie if (Objects.equals(carriersFileLocation, "")) throw new RuntimeException("No path to the carrier file selected"); else { - freightConfigGroup.setCarriersFile(carriersFileLocation); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + freightCarriersConfigGroup.setCarriersFile(carriersFileLocation); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); log.info("Load carriers from: " + carriersFileLocation); } } case createCarriersFromCSV -> // creates all carriers based on the given information in the read carrier csv - CarrierReaderFromCSV.readAndCreateCarrierFromCSV(scenario, freightConfigGroup, csvLocationCarrier, + CarrierReaderFromCSV.readAndCreateCarrierFromCSV(scenario, freightCarriersConfigGroup, csvLocationCarrier, polygonsInShape, defaultJspritIterations, crsTransformationNetworkAndShape, shapeCategory); default -> throw new RuntimeException("no method to create or read carrier selected."); } @@ -415,7 +415,7 @@ private void createDemand(DemandGenerationOptions selectedDemandGenerationOption case useDemandFromCarrierFile -> { // use only the given demand of the read carrier file boolean oneCarrierHasJobs = false; - for (Carrier carrier : FreightUtils.getCarriers(scenario).getCarriers().values()) + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) if (carrier.getServices().isEmpty() && carrier.getShipments().isEmpty()) log.warn(carrier.getId().toString() + " has no jobs which can be used"); else { @@ -462,29 +462,29 @@ private static void solveSelectedSolution(OptionsOfVRPSolutions selectedSolution case runJspritAndMATSim -> { // solves the VRP with jsprit and runs MATSim afterwards new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersNoPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersNoPlans.xml"); runJsprit(controler, false); controler.run(); new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersWithPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersWithPlans.xml"); } case runJspritAndMATSimWithDistanceConstraint -> { // solves the VRP with jsprit by using the distance constraint and runs MATSim // afterwards new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersNoPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersNoPlans.xml"); runJsprit(controler, true); controler.run(); new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersWithPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersWithPlans.xml"); } case runJsprit -> { // solves only the VRP with jsprit new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersNoPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersNoPlans.xml"); runJsprit(controler, false); new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersWithPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersWithPlans.xml"); log.warn( "##Finished with the jsprit solution. If you also want to run MATSim, please change case of optionsOfVRPSolutions"); System.exit(0); @@ -492,10 +492,10 @@ private static void solveSelectedSolution(OptionsOfVRPSolutions selectedSolution case runJspritWithDistanceConstraint -> { // solves only the VRP with jsprit by using the distance constraint new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersNoPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersNoPlans.xml"); runJsprit(controler, true); new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersWithPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersWithPlans.xml"); log.warn( "##Finished with the jsprit solution. If you also want to run MATSim, please change case of optionsOfVRPSolutions"); System.exit(0); @@ -504,7 +504,7 @@ private static void solveSelectedSolution(OptionsOfVRPSolutions selectedSolution // creates no solution of the VRP and only writes the carrier file with the // generated carriers and demands new CarrierPlanWriter((Carriers) controler.getScenario().getScenarioElement("carriers")) - .write(config.controler().getOutputDirectory() + "/output_carriersNoPlans.xml"); + .write(config.controller().getOutputDirectory() + "/output_carriersNoPlans.xml"); log.warn( "##Finished without solution of the VRP. If you also want to run jsprit and/or MATSim, please change case of optionsOfVRPSolutions"); System.exit(0); @@ -524,11 +524,11 @@ private static void solveSelectedSolution(OptionsOfVRPSolutions selectedSolution */ private static void runJsprit(Controler controler, boolean usingRangeRestriction) throws ExecutionException, InterruptedException { - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(controler.getConfig(), - FreightConfigGroup.class); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(controler.getConfig(), + FreightCarriersConfigGroup.class); if (usingRangeRestriction) - freightConfigGroup.setUseDistanceConstraintForTourPlanning( - FreightConfigGroup.UseDistanceConstraintForTourPlanning.basedOnEnergyConsumption); - FreightUtils.runJsprit(controler.getScenario()); + freightCarriersConfigGroup.setUseDistanceConstraintForTourPlanning( + FreightCarriersConfigGroup.UseDistanceConstraintForTourPlanning.basedOnEnergyConsumption); + CarriersUtils.runJsprit(controler.getScenario()); } } diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java index 6c4a09703c4..b2d70951be8 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java @@ -29,10 +29,10 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.*; import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierService; -import org.matsim.contrib.freight.carrier.CarrierShipment; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierService; +import org.matsim.freight.carriers.CarrierShipment; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.controler.Controler; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.geometry.geotools.MGC; @@ -99,11 +99,11 @@ static void preparePopulation(Population population, double sampleSizeInputPopul static void createDemandLocationsFile(Controler controler) { Network network = controler.getScenario().getNetwork(); - File file = new File(controler.getConfig().controler().getOutputDirectory() + "/outputFacilitiesFile.tsv"); + File file = new File(controler.getConfig().controller().getOutputDirectory() + "/outputFacilitiesFile.tsv"); try (FileWriter writer = new FileWriter(file, true)) { writer.write("id x y type ServiceLocation pickupLocation deliveryLocation\n"); - for (Carrier thisCarrier : FreightUtils.getCarriers(controler.getScenario()).getCarriers().values()) { + for (Carrier thisCarrier : CarriersUtils.getCarriers(controler.getScenario()).getCarriers().values()) { for (CarrierService thisService : thisCarrier.getServices().values()) { Coord coord = FreightDemandGenerationUtils .getCoordOfMiddlePointOfLink(network.getLinks().get(thisService.getLocationLinkId())); diff --git a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java index 0c72be12c3b..46ec4a745b6 100644 --- a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java +++ b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java @@ -38,14 +38,17 @@ import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.ShpOptions; import org.matsim.application.options.ShpOptions.Index; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.*; -import org.matsim.contrib.freight.carrier.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freight.controler.*; -import org.matsim.contrib.freight.usecases.chessboard.CarrierTravelDisutilities; +import org.matsim.core.config.consistency.UnmaterializedConfigGroupChecker; +import org.matsim.core.scenario.ProjectionUtils; +import org.matsim.core.utils.geometry.CoordUtils; +import org.matsim.core.utils.geometry.CoordinateTransformation; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.controler.*; +import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; +import org.matsim.freight.carriers.usecases.chessboard.CarrierTravelDisutilities; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.config.groups.VspExperimentalConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; @@ -79,6 +82,8 @@ import java.util.*; import java.util.stream.Collectors; +import static org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles; + /** * Tool to generate small scale commercial traffic for a selected area. The needed input data are: employee information for the area and three shapes files (zones, buildings, landuse). These data should be available with OSM. * @@ -96,8 +101,6 @@ public class GenerateSmallScaleCommercialTrafficDemand implements MATSimAppComma // Option 3: Leerkamp (nur in RVR Modell). private static final Logger log = LogManager.getLogger(GenerateSmallScaleCommercialTrafficDemand.class); - private static final HashMap>> buildingsPerZone = new HashMap<>(); - private static final HashMap> landuseCategoriesAndDataConnection = new HashMap<>(); private enum CreationOption { useExistingCarrierFileWithSolution, createNewCarrierFile, useExistingCarrierFileWithoutSolution @@ -153,10 +156,19 @@ private enum SmallScaleCommercialTrafficType { @CommandLine.Option(names = "--numberOfPlanVariantsPerAgent", description = "If an agent should have variant plans, you should set this parameter.", defaultValue = "1") private int numberOfPlanVariantsPerAgent; + @CommandLine.Option(names = "--network", description = "Overwrite network file in config") + private String network; + @CommandLine.Option(names = "--pathOutput", description = "Path for the output") private Path output; private Random rnd; + private final Map>> buildingsPerZone = new HashMap<>(); + private final Map> landuseCategoriesAndDataConnection = new HashMap<>(); + + private Index indexZones; + private Index indexBuildings; + private Index indexLanduse; public static void main(String[] args) { System.exit(new CommandLine(new GenerateSmallScaleCommercialTrafficDemand()).execute(args)); @@ -172,34 +184,34 @@ public Integer call() throws Exception { Config config = readAndCheckConfig(configPath, modelName, sampleName, output); - output = Path.of(config.controler().getOutputDirectory()); + output = Path.of(config.controller().getOutputDirectory()); Scenario scenario = ScenarioUtils.loadScenario(config); NetworkUtils.runNetworkCleaner(scenario.getNetwork()); // e.g. for vulkaneifel network - FreightConfigGroup freightConfigGroup; + FreightCarriersConfigGroup freightCarriersConfigGroup; switch (usedCreationOption) { case useExistingCarrierFileWithSolution -> { log.info("Existing carriers (including carrier vehicle types ) should be set in the freight config group"); if (includeExistingModels) throw new Exception( "You set that existing models should included to the new model. This is only possible for a creation of the new carrier file and not by using an existing."); - freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - if (config.vehicles() != null && freightConfigGroup.getCarriersVehicleTypesFile() == null) - freightConfigGroup.setCarriersVehicleTypesFile(config.vehicles().getVehiclesFile()); - log.info("Load carriers from: " + freightConfigGroup.getCarriersFile()); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + if (config.vehicles() != null && freightCarriersConfigGroup.getCarriersVehicleTypesFile() == null) + freightCarriersConfigGroup.setCarriersVehicleTypesFile(config.vehicles().getVehiclesFile()); + log.info("Load carriers from: " + freightCarriersConfigGroup.getCarriersFile()); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); } case useExistingCarrierFileWithoutSolution -> { log.info("Existing carriers (including carrier vehicle types ) should be set in the freight config group"); if (includeExistingModels) throw new Exception( "You set that existing models should included to the new model. This is only possible for a creation of the new carrier file and not by using an existing."); - freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - if (config.vehicles() != null && freightConfigGroup.getCarriersVehicleTypesFile() == null) - freightConfigGroup.setCarriersVehicleTypesFile(config.vehicles().getVehiclesFile()); - log.info("Load carriers from: " + freightConfigGroup.getCarriersFile()); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + if (config.vehicles() != null && freightCarriersConfigGroup.getCarriersVehicleTypesFile() == null) + freightCarriersConfigGroup.setCarriersVehicleTypesFile(config.vehicles().getVehiclesFile()); + log.info("Load carriers from: " + freightCarriersConfigGroup.getCarriersFile()); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); solveSeparatedVRPs(scenario, null); } default -> { @@ -214,13 +226,19 @@ public Integer call() throws Exception { throw new Exception("Required districts shape file {} not found" + shapeFileZonePath.toString()); } Path inputDataDirectory = Path.of(config.getContext().toURI()).getParent(); - HashMap> resultingDataPerZone = LanduseBuildingAnalysis - .createInputDataDistribution(output, landuseCategoriesAndDataConnection, inputDataDirectory, - usedLanduseConfiguration.toString(), shapeFileLandusePath, shapeFileZonePath, - shapeFileBuildingsPath, shapeCRS, buildingsPerZone); + ShpOptions shpZones = new ShpOptions(shapeFileZonePath, shapeCRS, StandardCharsets.UTF_8); - Map, Link>> regionLinksMap = filterLinksForZones(scenario, shpZones, - SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS), buildingsPerZone); + + indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS); + indexBuildings = SmallScaleCommercialTrafficUtils.getIndexBuildings(shapeFileBuildingsPath, shapeCRS); + indexLanduse = SmallScaleCommercialTrafficUtils.getIndexLanduse(shapeFileLandusePath, shapeCRS); + + Map> resultingDataPerZone = LanduseBuildingAnalysis + .createInputDataDistribution(output, landuseCategoriesAndDataConnection, inputDataDirectory, + usedLanduseConfiguration.toString(), indexLanduse, indexZones, + indexBuildings, buildingsPerZone); + + Map, Link>> regionLinksMap = filterLinksForZones(scenario, indexZones, buildingsPerZone); switch (usedSmallScaleCommercialTrafficType) { case commercialPersonTraffic, goodsTraffic -> @@ -236,27 +254,37 @@ public Integer call() throws Exception { } default -> throw new RuntimeException("No traffic type selected."); } - if (config.controler().getRunId() == null) - new CarrierPlanWriter(FreightUtils.addOrGetCarriers(scenario)) - .write(scenario.getConfig().controler().getOutputDirectory() + "/output_CarrierDemand.xml"); + if (config.controller().getRunId() == null) + new CarrierPlanWriter(CarriersUtils.addOrGetCarriers(scenario)) + .write(scenario.getConfig().controller().getOutputDirectory() + "/output_CarrierDemand.xml"); else - new CarrierPlanWriter(FreightUtils.addOrGetCarriers(scenario)) - .write(scenario.getConfig().controler().getOutputDirectory() + "/" - + scenario.getConfig().controler().getRunId() + ".output_CarrierDemand.xml"); + new CarrierPlanWriter(CarriersUtils.addOrGetCarriers(scenario)) + .write(scenario.getConfig().controller().getOutputDirectory() + "/" + + scenario.getConfig().controller().getRunId() + ".output_CarrierDemand.xml"); solveSeparatedVRPs(scenario, regionLinksMap); } } - if (config.controler().getRunId() == null) - new CarrierPlanWriter(FreightUtils.addOrGetCarriers(scenario)).write( - scenario.getConfig().controler().getOutputDirectory() + "/output_CarrierDemandWithPlans.xml"); + if (config.controller().getRunId() == null) + new CarrierPlanWriter(CarriersUtils.addOrGetCarriers(scenario)).write( + scenario.getConfig().controller().getOutputDirectory() + "/output_CarrierDemandWithPlans.xml"); else - new CarrierPlanWriter(FreightUtils.addOrGetCarriers(scenario)) + new CarrierPlanWriter(CarriersUtils.addOrGetCarriers(scenario)) .write( - scenario.getConfig().controler().getOutputDirectory() + "/" + scenario.getConfig().controler().getRunId() + ".output_CarrierDemandWithPlans.xml"); + scenario.getConfig().controller().getOutputDirectory() + "/" + scenario.getConfig().controller().getRunId() + ".output_CarrierDemandWithPlans.xml"); + Controler controler = prepareControler(scenario); + + // Creating inject always adds check for unmaterialized config groups. + controler.getInjector(); + + // Removes check after injector has been created + controler.getConfig().removeConfigConsistencyChecker(UnmaterializedConfigGroupChecker.class); + controler.run(); + SmallScaleCommercialTrafficUtils.createPlansBasedOnCarrierPlans(controler.getScenario(), usedSmallScaleCommercialTrafficType.toString(), output, modelName, sampleName, nameOutputPopulation, numberOfPlanVariantsPerAgent); + return 0; } @@ -264,17 +292,17 @@ public Integer call() throws Exception { * @param originalScenario complete Scenario * @param regionLinksMap list with Links for each region */ - private void solveSeparatedVRPs(Scenario originalScenario, Map, Link>> regionLinksMap) throws Exception { + private void solveSeparatedVRPs(Scenario originalScenario, Map, Link>> regionLinksMap) throws Exception { boolean splitCarrier = true; boolean splitVRPs = false; int maxServicesPerCarrier = 100; Map, Carrier> allCarriers = new HashMap<>( - FreightUtils.getCarriers(originalScenario).getCarriers()); + CarriersUtils.getCarriers(originalScenario).getCarriers()); Map, Carrier> solvedCarriers = new HashMap<>(); List> keyList = new ArrayList<>(allCarriers.keySet()); - FreightUtils.getCarriers(originalScenario).getCarriers().values().forEach(carrier -> { - if (CarrierUtils.getJspritIterations(carrier) == 0) { + CarriersUtils.getCarriers(originalScenario).getCarriers().values().forEach(carrier -> { + if (CarriersUtils.getJspritIterations(carrier) == 0) { allCarriers.remove(carrier.getId()); solvedCarriers.put(carrier.getId(), carrier); } @@ -320,7 +348,7 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map newCarrier.getAttributes() .putAttribute(attribute, carrier.getAttributes().getAttribute(attribute))); @@ -369,18 +397,18 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map { + CarriersUtils.getCarriers(originalScenario).getCarriers().putAll(solvedCarriers); + CarriersUtils.getCarriers(originalScenario).getCarriers().values().forEach(carrier -> { if (regionLinksMap != null && !carrier.getAttributes().getAsMap().containsKey("tourStartArea")) { List startAreas = new ArrayList<>(); for (ScheduledTour tour : carrier.getSelectedPlan().getScheduledTours()) { @@ -396,8 +424,8 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map> resultingDataPerZone, - Map, Link>> regionLinksMap, String smallScaleCommercialTrafficType, + Map> resultingDataPerZone, + Map, Link>> regionLinksMap, String smallScaleCommercialTrafficType, boolean includeExistingModels) throws Exception { ArrayList modesORvehTypes; @@ -411,9 +439,9 @@ else if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) TrafficVolumeGeneration.setInputParameters(smallScaleCommercialTrafficType); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, smallScaleCommercialTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, smallScaleCommercialTrafficType); if (includeExistingModels) { @@ -427,29 +455,49 @@ else if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) } /** - * Reads and checks config if all necessary parameter are set. + * Reads and checks config if all necessary parameters are set. */ private Config readAndCheckConfig(Path configPath, String modelName, String sampleName, Path output) throws Exception { Config config = ConfigUtils.loadConfig(configPath.toString()); if (output == null || output.toString().isEmpty()) - config.controler().setOutputDirectory(Path.of(config.controler().getOutputDirectory()).resolve(modelName) + config.controller().setOutputDirectory(Path.of(config.controller().getOutputDirectory()).resolve(modelName) .resolve(usedSmallScaleCommercialTrafficType.toString() + "_" + sampleName + "pct" + "_" + java.time.LocalDate.now() + "_" + java.time.LocalTime.now().toSecondOfDay() + "_" + resistanceFactor) .toString()); else - config.controler().setOutputDirectory(output.toString()); - new OutputDirectoryHierarchy(config.controler().getOutputDirectory(), config.controler().getRunId(), - config.controler().getOverwriteFileSetting(), ControlerConfigGroup.CompressionType.gzip); - new File(Path.of(config.controler().getOutputDirectory()).resolve("calculatedData").toString()).mkdir(); + config.controller().setOutputDirectory(output.toString()); + + // Reset some config values that are not needed + config.controller().setFirstIteration(0); + config.controller().setLastIteration(0); + config.plans().setInputFile(null); + config.transit().setTransitScheduleFile(null); + config.transit().setVehiclesFile(null); + config.counts().setInputFile(null); + + // Set flow and storage capacity to a high value + config.qsim().setFlowCapFactor(sample * 4); + config.qsim().setStorageCapFactor(sample * 4); + config.qsim().setUsePersonIdForMissingVehicleId(true); + + // Overwrite network + if (network != null) + config.network().setInputFile(network); + + // Some files are written before the controller is created, deleting the directory is not an option + config.controller().setOverwriteFileSetting(overwriteExistingFiles); + + new OutputDirectoryHierarchy(config.controller().getOutputDirectory(), config.controller().getRunId(), + config.controller().getOverwriteFileSetting(), ControllerConfigGroup.CompressionType.gzip); + new File(Path.of(config.controller().getOutputDirectory()).resolve("calculatedData").toString()).mkdir(); rnd = new Random(config.global().getRandomSeed()); + if (config.network().getInputFile() == null) throw new Exception("No network file in config"); - if (config.network().getInputCRS() == null) - throw new Exception("No network CRS is set in config"); if (config.global().getCoordinateSystem() == null) throw new Exception("No global CRS is set in config"); - if (config.controler().getOutputDirectory() == null) + if (config.controller().getOutputDirectory() == null) throw new Exception("No output directory was set"); return config; @@ -466,11 +514,13 @@ private Controler prepareControler(Scenario scenario) { @Override public void install() { bind(CarrierStrategyManager.class).toProvider( - new MyCarrierPlanStrategyManagerFactory(FreightUtils.getCarrierVehicleTypes(scenario))); + new MyCarrierPlanStrategyManagerFactory(CarriersUtils.getCarrierVehicleTypes(scenario))); bind(CarrierScoringFunctionFactory.class).toInstance(new MyCarrierScoringFunctionFactory()); } }); - controler.getConfig().vspExperimental().setVspDefaultsCheckingLevel(VspExperimentalConfigGroup.VspDefaultsCheckingLevel.abort); + + controler.getConfig().vspExperimental().setVspDefaultsCheckingLevel(VspExperimentalConfigGroup.VspDefaultsCheckingLevel.warn); + return controler; } @@ -479,8 +529,8 @@ public void install() { * TripDistributionMatrix. */ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, - HashMap> resultingDataPerZone, String smallScaleCommercialTrafficType, - Map, Link>> regionLinksMap) { + Map> resultingDataPerZone, String smallScaleCommercialTrafficType, + Map, Link>> regionLinksMap) { int maxNumberOfCarrier = odMatrix.getListOfPurposes().size() * odMatrix.getListOfZones().size() * odMatrix.getListOfModesOrVehTypes().size(); int createdCarrier = 0; @@ -490,10 +540,13 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, Map stopDurationTimeSelector = createStopDurationTimeDistributionPerCategory( smallScaleCommercialTrafficType); - CarrierVehicleTypes carrierVehicleTypes = FreightUtils.getCarrierVehicleTypes(scenario); + CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); Map, VehicleType> additionalCarrierVehicleTypes = scenario.getVehicles().getVehicleTypes(); - additionalCarrierVehicleTypes.values().forEach( - vehicleType -> carrierVehicleTypes.getVehicleTypes().putIfAbsent(vehicleType.getId(), vehicleType)); + + // Only vehicle with cost information will work properly + additionalCarrierVehicleTypes.values().stream() + .filter(vehicleType -> vehicleType.getCostInformation().getCostsPerSecond() != null) + .forEach(vehicleType -> carrierVehicleTypes.getVehicleTypes().putIfAbsent(vehicleType.getId(), vehicleType)); for (VehicleType vehicleType : carrierVehicleTypes.getVehicleTypes().values()) { CostInformation costInformation = vehicleType.getCostInformation(); @@ -583,7 +636,7 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, assert possibleVehicleTypes != null; for (String possibleVehicleType : possibleVehicleTypes) { - if (FreightUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().containsKey( + if (CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().containsKey( Id.create(possibleVehicleType, VehicleType.class))) vehicleTypes.add(possibleVehicleType); } @@ -663,19 +716,19 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, private void createServices(Scenario scenario, ArrayList noPossibleLinks, String selectedStopCategory, String carrierName, int numberOfJobs, String[] serviceArea, Integer serviceTimePerStop, TimeWindow serviceTimeWindow, - Map, Link>> regionLinksMap) { + Map, Link>> regionLinksMap) { String stopZone = serviceArea[0]; for (int i = 0; i < numberOfJobs; i++) { - Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks, regionLinksMap, shapeCRS); + Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks, regionLinksMap); Id idNewService = Id.create(carrierName + "_" + linkId + "_" + rnd.nextInt(10000), CarrierService.class); CarrierService thisService = CarrierService.Builder.newInstance(idNewService, linkId) .setServiceDuration(serviceTimePerStop).setServiceStartTimeWindow(serviceTimeWindow).build(); - FreightUtils.getCarriers(scenario).getCarriers().get(Id.create(carrierName, Carrier.class)).getServices() + CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create(carrierName, Carrier.class)).getServices() .put(thisService.getId(), thisService); } @@ -688,17 +741,17 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo String selectedStartCategory, String carrierName, List vehicleTypes, int numberOfDepots, FleetSize fleetSize, int fixedNumberOfVehiclePerTypeAndLocation, - ArrayList vehicleDepots, Map, Link>> regionLinksMap, + List vehicleDepots, Map, Link>> regionLinksMap, String smallScaleCommercialTrafficType, ValueSelectorUnderGivenProbability tourStartTimeSelector, ValueSelectorUnderGivenProbability tourDurationTimeSelector) { - Carriers carriers = FreightUtils.addOrGetCarriers(scenario); - CarrierVehicleTypes carrierVehicleTypes = FreightUtils.getCarrierVehicleTypes(scenario); + Carriers carriers = CarriersUtils.addOrGetCarriers(scenario); + CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); CarrierCapabilities carrierCapabilities; - Carrier thisCarrier = CarrierUtils.createCarrier(Id.create(carrierName, Carrier.class)); + Carrier thisCarrier = CarriersUtils.createCarrier(Id.create(carrierName, Carrier.class)); if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic") && purpose == 3) thisCarrier.getAttributes().putAttribute("subpopulation", smallScaleCommercialTrafficType + "_service"); else @@ -707,12 +760,12 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo thisCarrier.getAttributes().putAttribute("purpose", purpose); thisCarrier.getAttributes().putAttribute("tourStartArea", startZone); if (jspritIterations > 0) - CarrierUtils.setJspritIterations(thisCarrier, jspritIterations); + CarriersUtils.setJspritIterations(thisCarrier, jspritIterations); carrierCapabilities = CarrierCapabilities.Builder.newInstance().setFleetSize(fleetSize).build(); carriers.addCarrier(thisCarrier); while (vehicleDepots.size() < numberOfDepots) { - Id link = findPossibleLink(startZone, selectedStartCategory, null, regionLinksMap, shapeCRS); + Id link = findPossibleLink(startZone, selectedStartCategory, null, regionLinksMap); vehicleDepots.add(link.toString()); } @@ -800,16 +853,13 @@ else if (smallScaleCommercialTrafficType.equals(SmallScaleCommercialTrafficType. /** * Finds a possible link for a service or the vehicle location. */ - private Id findPossibleLink(String zone, String selectedCategory, ArrayList noPossibleLinks, - Map, Link>> regionLinksMap, String shapeCRS) { - - Index indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS); + private Id findPossibleLink(String zone, String selectedCategory, List noPossibleLinks, + Map, Link>> regionLinksMap) { if (buildingsPerZone.isEmpty()) { - ShpOptions shpBuildings = new ShpOptions(shapeFileBuildingsPath, "EPSG:4326", StandardCharsets.UTF_8); - List buildingsFeatures = shpBuildings.readFeatures(); + List buildingsFeatures = indexBuildings.getAllFeatures(); LanduseBuildingAnalysis.analyzeBuildingType(buildingsFeatures, buildingsPerZone, - landuseCategoriesAndDataConnection, shapeFileLandusePath, indexZones, shapeCRS); + landuseCategoriesAndDataConnection, indexLanduse, indexZones); } Id newLink = null; for (int a = 0; newLink == null && a < buildingsPerZone.get(zone).get(selectedCategory).size() * 2; a++) { @@ -835,9 +885,9 @@ private Id findPossibleLink(String zone, String selectedCategory, ArrayLis /** * Filters links by used mode "car" and creates Map with all links in each zone */ - static Map, Link>> filterLinksForZones(Scenario scenario, ShpOptions shpZones, Index indexZones, - HashMap>> buildingsPerZone) throws URISyntaxException { - Map, Link>> regionLinksMap = new HashMap<>(); + static Map, Link>> filterLinksForZones(Scenario scenario, Index indexZones, + Map>> buildingsPerZone) throws URISyntaxException { + Map, Link>> regionLinksMap = new HashMap<>(); List links; log.info("Filtering and assign links to zones. This take some time..."); @@ -850,31 +900,34 @@ static Map, Link>> filterLinksForZones(Scenario scenari Network networkToChange = NetworkUtils.readNetwork(networkPath); NetworkUtils.runNetworkCleaner(networkToChange); + CoordinateTransformation ct = indexZones.getShp().createTransformation(ProjectionUtils.getCRS(scenario.getNetwork())); + links = networkToChange.getLinks().values().stream().filter(l -> l.getAllowedModes().contains("car")) .collect(Collectors.toList()); links.forEach(l -> l.getAttributes().putAttribute("newCoord", - shpZones.createTransformation(scenario.getConfig().network().getInputCRS()).transform(l.getCoord()))); + CoordUtils.round(ct.transform(l.getCoord())))); links.forEach(l -> l.getAttributes().putAttribute("zone", indexZones.query((Coord) l.getAttributes().getAttribute("newCoord")))); links = links.stream().filter(l -> l.getAttributes().getAttribute("zone") != null).collect(Collectors.toList()); links.forEach(l -> regionLinksMap .computeIfAbsent((String) l.getAttributes().getAttribute("zone"), (k) -> new HashMap<>()) .put(l.getId(), l)); - if (regionLinksMap.size() != shpZones.readFeatures().size()) - findNearestLinkForZonesWithoutLinks(networkToChange, regionLinksMap, shpZones, buildingsPerZone); + if (regionLinksMap.size() != indexZones.size()) + findNearestLinkForZonesWithoutLinks(networkToChange, regionLinksMap, indexZones, buildingsPerZone); + return regionLinksMap; } /** - * Finds for areas without links the nearest Link, if the area contains any building. + * Finds for areas without links the nearest Link if the area contains any building. */ - private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, Map, Link>> regionLinksMap, - ShpOptions shpZones, - HashMap>> buildingsPerZone) { - for (SimpleFeature singleArea : shpZones.readFeatures()) { + private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, Map, Link>> regionLinksMap, + Index shpZones, + Map>> buildingsPerZone) { + for (SimpleFeature singleArea : shpZones.getAllFeatures()) { String zoneID = (String) singleArea.getAttribute("areaID"); if (!regionLinksMap.containsKey(zoneID) && buildingsPerZone.get(zoneID) != null) { - for (ArrayList buildingList : buildingsPerZone.get(zoneID).values()) { + for (List buildingList : buildingsPerZone.get(zoneID).values()) { for (SimpleFeature building : buildingList) { Link l = NetworkUtils.getNearestLink(networkToChange, MGC.point2Coord(((Geometry) building.getDefaultGeometry()).getCentroid())); @@ -892,14 +945,14 @@ private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, * Creates the number of trips between the zones for each mode and purpose. */ private TripDistributionMatrix createTripDistribution( - HashMap> trafficVolume_start, - HashMap> trafficVolume_stop, ShpOptions shpZones, - String smallScaleCommercialTrafficType, Scenario scenario, Path output, Map, Link>> regionLinksMap) + Map> trafficVolume_start, + Map> trafficVolume_stop, ShpOptions shpZones, + String smallScaleCommercialTrafficType, Scenario scenario, Path output, Map, Link>> regionLinksMap) throws Exception { final TripDistributionMatrix odMatrix = TripDistributionMatrix.Builder - .newInstance(shpZones, trafficVolume_start, trafficVolume_stop, smallScaleCommercialTrafficType).build(); - ArrayList listOfZones = new ArrayList<>(); + .newInstance(indexZones, trafficVolume_start, trafficVolume_stop, smallScaleCommercialTrafficType).build(); + List listOfZones = new ArrayList<>(); trafficVolume_start.forEach((k, v) -> { if (!listOfZones.contains(k.getZone())) listOfZones.add(k.getZone()); @@ -971,7 +1024,7 @@ public CarrierStrategyManager get() { travelDisutility, modeTravelTimes.get(TransportMode.car)); // final GenericStrategyManager strategyManager = new GenericStrategyManager<>(); - final CarrierStrategyManager strategyManager = FreightUtils.createDefaultCarrierStrategyManager(); + final CarrierStrategyManager strategyManager = CarrierControlerUtils.createDefaultCarrierStrategyManager(); strategyManager.setMaxPlansPerAgent(5); { GenericPlanStrategyImpl strategy = new GenericPlanStrategyImpl<>( @@ -1085,7 +1138,7 @@ private double getDistanceParameter(CarrierVehicle vehicle) { public void handleLeg(Leg leg) { if (leg.getRoute() instanceof NetworkRoute nRoute) { Id vehicleId = nRoute.getVehicleId(); - CarrierVehicle vehicle = CarrierUtils.getCarrierVehicle(carrier, vehicleId); + CarrierVehicle vehicle = CarriersUtils.getCarrierVehicle(carrier, vehicleId); Gbl.assertNotNull(vehicle); employedVehicles.add(vehicle); double distance = 0.0; diff --git a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java index 8054c953605..faffac894c1 100644 --- a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java @@ -29,7 +29,6 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.matsim.api.core.v01.Coord; -import org.matsim.application.options.ShpOptions; import org.matsim.application.options.ShpOptions.Index; import org.matsim.core.utils.geometry.geotools.MGC; import org.matsim.core.utils.io.IOUtils; @@ -37,14 +36,10 @@ import java.io.BufferedReader; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.*; /** * @author Ricardo Ewert @@ -58,14 +53,14 @@ public class LanduseBuildingAnalysis { * Creates a distribution of the given input data for each zone based on the * used OSM data. */ - static HashMap> createInputDataDistribution(Path output, - HashMap> landuseCategoriesAndDataConnection, Path inputDataDirectory, - String usedLanduseConfiguration, Path shapeFileLandusePath, Path shapeFileZonePath, - Path shapeFileBuildingsPath, String shapeCRS, HashMap>> buildingsPerZone) + static Map> createInputDataDistribution(Path output, + Map> landuseCategoriesAndDataConnection, Path inputDataDirectory, + String usedLanduseConfiguration, Index indexLanduse, Index indexZones, + Index indexBuildings, Map>> buildingsPerZone) throws IOException { - HashMap> resultingDataPerZone = new HashMap<>(); - HashMap zoneIdNameConnection = new HashMap<>(); + Map> resultingDataPerZone = new HashMap<>(); + Map zoneIdNameConnection = new HashMap<>(); Path outputFileInOutputFolder = output.resolve("calculatedData").resolve("dataDistributionPerZone.csv"); landuseCategoriesAndDataConnection.put("Inhabitants", @@ -113,12 +108,12 @@ static HashMap> createInputDataDistribution(Pat log.info("New analyze for data distribution is started. The used method is: " + usedLanduseConfiguration); - HashMap> landuseCategoriesPerZone = new HashMap<>(); - createLanduseDistribution(landuseCategoriesPerZone, shapeFileLandusePath, shapeFileZonePath, - usedLanduseConfiguration, shapeFileBuildingsPath, landuseCategoriesAndDataConnection, - buildingsPerZone, zoneIdNameConnection, shapeCRS); + Map> landuseCategoriesPerZone = new HashMap<>(); + createLanduseDistribution(landuseCategoriesPerZone, indexLanduse, indexZones, + usedLanduseConfiguration, indexBuildings, landuseCategoriesAndDataConnection, + buildingsPerZone, zoneIdNameConnection); - HashMap> investigationAreaData = new HashMap<>(); + Map> investigationAreaData = new HashMap<>(); readAreaData(investigationAreaData, inputDataDirectory); createResultingDataForLanduseInZones(landuseCategoriesPerZone, investigationAreaData, resultingDataPerZone, @@ -136,14 +131,14 @@ static HashMap> createInputDataDistribution(Pat * and the original data. */ private static void createResultingDataForLanduseInZones( - HashMap> landuseCategoriesPerZone, - HashMap> investigationAreaData, - HashMap> resultingDataPerZone, - HashMap> landuseCategoriesAndDataConnection) { + Map> landuseCategoriesPerZone, + Map> investigationAreaData, + Map> resultingDataPerZone, + Map> landuseCategoriesAndDataConnection) { - HashMap> totalSquareMetersPerCategory = new HashMap>(); - HashMap> totalEmployeesInCategoriesPerZone = new HashMap>(); - HashMap> totalEmployeesPerCategories = new HashMap>(); + Map> totalSquareMetersPerCategory = new HashMap>(); + Map> totalEmployeesInCategoriesPerZone = new HashMap>(); + Map> totalEmployeesPerCategories = new HashMap>(); investigationAreaData.keySet() .forEach(c -> totalSquareMetersPerCategory.computeIfAbsent(c, k -> new Object2DoubleOpenHashMap<>())); @@ -176,7 +171,7 @@ private static void createResultingDataForLanduseInZones( * creates the percentages of each category and zones based on the sum in this * category */ - HashMap> checkPercentages = new HashMap>(); + Map> checkPercentages = new HashMap>(); investigationAreaData.keySet() .forEach(c -> checkPercentages.computeIfAbsent(c, k -> new Object2DoubleOpenHashMap<>())); for (String zoneId : resultingDataPerZone.keySet()) @@ -220,22 +215,18 @@ private static void createResultingDataForLanduseInZones( * Method create the percentage for each land use category in each zone based on * the sum of this category in all zones of the zone shape file */ - private static void createLanduseDistribution(HashMap> landuseCategoriesPerZone, - Path shapeFileLandusePath, Path shapeFileZonePath, String usedLanduseConfiguration, - Path shapeFileBuildingsPath, HashMap> landuseCategoriesAndDataConnection, - HashMap>> buildingsPerZone, - HashMap zoneIdNameConnection, String shapeCRS) { + private static void createLanduseDistribution(Map> landuseCategoriesPerZone, + Index indexLanduse, Index indexZones, String usedLanduseConfiguration, + Index indexBuildings, Map> landuseCategoriesAndDataConnection, + Map>> buildingsPerZone, + Map zoneIdNameConnection) { List neededLanduseCategories = List.of("residential", "industrial", "commercial", "retail", "farmyard", "farmland", "construction"); - ShpOptions shpLanduse = new ShpOptions(shapeFileLandusePath, shapeCRS, StandardCharsets.UTF_8); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, shapeCRS, StandardCharsets.UTF_8); + List landuseFeatures = indexLanduse.getAllFeatures(); + List zonesFeatures = indexZones.getAllFeatures(); - List landuseFeatures = shpLanduse.readFeatures(); - List zonesFeatures = shpZones.readFeatures(); - - Index indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shpZones.getShapeCrs()); for (SimpleFeature singleZone : zonesFeatures) { Object2DoubleMap landusePerCategory = new Object2DoubleOpenHashMap<>(); @@ -246,10 +237,9 @@ private static void createLanduseDistribution(HashMap buildingsFeatures = shpBuildings.readFeatures(); + List buildingsFeatures = indexBuildings.getAllFeatures(); analyzeBuildingType(buildingsFeatures, buildingsPerZone, landuseCategoriesAndDataConnection, - shapeFileLandusePath, indexZones, shpLanduse.getShapeCrs()); + indexLanduse, indexZones); for (String zone : buildingsPerZone.keySet()) for (String category : buildingsPerZone.get(zone).keySet()) @@ -289,7 +279,7 @@ private static void createLanduseDistribution(HashMap> areaData, Path inputDataDirectory) + private static void readAreaData(Map> areaData, Path inputDataDirectory) throws IOException { Path areaDataPath = inputDataDirectory.resolve("investigationAreaData.csv"); @@ -300,7 +290,7 @@ private static void readAreaData(HashMap> areaD CSVFormat.Builder.create(CSVFormat.TDF).setHeader().setSkipHeaderRecord(true).build())) { for (CSVRecord record : parser) { - HashMap lookUpTable = new HashMap<>(); + Map lookUpTable = new HashMap<>(); for (String csvRecord : parser.getHeaderMap().keySet()) { if (parser.getHeaderMap().get(csvRecord) > 0) lookUpTable.put(csvRecord, Integer.valueOf(record.get(csvRecord))); @@ -314,11 +304,9 @@ private static void readAreaData(HashMap> areaD * Analysis the building types so that you have the buildings per zone and type. */ static void analyzeBuildingType(List buildingsFeatures, - HashMap>> buildingsPerZone, - HashMap> landuseCategoriesAndDataConnection, Path shapeFileLandusePath, - Index indexZones, String crsLanduse) { - - Index indexLanduse = SmallScaleCommercialTrafficUtils.getIndexLanduse(shapeFileLandusePath, crsLanduse); + Map>> buildingsPerZone, + Map> landuseCategoriesAndDataConnection, Index indexLanduse, + Index indexZones) { int countOSMObjects = 0; log.info("Analyzing buildings types. This may take some time..."); @@ -360,7 +348,7 @@ static void analyzeBuildingType(List buildingsFeatures, categoriesOfBuilding.add("Employee"); if (singleZone != null) { categoriesOfBuilding.forEach(c -> buildingsPerZone - .computeIfAbsent(singleZone, k -> new HashMap>()) + .computeIfAbsent(singleZone, k -> new HashMap<>()) .computeIfAbsent(c, k -> new ArrayList()).add(singleBuildingFeature)); } } diff --git a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java index 9d7ab8ad305..1ea26e82ee3 100644 --- a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java +++ b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java @@ -40,19 +40,20 @@ import org.matsim.api.core.v01.population.*; import org.matsim.application.options.ShpOptions; import org.matsim.application.options.ShpOptions.Index; -import org.matsim.contrib.freight.carrier.*; -import org.matsim.contrib.freight.carrier.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freight.carrier.Tour.Pickup; -import org.matsim.contrib.freight.carrier.Tour.ServiceActivity; -import org.matsim.contrib.freight.carrier.Tour.TourElement; -import org.matsim.contrib.freight.controler.FreightUtils; -import org.matsim.contrib.freight.jsprit.MatsimJspritFactory; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; +import org.matsim.freight.carriers.Tour.Pickup; +import org.matsim.freight.carriers.Tour.ServiceActivity; +import org.matsim.freight.carriers.Tour.TourElement; +import org.matsim.freight.carriers.jsprit.MatsimJspritFactory; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PopulationUtils; import org.matsim.core.utils.io.IOUtils; +import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; +import org.matsim.vehicles.Vehicles; import java.io.BufferedWriter; import java.io.IOException; @@ -74,7 +75,7 @@ public class SmallScaleCommercialTrafficUtils { private static final Joiner JOIN = Joiner.on("\t"); /** - * Creates and return the Index of the zones shape. + * Creates and return the Index of the zone shape. * * @return indexZones */ @@ -96,17 +97,28 @@ static Index getIndexLanduse(Path shapeFileLandusePath, String shapeCRS) { } /** - * Writes a csv file with result of the distribution per zone of the input data. + * Creates and return the Index of the building shape. + * + * @return indexBuildings + */ + static Index getIndexBuildings(Path shapeFileBuildingsPath, String shapeCRS) { + + ShpOptions shpLanduse = new ShpOptions(shapeFileBuildingsPath, shapeCRS, StandardCharsets.UTF_8); + return shpLanduse.createIndex(shapeCRS, "type"); + } + + /** + * Writes a csv file with the result of the distribution per zone of the input data. */ - static void writeResultOfDataDistribution(HashMap> resultingDataPerZone, - Path outputFileInOutputFolder, HashMap zoneIdNameConnection) + static void writeResultOfDataDistribution(Map> resultingDataPerZone, + Path outputFileInOutputFolder, Map zoneIdNameConnection) throws IOException { writeCSVWithCategoryHeader(resultingDataPerZone, outputFileInOutputFolder, zoneIdNameConnection); log.info("The data distribution is finished and written to: " + outputFileInOutputFolder); } - static Id findNearestPossibleLink(String zone, ArrayList noPossibleLinks, Map, Link>> regionLinksMap, + static Id findNearestPossibleLink(String zone, List noPossibleLinks, Map, Link>> regionLinksMap, Id newLink, Coord centroidPointOfBuildingPolygon, int numberOfPossibleLinks) { double minDistance = Double.MAX_VALUE; searchLink: @@ -144,9 +156,9 @@ static Id findNearestPossibleLink(String zone, ArrayList noPossibl /** * Writer of data distribution data. */ - private static void writeCSVWithCategoryHeader(HashMap> resultingDataPerZone, + private static void writeCSVWithCategoryHeader(Map> resultingDataPerZone, Path outputFileInInputFolder, - HashMap zoneIdNameConnection) throws MalformedURLException { + Map zoneIdNameConnection) throws MalformedURLException { BufferedWriter writer = IOUtils.getBufferedWriter(outputFileInInputFolder.toUri().toURL(), StandardCharsets.UTF_8, true); try { @@ -170,7 +182,7 @@ private static void writeCSVWithCategoryHeader(HashMap idCounter = new HashMap<>(); Population populationFromCarrier = (Population) scenario.getScenarioElement("allpersons"); + Vehicles allVehicles = VehicleUtils.getOrCreateAllvehicles(scenario); + for (Person person : populationFromCarrier.getPersons().values()) { Plan plan = popFactory.createPlan(); String carrierName = person.getId().toString().split("freight_")[1].split("_veh_")[0]; - Carrier relatedCarrier = FreightUtils.addOrGetCarriers(scenario).getCarriers() + Carrier relatedCarrier = CarriersUtils.addOrGetCarriers(scenario).getCarriers() .get(Id.create(carrierName, Carrier.class)); String subpopulation = relatedCarrier.getAttributes().getAttribute("subpopulation").toString(); final String mode; @@ -239,11 +253,12 @@ else if (subpopulation.contains("goodsTraffic")) if (relatedCarrier.getAttributes().getAsMap().containsKey("tourStartArea")) newPerson.getAttributes().putAttribute("tourStartArea", relatedCarrier.getAttributes().getAttribute("tourStartArea")); - VehicleUtils.insertVehicleIdsIntoAttributes(newPerson, (new HashMap<>() { - { - put(mode, (Id.createVehicleId(person.getId().toString()))); - } - })); + + Id vehicleId = Id.createVehicleId(person.getId().toString()); + + VehicleUtils.insertVehicleIdsIntoAttributes(newPerson, Map.of(mode, vehicleId)); + VehicleUtils.insertVehicleTypesIntoAttributes(newPerson, Map.of(mode, allVehicles.getVehicles().get(vehicleId).getType().getId())); + population.addPerson(newPerson); } @@ -282,7 +297,7 @@ static String getSampleNameOfOutputFolder(double sample) { * dispersedTraffic will be added additionally. */ static void readExistingModels(Scenario scenario, double sampleScenario, - Map, Link>> regionLinksMap) throws Exception { + Map, Link>> regionLinksMap) throws Exception { Path existingModelsFolder = Path.of(scenario.getConfig().getContext().toURI()).getParent().resolve("existingModels"); String locationOfExistingModels = existingModelsFolder.resolve("existingModels.csv").toString(); @@ -460,10 +475,10 @@ static void readExistingModels(Scenario scenario, double sampleScenario, } } carrierToRemove.forEach(carrier -> carriers.getCarriers().remove(carrier.getId())); - FreightUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().putAll(usedVehicleTypes.getVehicleTypes()); + CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().putAll(usedVehicleTypes.getVehicleTypes()); carriers.getCarriers().values().forEach(carrier -> { - Carrier newCarrier = CarrierUtils + Carrier newCarrier = CarriersUtils .createCarrier(Id.create(modelName + "_" + carrier.getId().toString(), Carrier.class)); newCarrier.getAttributes().putAttribute("subpopulation", modelTrafficType); if (modelPurpose != null) @@ -490,7 +505,7 @@ else if (!carrier.getShipments().isEmpty()) newCarrier.getAttributes().putAttribute("tourStartArea", String.join(";", startAreas)); - CarrierUtils.setJspritIterations(newCarrier, 0); + CarriersUtils.setJspritIterations(newCarrier, 0); // recalculate score for selectedPlan VehicleRoutingProblem vrp = MatsimJspritFactory .createRoutingProblemBuilder(carrier, scenario.getNetwork()).build(); @@ -500,10 +515,10 @@ else if (!carrier.getShipments().isEmpty()) double costs = solutionCostsCalculator.getCosts(solution) * (-1); carrier.getSelectedPlan().setScore(costs); } else { - CarrierUtils.setJspritIterations(newCarrier, CarrierUtils.getJspritIterations(carrier)); + CarriersUtils.setJspritIterations(newCarrier, CarriersUtils.getJspritIterations(carrier)); newCarrier.getCarrierCapabilities().setFleetSize(carrier.getCarrierCapabilities().getFleetSize()); } - FreightUtils.addOrGetCarriers(scenario).getCarriers().put(newCarrier.getId(), newCarrier); + CarriersUtils.addOrGetCarriers(scenario).getCarriers().put(newCarrier.getId(), newCarrier); }); } } @@ -511,7 +526,7 @@ else if (!carrier.getShipments().isEmpty()) /** * Find the zone where the link is located */ - static String findZoneOfLink(Id linkId, Map, Link>> regionLinksMap) { + static String findZoneOfLink(Id linkId, Map, Link>> regionLinksMap) { for (String area : regionLinksMap.keySet()) { if (regionLinksMap.get(area).containsKey(linkId)) return area; diff --git a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java index 6f747bc2ee5..7e9e591eabc 100644 --- a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java +++ b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java @@ -27,11 +27,10 @@ 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.contrib.freight.carrier.*; -import org.matsim.contrib.freight.carrier.Tour.Pickup; -import org.matsim.contrib.freight.carrier.Tour.ServiceActivity; -import org.matsim.contrib.freight.carrier.Tour.TourElement; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.Tour.Pickup; +import org.matsim.freight.carriers.Tour.ServiceActivity; +import org.matsim.freight.carriers.Tour.TourElement; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.utils.io.IOUtils; @@ -51,10 +50,10 @@ public class TrafficVolumeGeneration { private static final Logger log = LogManager.getLogger(TrafficVolumeGeneration.class); private static final Joiner JOIN = Joiner.on("\t"); - private static HashMap> generationRatesStart = new HashMap<>(); - private static HashMap> generationRatesStop = new HashMap<>(); - private static HashMap> commitmentRatesStart = new HashMap<>(); - private static HashMap> commitmentRatesStop = new HashMap<>(); + private static Map> generationRatesStart = new HashMap<>(); + private static Map> generationRatesStop = new HashMap<>(); + private static Map> commitmentRatesStart = new HashMap<>(); + private static Map> commitmentRatesStop = new HashMap<>(); static class TrafficVolumeKey { private final String zone; @@ -117,11 +116,11 @@ static TrafficVolumeKey makeTrafficVolumeKey(String zone, String modeORvehType) * @param modesORvehTypes selected mode or vehicleType * @return trafficVolume_start */ - static HashMap> createTrafficVolume_start( - HashMap> resultingDataPerZone, Path output, double sample, - ArrayList modesORvehTypes, String trafficType) throws MalformedURLException { + static Map> createTrafficVolume_start( + Map> resultingDataPerZone, Path output, double sample, + List modesORvehTypes, String trafficType) throws MalformedURLException { - HashMap> trafficVolume_start = new HashMap<>(); + Map> trafficVolume_start = new HashMap<>(); calculateTrafficVolumePerZone(trafficVolume_start, resultingDataPerZone, "start", sample, modesORvehTypes); String sampleName = SmallScaleCommercialTrafficUtils.getSampleNameOfOutputFolder(sample); Path outputFileStart = output.resolve("calculatedData") @@ -141,11 +140,11 @@ static HashMap> createTrafficVolume_ * @param modesORvehTypes selected mode or vehicleType * @return trafficVolume_stop */ - static HashMap> createTrafficVolume_stop( - HashMap> resultingDataPerZone, Path output, double sample, - ArrayList modesORvehTypes, String trafficType) throws MalformedURLException { + static Map> createTrafficVolume_stop( + Map> resultingDataPerZone, Path output, double sample, + List modesORvehTypes, String trafficType) throws MalformedURLException { - HashMap> trafficVolume_stop = new HashMap<>(); + Map> trafficVolume_stop = new HashMap<>(); calculateTrafficVolumePerZone(trafficVolume_stop, resultingDataPerZone, "stop", sample, modesORvehTypes); String sampleName = SmallScaleCommercialTrafficUtils.getSampleNameOfOutputFolder(sample); Path outputFileStop = output.resolve("calculatedData") @@ -165,12 +164,12 @@ static HashMap> createTrafficVolume_ * @param sample sample size */ private static void calculateTrafficVolumePerZone( - HashMap> trafficVolume, - HashMap> resultingDataPerZone, String volumeType, double sample, - ArrayList modesORvehTypes) { + Map> trafficVolume, + Map> resultingDataPerZone, String volumeType, double sample, + List modesORvehTypes) { - HashMap> generationRates; - HashMap> commitmentRates; + Map> generationRates; + Map> commitmentRates; if (volumeType.equals("start")) { generationRates = generationRatesStart; @@ -217,7 +216,7 @@ private static void calculateTrafficVolumePerZone( * @param trafficVolume traffic volumes for each combination * @param outputFileInInputFolder location of written output */ - private static void writeCSVTrafficVolume(HashMap> trafficVolume, + private static void writeCSVTrafficVolume(Map> trafficVolume, Path outputFileInInputFolder) throws MalformedURLException { BufferedWriter writer = IOUtils.getBufferedWriter(outputFileInInputFolder.toUri().toURL(), StandardCharsets.UTF_8, true); @@ -240,7 +239,7 @@ private static void writeCSVTrafficVolume(HashMap, Link>> regionLinksMap, String smallScaleCommercialTrafficType, - HashMap> trafficVolumePerTypeAndZone_start, - HashMap> trafficVolumePerTypeAndZone_stop) { + Map, Link>> regionLinksMap, String smallScaleCommercialTrafficType, + Map> trafficVolumePerTypeAndZone_start, + Map> trafficVolumePerTypeAndZone_stop) { - for (Carrier carrier : FreightUtils.addOrGetCarriers(scenario).getCarriers().values()) { + for (Carrier carrier : CarriersUtils.addOrGetCarriers(scenario).getCarriers().values()) { if (!carrier.getAttributes().getAsMap().containsKey("subpopulation") || !carrier.getAttributes().getAttribute("subpopulation").equals(smallScaleCommercialTrafficType)) continue; @@ -322,7 +321,7 @@ static void reduceDemandBasedOnExistingCarriers(Scenario scenario, } } } else { - if (carrier.getServices().size() != 0) { + if (!carrier.getServices().isEmpty()) { List possibleStartAreas = new ArrayList<>(); for (CarrierVehicle vehicle : carrier.getCarrierCapabilities().getCarrierVehicles().values()) { possibleStartAreas @@ -342,7 +341,7 @@ static void reduceDemandBasedOnExistingCarriers(Scenario scenario, + " is not part of the zones. That's why the traffic volume was not reduces by this service."); } } - } else if (carrier.getShipments().size() != 0) { + } else if (!carrier.getShipments().isEmpty()) { for (CarrierShipment shipment : carrier.getShipments().values()) { String startZone = SmallScaleCommercialTrafficUtils.findZoneOfLink(shipment.getFrom(), regionLinksMap); @@ -373,8 +372,8 @@ static void reduceDemandBasedOnExistingCarriers(Scenario scenario, * @param stopZone end zone */ private static void reduceVolumeForThisExistingJobElement( - HashMap> trafficVolumePerTypeAndZone_start, - HashMap> trafficVolumePerTypeAndZone_stop, String modeORvehType, + Map> trafficVolumePerTypeAndZone_start, + Map> trafficVolumePerTypeAndZone_stop, String modeORvehType, Integer purpose, String startZone, String stopZone) { if (startZone != null && stopZone != null) { @@ -403,7 +402,7 @@ private static void reduceVolumeForThisExistingJobElement( * @param originalZone zone with volume of 0, although volume in existing model */ private static void reduceVolumeForOtherArea( - HashMap> trafficVolumePerTypeAndZone, String modeORvehType, + Map> trafficVolumePerTypeAndZone, String modeORvehType, Integer purpose, String volumeType, String originalZone) { ArrayList shuffledKeys = new ArrayList<>( trafficVolumePerTypeAndZone.keySet()); @@ -426,16 +425,16 @@ private static void reduceVolumeForOtherArea( * @param smallScaleCommercialTrafficType used trafficType (freight or business traffic) * @param generationType start or stop rates */ - private static HashMap> setGenerationRates(String smallScaleCommercialTrafficType, + private static Map> setGenerationRates(String smallScaleCommercialTrafficType, String generationType) { - HashMap> generationRates = new HashMap<>(); - HashMap ratesPerPurpose1 = new HashMap<>(); - HashMap ratesPerPurpose2 = new HashMap<>(); - HashMap ratesPerPurpose3 = new HashMap<>(); - HashMap ratesPerPurpose4 = new HashMap<>(); - HashMap ratesPerPurpose5 = new HashMap<>(); - HashMap ratesPerPurpose6 = new HashMap<>(); + Map> generationRates = new HashMap<>(); + Map ratesPerPurpose1 = new HashMap<>(); + Map ratesPerPurpose2 = new HashMap<>(); + Map ratesPerPurpose3 = new HashMap<>(); + Map ratesPerPurpose4 = new HashMap<>(); + Map ratesPerPurpose5 = new HashMap<>(); + Map ratesPerPurpose6 = new HashMap<>(); if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { if (generationType.equals("start")) { ratesPerPurpose1.put("Inhabitants", 0.0); @@ -658,43 +657,43 @@ private static HashMap> setGenerationRates(Stri * @param smallScaleCommercialTrafficType used trafficType (freight or business traffic) * @param commitmentType start or stop parameter */ - private static HashMap> setCommitmentRates(String smallScaleCommercialTrafficType, + private static Map> setCommitmentRates(String smallScaleCommercialTrafficType, String commitmentType) { - HashMap> commitmentRates = new HashMap<>(); + Map> commitmentRates = new HashMap<>(); if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { // the first number is the purpose; second number the vehicle type - HashMap ratesPerPurpose1_1 = new HashMap<>(); - HashMap ratesPerPurpose1_2 = new HashMap<>(); - HashMap ratesPerPurpose1_3 = new HashMap<>(); - HashMap ratesPerPurpose1_4 = new HashMap<>(); - HashMap ratesPerPurpose1_5 = new HashMap<>(); - HashMap ratesPerPurpose2_1 = new HashMap<>(); - HashMap ratesPerPurpose2_2 = new HashMap<>(); - HashMap ratesPerPurpose2_3 = new HashMap<>(); - HashMap ratesPerPurpose2_4 = new HashMap<>(); - HashMap ratesPerPurpose2_5 = new HashMap<>(); - HashMap ratesPerPurpose3_1 = new HashMap<>(); - HashMap ratesPerPurpose3_2 = new HashMap<>(); - HashMap ratesPerPurpose3_3 = new HashMap<>(); - HashMap ratesPerPurpose3_4 = new HashMap<>(); - HashMap ratesPerPurpose3_5 = new HashMap<>(); - HashMap ratesPerPurpose4_1 = new HashMap<>(); - HashMap ratesPerPurpose4_2 = new HashMap<>(); - HashMap ratesPerPurpose4_3 = new HashMap<>(); - HashMap ratesPerPurpose4_4 = new HashMap<>(); - HashMap ratesPerPurpose4_5 = new HashMap<>(); - HashMap ratesPerPurpose5_1 = new HashMap<>(); - HashMap ratesPerPurpose5_2 = new HashMap<>(); - HashMap ratesPerPurpose5_3 = new HashMap<>(); - HashMap ratesPerPurpose5_4 = new HashMap<>(); - HashMap ratesPerPurpose5_5 = new HashMap<>(); - HashMap ratesPerPurpose6_1 = new HashMap<>(); - HashMap ratesPerPurpose6_2 = new HashMap<>(); - HashMap ratesPerPurpose6_3 = new HashMap<>(); - HashMap ratesPerPurpose6_4 = new HashMap<>(); - HashMap ratesPerPurpose6_5 = new HashMap<>(); + Map ratesPerPurpose1_1 = new HashMap<>(); + Map ratesPerPurpose1_2 = new HashMap<>(); + Map ratesPerPurpose1_3 = new HashMap<>(); + Map ratesPerPurpose1_4 = new HashMap<>(); + Map ratesPerPurpose1_5 = new HashMap<>(); + Map ratesPerPurpose2_1 = new HashMap<>(); + Map ratesPerPurpose2_2 = new HashMap<>(); + Map ratesPerPurpose2_3 = new HashMap<>(); + Map ratesPerPurpose2_4 = new HashMap<>(); + Map ratesPerPurpose2_5 = new HashMap<>(); + Map ratesPerPurpose3_1 = new HashMap<>(); + Map ratesPerPurpose3_2 = new HashMap<>(); + Map ratesPerPurpose3_3 = new HashMap<>(); + Map ratesPerPurpose3_4 = new HashMap<>(); + Map ratesPerPurpose3_5 = new HashMap<>(); + Map ratesPerPurpose4_1 = new HashMap<>(); + Map ratesPerPurpose4_2 = new HashMap<>(); + Map ratesPerPurpose4_3 = new HashMap<>(); + Map ratesPerPurpose4_4 = new HashMap<>(); + Map ratesPerPurpose4_5 = new HashMap<>(); + Map ratesPerPurpose5_1 = new HashMap<>(); + Map ratesPerPurpose5_2 = new HashMap<>(); + Map ratesPerPurpose5_3 = new HashMap<>(); + Map ratesPerPurpose5_4 = new HashMap<>(); + Map ratesPerPurpose5_5 = new HashMap<>(); + Map ratesPerPurpose6_1 = new HashMap<>(); + Map ratesPerPurpose6_2 = new HashMap<>(); + Map ratesPerPurpose6_3 = new HashMap<>(); + Map ratesPerPurpose6_4 = new HashMap<>(); + Map ratesPerPurpose6_5 = new HashMap<>(); if (commitmentType.equals("start")) { ratesPerPurpose1_1.put("Inhabitants", 0.0); ratesPerPurpose1_1.put("Employee", 0.8); diff --git a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrix.java b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrix.java index 698f43a967a..7d631a6b96d 100644 --- a/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrix.java +++ b/contribs/application/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrix.java @@ -32,21 +32,24 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.freight.jsprit.NetworkBasedTransportCosts; +import org.matsim.application.options.ShpOptions.Index; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; +import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts; +import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; import org.opengis.feature.simple.SimpleFeature; -import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; import java.io.BufferedWriter; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** @@ -61,8 +64,8 @@ public class TripDistributionMatrix { private final ArrayList listOfModesORvehTypes = new ArrayList<>(); private final ArrayList listOfPurposes = new ArrayList<>(); private final List zonesFeatures; - private final HashMap> trafficVolume_start; - private final HashMap> trafficVolume_stop; + private final Map> trafficVolume_start; + private final Map> trafficVolume_stop; private final String smallScaleCommercialTrafficType; private static class TripDistributionMatrixKey { @@ -232,23 +235,23 @@ public boolean equals(Object obj) { public static class Builder { private final List zonesFeatures; - private final HashMap> trafficVolume_start; - private final HashMap> trafficVolume_stop; + private final Map> trafficVolume_start; + private final Map> trafficVolume_stop; private final String smallScaleCommercialTrafficType; - public static Builder newInstance(ShpOptions shpZones, - HashMap> trafficVolume_start, - HashMap> trafficVolume_stop, + public static Builder newInstance(Index indexZones, + Map> trafficVolume_start, + Map> trafficVolume_stop, String smallScaleCommercialTrafficType) { - return new Builder(shpZones, trafficVolume_start, trafficVolume_stop, smallScaleCommercialTrafficType); + return new Builder(indexZones, trafficVolume_start, trafficVolume_stop, smallScaleCommercialTrafficType); } - private Builder(ShpOptions shpZones, - HashMap> trafficVolume_start, - HashMap> trafficVolume_stop, + private Builder(Index indexZones, + Map> trafficVolume_start, + Map> trafficVolume_stop, String smallScaleCommercialTrafficType) { super(); - this.zonesFeatures = shpZones.readFeatures(); + this.zonesFeatures = indexZones.getAllFeatures(); this.trafficVolume_start = trafficVolume_start; this.trafficVolume_stop = trafficVolume_stop; this.smallScaleCommercialTrafficType = smallScaleCommercialTrafficType; @@ -285,7 +288,7 @@ private TripDistributionMatrix(Builder builder) { * @param regionLinksMap links in each zone */ void setTripDistributionValue(String startZone, String stopZone, String modeORvehType, Integer purpose, String smallScaleCommercialTrafficType, Network network, - Map, Link>> regionLinksMap, double resistanceFactor) { + Map, Link>> regionLinksMap, double resistanceFactor) { double volumeStart = trafficVolume_start.get(TrafficVolumeGeneration.makeTrafficVolumeKey(startZone, modeORvehType)).getDouble(purpose); double volumeStop = trafficVolume_stop.get(TrafficVolumeGeneration.makeTrafficVolumeKey(stopZone, modeORvehType)).getDouble(purpose); int roundedVolume; @@ -337,7 +340,7 @@ Integer getTripDistributionValue(String startZone, String stopZone, String modeO * @param stopZone stop zone * @param regionLinksMap links for each zone */ - private Double getResistanceFunktionValue(String startZone, String stopZone, Network network, Map, Link>> regionLinksMap, double resistanceFactor) { + private Double getResistanceFunktionValue(String startZone, String stopZone, Network network, Map, Link>> regionLinksMap, double resistanceFactor) { //if false the calculation is faster; e.g. for debugging boolean useNetworkRoutesForResistanceFunction = true; @@ -448,8 +451,8 @@ private VehicleImpl getExampleVehicle(Location fromId) { * @return gravity constant */ private double getGravityConstant(String baseZone, - HashMap> trafficVolume, String modeORvehType, - Integer purpose, Network network, Map, Link>> regionLinksMap, double resistanceFactor) { + Map> trafficVolume, String modeORvehType, + Integer purpose, Network network, Map, Link>> regionLinksMap, double resistanceFactor) { GravityConstantKey gravityKey = makeGravityKey(baseZone, modeORvehType, purpose); if (!gravityConstantACache.containsKey(gravityKey)) { @@ -629,7 +632,7 @@ void writeODMatrices(Path output, String smallScaleCommercialTrafficType) throws writer.close(); } catch (IOException e) { - e.printStackTrace(); + log.error("Problem to write OD matrix", e); } log.info("Write OD matrix for mode " + modeORvehType + " and for purpose " + purpose + " to " + outputFolder); diff --git a/contribs/application/src/test/java/org/matsim/application/ApplicationUtilsTest.java b/contribs/application/src/test/java/org/matsim/application/ApplicationUtilsTest.java index edb2bcdbba6..31d1d3d1970 100644 --- a/contribs/application/src/test/java/org/matsim/application/ApplicationUtilsTest.java +++ b/contribs/application/src/test/java/org/matsim/application/ApplicationUtilsTest.java @@ -1,16 +1,16 @@ package org.matsim.application; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.application.analysis.TestAnalysis; import org.matsim.application.analysis.TestDependentAnalysis; import org.matsim.application.options.ShpOptions; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class ApplicationUtilsTest { @Test - public void shp() { + void shp() { assertTrue(ApplicationUtils.acceptsOptions(TestAnalysis.class, ShpOptions.class)); diff --git a/contribs/application/src/test/java/org/matsim/application/CommandRunnerTest.java b/contribs/application/src/test/java/org/matsim/application/CommandRunnerTest.java index 67f566eb5ae..bd7f228964f 100644 --- a/contribs/application/src/test/java/org/matsim/application/CommandRunnerTest.java +++ b/contribs/application/src/test/java/org/matsim/application/CommandRunnerTest.java @@ -1,8 +1,8 @@ package org.matsim.application; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.analysis.TestDependentAnalysis; import org.matsim.application.analysis.TestOtherAnalysis; import org.matsim.application.analysis.TestOtherDependentAnalysis; @@ -12,11 +12,11 @@ public class CommandRunnerTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void runner() { + void runner() { Path path = Path.of(utils.getOutputDirectory()); diff --git a/contribs/application/src/test/java/org/matsim/application/MATSimApplicationTest.java b/contribs/application/src/test/java/org/matsim/application/MATSimApplicationTest.java index 69931f9032c..9d9d2052338 100644 --- a/contribs/application/src/test/java/org/matsim/application/MATSimApplicationTest.java +++ b/contribs/application/src/test/java/org/matsim/application/MATSimApplicationTest.java @@ -1,9 +1,9 @@ package org.matsim.application; -import org.junit.Assume; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.options.SampleOptions; import org.matsim.application.prepare.freight.tripExtraction.ExtractRelevantFreightTrips; import org.matsim.application.prepare.population.GenerateShortDistanceTrips; @@ -11,7 +11,7 @@ import org.matsim.application.prepare.population.TrajectoryToPlans; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.utils.io.IOUtils; @@ -24,48 +24,48 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class MATSimApplicationTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void help() { + void help() { int ret = MATSimApplication.execute(TestScenario.class, "--help"); - assertEquals("Return code should be 0", 0, ret); + assertEquals(0, ret, "Return code should be 0"); } @Test - public void config() { + void config() { Controler controler = MATSimApplication.prepare(TestScenario.class, ConfigUtils.createConfig(), "-c:controler.runId=Test123", "--config:global.numberOfThreads=4", "--config:plans.inputCRS", "EPSG:1234"); Config config = controler.getConfig(); - assertThat(config.controler().getRunId()).isEqualTo("Test123"); + assertThat(config.controller().getRunId()).isEqualTo("Test123"); assertThat(config.global().getNumberOfThreads()).isEqualTo(4); assertThat(config.plans().getInputCRS()).isEqualTo("EPSG:1234"); } @Test - public void yaml() { + void yaml() { Path yml = Path.of(utils.getClassInputDirectory(), "specs.yml"); Controler controler = MATSimApplication.prepare(TestScenario.class, ConfigUtils.createConfig(), "--yaml", yml.toString()); - assertThat(controler.getConfig().controler().getRunId()) + assertThat(controler.getConfig().controller().getRunId()) .isEqualTo("567"); - PlanCalcScoreConfigGroup score = controler.getConfig().planCalcScore(); + ScoringConfigGroup score = controler.getConfig().scoring(); - PlanCalcScoreConfigGroup.ScoringParameterSet params = score.getScoringParameters(null); + ScoringConfigGroup.ScoringParameterSet params = score.getScoringParameters(null); assertThat(params.getOrCreateModeParams("car").getConstant()) .isEqualTo(-1); @@ -76,23 +76,23 @@ public void yaml() { } @Test - public void sample() { + void sample() { Controler controler = MATSimApplication.prepare(TestScenario.class, ConfigUtils.createConfig(), "--10pct"); - assertThat(controler.getConfig().controler().getRunId()) + assertThat(controler.getConfig().controller().getRunId()) .isEqualTo("run-10pct"); controler = MATSimApplication.prepare(TestScenario.class, ConfigUtils.createConfig()); - assertThat(controler.getConfig().controler().getRunId()) + assertThat(controler.getConfig().controller().getRunId()) .isEqualTo("run-25pct"); } @Test - public void population() throws MalformedURLException { + void population() throws MalformedURLException { Path input = Path.of(utils.getClassInputDirectory()); Path output = Path.of(utils.getOutputDirectory()); @@ -127,13 +127,13 @@ public void population() throws MalformedURLException { } @Test - @Ignore("Class is deprecated") - public void freight() { + @Disabled("Class is deprecated") + void freight() { Path input = Path.of("..", "..", "..", "..", "shared-svn", "komodnext", "data", "freight", "original_data").toAbsolutePath().normalize(); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); Path output = Path.of(utils.getOutputDirectory()); @@ -161,14 +161,14 @@ public void freight() { } @Test - public void run() { + void run() { Config config = ConfigUtils.createConfig(); Path out = Path.of(utils.getOutputDirectory()).resolve("out"); - config.controler().setOutputDirectory(out.toString()); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(1); + config.controller().setOutputDirectory(out.toString()); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(1); int ret = MATSimApplication.execute(TestScenario.class, config); @@ -197,7 +197,7 @@ public TestScenario() { @Override protected Config prepareConfig(Config config) { - config.controler().setRunId(sample.adjustName("run-25pct")); + config.controller().setRunId(sample.adjustName("run-25pct")); return config; } diff --git a/contribs/application/src/test/java/org/matsim/application/analysis/LogFileAnalysisTest.java b/contribs/application/src/test/java/org/matsim/application/analysis/LogFileAnalysisTest.java index 13c79e7877e..5309e1585b5 100644 --- a/contribs/application/src/test/java/org/matsim/application/analysis/LogFileAnalysisTest.java +++ b/contribs/application/src/test/java/org/matsim/application/analysis/LogFileAnalysisTest.java @@ -1,8 +1,8 @@ package org.matsim.application.analysis; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.ApplicationUtils; import org.matsim.application.MATSimApplication; import org.matsim.application.MATSimApplicationTest; @@ -16,23 +16,23 @@ public class LogFileAnalysisTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void output() throws IOException { + void output() throws IOException { Config config = ConfigUtils.createConfig(); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(2); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(2); int execute = MATSimApplication.execute(MATSimApplicationTest.TestScenario.class, config); Assertions.assertThat(execute) .isEqualTo(0); - Path out = Path.of(config.controler().getOutputDirectory()); + Path out = Path.of(config.controller().getOutputDirectory()); new LogFileAnalysis().execute( "--input", ApplicationUtils.matchInput("logfile.log", out).toString(), "--output-memory-stats", out.resolve("mem_stats.csv").toString(), diff --git a/contribs/application/src/test/java/org/matsim/application/options/CsvOptionsTest.java b/contribs/application/src/test/java/org/matsim/application/options/CsvOptionsTest.java index fff884efa77..65299cb0e81 100644 --- a/contribs/application/src/test/java/org/matsim/application/options/CsvOptionsTest.java +++ b/contribs/application/src/test/java/org/matsim/application/options/CsvOptionsTest.java @@ -2,9 +2,9 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import java.io.IOException; import java.nio.file.Path; @@ -14,15 +14,15 @@ public class CsvOptionsTest { - @Rule - public TemporaryFolder f = new TemporaryFolder(); + @TempDir + public Path f; @Test - public void output() throws IOException { + void output() throws IOException { CsvOptions csv = new CsvOptions(CSVFormat.Predefined.TDF); - Path tmp = f.getRoot().toPath().resolve("test.csv"); + Path tmp = f.resolve("test.csv"); CSVPrinter printer = csv.createPrinter(tmp); @@ -34,4 +34,4 @@ public void output() throws IOException { .hasContent("header\tcolumn\n1\t2"); } -} \ No newline at end of file +} diff --git a/contribs/application/src/test/java/org/matsim/application/options/SampleOptionsTest.java b/contribs/application/src/test/java/org/matsim/application/options/SampleOptionsTest.java index 545e30560a2..cc7f4469b2b 100644 --- a/contribs/application/src/test/java/org/matsim/application/options/SampleOptionsTest.java +++ b/contribs/application/src/test/java/org/matsim/application/options/SampleOptionsTest.java @@ -2,7 +2,7 @@ import com.google.common.util.concurrent.AtomicDouble; import org.assertj.core.api.Assertions; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.application.MATSimAppCommand; import picocli.CommandLine; @@ -11,7 +11,7 @@ public class SampleOptionsTest { @Test - public void flexible() { + void flexible() { AtomicInteger size = new AtomicInteger(); AtomicDouble dSize = new AtomicDouble(); @@ -39,7 +39,7 @@ public Integer call() throws Exception { } @Test - public void fixed() { + void fixed() { AtomicInteger size = new AtomicInteger(); diff --git a/contribs/application/src/test/java/org/matsim/application/options/ShpOptionsTest.java b/contribs/application/src/test/java/org/matsim/application/options/ShpOptionsTest.java index 8874cfaf671..7742e1bdc2e 100644 --- a/contribs/application/src/test/java/org/matsim/application/options/ShpOptionsTest.java +++ b/contribs/application/src/test/java/org/matsim/application/options/ShpOptionsTest.java @@ -1,11 +1,10 @@ package org.matsim.application.options; -import org.junit.Assert; -import org.junit.Assume; -import org.junit.Rule; -import org.junit.Test; +import org.assertj.core.data.Offset; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.GeometryFactory; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; @@ -19,11 +18,11 @@ public class ShpOptionsTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void readZip() { + void readZip() { // use same shape file as for land-use Path input = Path.of(utils.getClassInputDirectory() @@ -31,7 +30,7 @@ public void readZip() { .replace("options", "prepare")) .resolve("andorra-latest-free.shp.zip"); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); ShpOptions shp = new ShpOptions(input, null, null); @@ -43,7 +42,7 @@ public void readZip() { } @Test - public void all() { + void all() { // use same shape file as for land-use Path input = Path.of(utils.getClassInputDirectory() @@ -51,41 +50,38 @@ public void all() { .replace("options", "prepare")) .resolve("andorra-latest-free.shp.zip"); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); ShpOptions shp = new ShpOptions(input, null, null); ShpOptions.Index index = shp.createIndex(shp.getShapeCrs(), "_"); - List ft = index.getAll(); + List ft = index.getAllFeatures(); assertThat(ft) - .hasSize(578) + .hasSize(4906) .hasSize(Set.copyOf(ft).size()); + assertThat(shp.readFeatures()) + .hasSameElementsAs(ft); + } @Test - public void testGetGeometry() { + void testGetGeometry() { Path input = Path.of(utils.getClassInputDirectory() .replace("ShpOptionsTest", "CreateLandUseShpTest") .replace("options", "prepare")) .resolve("andorra-latest-free.shp.zip"); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); ShpOptions shp = new ShpOptions(input, null, null); Geometry geometry = shp.getGeometry() ; - Geometry expectedGeometry = new GeometryFactory().createEmpty(2); - - List features = shp.readFeatures(); - for(SimpleFeature feature : features) { - Geometry geometryToJoin = (Geometry) feature.getDefaultGeometry(); - expectedGeometry = expectedGeometry.union(geometryToJoin); - } + assertThat(geometry.getArea()) + .isCloseTo(1.9847543618489646E-4, Offset.offset(1e-8)); - Assert.assertTrue(geometry.equals(expectedGeometry)); } -} \ No newline at end of file +} diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/CreateLandUseShpTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/CreateLandUseShpTest.java index 7068b755e78..ca40a8f3057 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/CreateLandUseShpTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/CreateLandUseShpTest.java @@ -1,8 +1,8 @@ package org.matsim.application.prepare; -import org.junit.Assume; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; import java.nio.file.Files; @@ -12,15 +12,15 @@ public class CreateLandUseShpTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void convert() { + void convert() { Path input = Path.of(utils.getClassInputDirectory(), "andorra-latest-free.shp.zip"); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); Path output = Path.of(utils.getOutputDirectory(), "output.shp"); @@ -34,4 +34,4 @@ public void convert() { .isRegularFile(); } -} \ No newline at end of file +} diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/ShapeFileTextLookupTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/ShapeFileTextLookupTest.java index 02f1892fc47..74153b6ab75 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/ShapeFileTextLookupTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/ShapeFileTextLookupTest.java @@ -1,8 +1,8 @@ package org.matsim.application.prepare; -import org.junit.Assume; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; import picocli.CommandLine; @@ -14,15 +14,15 @@ public class ShapeFileTextLookupTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - @Test - public void main() { + @Test + void main() { Path input = Path.of(utils.getClassInputDirectory(), "verkehrszellen.csv"); Path output = Path.of(utils.getOutputDirectory(), "output.csv"); - Assume.assumeTrue(Files.exists(input)); + Assumptions.assumeTrue(Files.exists(input)); CommandLine cli = new CommandLine(new ShapeFileTextLookup()); int ret = cli.execute( @@ -40,4 +40,4 @@ public void main() { .exists(); } -} \ No newline at end of file +} diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/counts/CreateCountsFromBAStDataTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/counts/CreateCountsFromBAStDataTest.java index 96db8afa2ae..c74d59b7801 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/counts/CreateCountsFromBAStDataTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/counts/CreateCountsFromBAStDataTest.java @@ -1,29 +1,26 @@ package org.matsim.application.prepare.counts; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Link; import org.matsim.core.utils.io.IOUtils; -import org.matsim.counts.Count; -import org.matsim.counts.Counts; -import org.matsim.counts.CountsReaderMatsimV1; -import org.matsim.counts.MatsimCountsReader; +import org.matsim.counts.*; import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; + public class CreateCountsFromBAStDataTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - String carOutput = "car-test-counts.xml.gz"; - String freightOutput = "freight-test-counts.xml.gz"; + String countsOutput = "test-counts.xml.gz"; String ignoredCounts = "ignored.csv"; String manualMatchedCounts = "manual.csv"; @@ -39,72 +36,76 @@ public class CreateCountsFromBAStDataTest { String shpCrs = "EPSG:3857"; @Test - public void testCreateCountsFromBAStData(){ + void testCreateCountsFromBAStData() { String version = "normal-"; - String car = utils.getOutputDirectory() + version + carOutput; - String freight = utils.getOutputDirectory() + version + freightOutput; + String out = utils.getOutputDirectory() + version + countsOutput; String[] args = new String[]{ - "--station-data=" + utils.getPackageInputDirectory() + stationData, - "--network=" + network, - "--input-crs=" + networkCrs, - "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, - "--primary-data=" + utils.getPackageInputDirectory() + primaryData, - "--shp=" + utils.getPackageInputDirectory() + shp, - "--shp-crs=" + shpCrs, - "--year=2021", - "--car-output=" + car, - "--freight-output=" + freight + "--station-data=" + utils.getPackageInputDirectory() + stationData, + "--network=" + network, + "--input-crs=" + networkCrs, + "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, + "--primary-data=" + utils.getPackageInputDirectory() + primaryData, + "--shp=" + utils.getPackageInputDirectory() + shp, + "--shp-crs=" + shpCrs, + "--year=2021", + "--output=" + out, }; new CreateCountsFromBAStData().execute(args); Counts counts = new Counts<>(); - new MatsimCountsReader(counts).readFile(car); + new MatsimCountsReader(counts).readFile(out); - Integer size = counts.getCounts().size(); + assertThat(counts.getMeasureLocations()) + .hasSize(24); - assertThat(size).isGreaterThan(0); + assertThat(counts.getCounts()) + .hasSize(24); + + for (Map.Entry, MeasurementLocation> e : counts.getMeasureLocations().entrySet()) { + assertThat(e.getValue().hasMeasurableForMode(Measurable.VOLUMES, TransportMode.car)) + .isTrue(); + + assertThat(e.getValue().hasMeasurableForMode(Measurable.VOLUMES, TransportMode.truck)) + .isTrue(); + } } @Test - public void testWithIgnoredStations(){ + void testWithIgnoredStations() { String version = "with-ignored-"; - String car1 = utils.getOutputDirectory() + version + carOutput; - String freight1 = utils.getOutputDirectory() + version + freightOutput; + String out1 = utils.getOutputDirectory() + version + countsOutput; String[] args1 = new String[]{ - "--station-data=" + utils.getPackageInputDirectory() + stationData, - "--network=" + network, - "--input-crs=" + networkCrs, - "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, - "--primary-data=" + utils.getPackageInputDirectory() + primaryData, - "--shp=" + utils.getPackageInputDirectory() + shp, - "--shp-crs=" + shpCrs, - "--year=2021", - "--car-output=" + car1, - "--freight-output=" + freight1 + "--station-data=" + utils.getPackageInputDirectory() + stationData, + "--network=" + network, + "--input-crs=" + networkCrs, + "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, + "--primary-data=" + utils.getPackageInputDirectory() + primaryData, + "--shp=" + utils.getPackageInputDirectory() + shp, + "--shp-crs=" + shpCrs, + "--year=2021", + "--output=" + out1, }; new CreateCountsFromBAStData().execute(args1); - String car2 = utils.getOutputDirectory() + "without-ignored-" + carOutput; - String freight2 = utils.getOutputDirectory() + "without-ignored-" + freightOutput; + String out2 = utils.getOutputDirectory() + "without-ignored-" + countsOutput; String[] args2 = new String[]{ - "--station-data=" + utils.getPackageInputDirectory() + stationData, - "--network=" + network, - "--input-crs=" + networkCrs, - "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, - "--primary-data=" + utils.getPackageInputDirectory() + primaryData, - "--shp=" + utils.getPackageInputDirectory() + shp, - "--shp-crs=" + shpCrs, - "--year=2021", - "--car-output=" + car2, - "--freight-output=" + freight2, - "--ignored-counts=" + utils.getPackageInputDirectory() + ignoredCounts, + "--station-data=" + utils.getPackageInputDirectory() + stationData, + "--network=" + network, + "--input-crs=" + networkCrs, + "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, + "--primary-data=" + utils.getPackageInputDirectory() + primaryData, + "--shp=" + utils.getPackageInputDirectory() + shp, + "--shp-crs=" + shpCrs, + "--year=2021", + "--output=" + out2, + "--ignored-counts=" + utils.getPackageInputDirectory() + ignoredCounts, }; new CreateCountsFromBAStData().execute(args2); @@ -112,78 +113,74 @@ public void testWithIgnoredStations(){ Counts countsComplete = new Counts<>(); Counts countsWithoutIgnored = new Counts<>(); - new MatsimCountsReader(countsComplete).readFile(car1); - new MatsimCountsReader(countsWithoutIgnored).readFile(car2); + new MatsimCountsReader(countsComplete).readFile(out1); + new MatsimCountsReader(countsWithoutIgnored).readFile(out2); - int completeSize = countsComplete.getCounts().size(); - int ignoredSize = countsWithoutIgnored.getCounts().size(); + int completeSize = countsComplete.getMeasureLocations().size(); + int ignoredSize = countsWithoutIgnored.getMeasureLocations().size(); assertThat(completeSize).isGreaterThan(ignoredSize); } @Test - public void testManualMatchedCounts(){ + void testManualMatchedCounts() { - String car = utils.getOutputDirectory() + "manual-matched-" + carOutput; - String freight = utils.getOutputDirectory() + "manual-matched-" + freightOutput; + String out = utils.getOutputDirectory() + "manual-matched-" + countsOutput; //Map contains supposed matching from manual.csv Map, String> manual = Map.of(Id.createLinkId("4205"), "Neukölln_N", Id.createLinkId("4219"), "Neukölln_S"); String[] args = new String[]{ - "--station-data=" + utils.getPackageInputDirectory() + stationData, - "--network=" + network, - "--input-crs=" + networkCrs, - "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, - "--primary-data=" + utils.getPackageInputDirectory() + primaryData, - "--shp=" + utils.getPackageInputDirectory() + shp, - "--shp-crs=" + shpCrs, - "--year=2021", - "--car-output=" + car, - "--freight-output=" + freight, - "--manual-matched-counts=" + utils.getPackageInputDirectory() + manualMatchedCounts, + "--station-data=" + utils.getPackageInputDirectory() + stationData, + "--network=" + network, + "--input-crs=" + networkCrs, + "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, + "--primary-data=" + utils.getPackageInputDirectory() + primaryData, + "--shp=" + utils.getPackageInputDirectory() + shp, + "--shp-crs=" + shpCrs, + "--year=2021", + "--output=" + out, + "--manual-matched-counts=" + utils.getPackageInputDirectory() + manualMatchedCounts, }; new CreateCountsFromBAStData().execute(args); Counts countsWithManualMatched = new Counts<>(); - new CountsReaderMatsimV1(countsWithManualMatched).readFile(car); + new MatsimCountsReader(countsWithManualMatched).readFile(out); - var map = countsWithManualMatched.getCounts(); + var map = countsWithManualMatched.getMeasureLocations(); - for(var entry: manual.entrySet()){ + for (var entry : manual.entrySet()) { Id supposed = entry.getKey(); String station = entry.getValue(); - Count actual = map.get(supposed); - String actualStation = actual.getCsLabel(); + MeasurementLocation actual = map.get(supposed); + String actualStation = actual.getStationName(); - Assert.assertEquals(station, actualStation); + Assertions.assertEquals(station, actualStation); } } @Test - public void testManualMatchingWithWrongInput(){ + void testManualMatchingWithWrongInput() { - String car = utils.getOutputDirectory() + "manual-matched-" + carOutput; - String freight = utils.getOutputDirectory() + "manual-matched-" + freightOutput; + String out = utils.getOutputDirectory() + "manual-matched-" + countsOutput; String[] args = new String[]{ - "--station-data=" + utils.getPackageInputDirectory() + stationData, - "--network=" + network, - "--input-crs=" + networkCrs, - "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, - "--primary-data=" + utils.getPackageInputDirectory() + primaryData, - "--shp=" + utils.getPackageInputDirectory() + shp, - "--shp-crs=" + shpCrs, - "--year=2021", - "--car-output=" + car, - "--freight-output=" + freight, - "--manual-matched-counts=" + utils.getPackageInputDirectory() + wrongManualMatchedCounts, + "--station-data=" + utils.getPackageInputDirectory() + stationData, + "--network=" + network, + "--input-crs=" + networkCrs, + "--motorway-data=" + utils.getPackageInputDirectory() + motorwayData, + "--primary-data=" + utils.getPackageInputDirectory() + primaryData, + "--shp=" + utils.getPackageInputDirectory() + shp, + "--shp-crs=" + shpCrs, + "--year=2021", + "--output=" + out, + "--manual-matched-counts=" + utils.getPackageInputDirectory() + wrongManualMatchedCounts, }; - Assert.assertThrows(RuntimeException.class, () -> new CreateCountsFromBAStData().execute(args)); + Assertions.assertThrows(RuntimeException.class, () -> new CreateCountsFromBAStData().execute(args)); } } diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/counts/NetworkIndexTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/counts/NetworkIndexTest.java index a342fbac29c..74d0a5e356a 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/counts/NetworkIndexTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/counts/NetworkIndexTest.java @@ -2,7 +2,7 @@ import org.assertj.core.data.Offset; import org.geotools.geometry.jts.JTSFactoryFinder; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; @@ -11,7 +11,7 @@ public class NetworkIndexTest { @Test - public void angle() { + void angle() { GeometryFactory f = JTSFactoryFinder.getGeometryFactory(); diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/population/CloseTrajectoriesTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/population/CloseTrajectoriesTest.java index d8fb62a6e30..5c45ddefdb3 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/population/CloseTrajectoriesTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/population/CloseTrajectoriesTest.java @@ -1,8 +1,8 @@ package org.matsim.application.prepare.population; import org.assertj.core.api.Condition; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; @@ -17,11 +17,11 @@ public class CloseTrajectoriesTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void main() { + void main() { Path input = Path.of(utils.getPackageInputDirectory(), "persons.xml"); @@ -45,4 +45,4 @@ public void main() { } -} \ No newline at end of file +} diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/population/FixSubtourModesTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/population/FixSubtourModesTest.java index cbd4d0bd400..6f65537c5bf 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/population/FixSubtourModesTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/population/FixSubtourModesTest.java @@ -1,6 +1,6 @@ package org.matsim.application.prepare.population; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; @@ -19,7 +19,7 @@ public class FixSubtourModesTest { private PopulationFactory fact = PopulationUtils.getFactory(); @Test - public void unclosed() { + void unclosed() { Person person = fact.createPerson(Id.create("1000", Person.class)); final Plan plan = fact.createPlan(); @@ -43,7 +43,7 @@ public void unclosed() { } @Test - public void complex() { + void complex() { Person person = fact.createPerson(Id.create("1000", Person.class)); final Plan plan = fact.createPlan(); @@ -72,7 +72,7 @@ public void complex() { @Test - public void correct() { + void correct() { Person person = fact.createPerson(Id.create("1000", Person.class)); final Plan plan = fact.createPlan(); diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/population/SplitActivityTypesDurationTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/population/SplitActivityTypesDurationTest.java index c88c1f977eb..3c87f29a3c8 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/population/SplitActivityTypesDurationTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/population/SplitActivityTypesDurationTest.java @@ -1,8 +1,8 @@ package org.matsim.application.prepare.population; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; @@ -17,11 +17,11 @@ public class SplitActivityTypesDurationTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void split() { + void split() { Path input = Path.of(utils.getPackageInputDirectory(), "persons.xml"); diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfsTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfsTest.java index 9d0b2553537..5b3732f6347 100644 --- a/contribs/application/src/test/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfsTest.java +++ b/contribs/application/src/test/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfsTest.java @@ -1,8 +1,8 @@ package org.matsim.application.prepare.pt; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; @@ -12,11 +12,11 @@ public class CreateTransitScheduleFromGtfsTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void run() { + void run() { String input = utils.getClassInputDirectory(); String output = utils.getOutputDirectory(); diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSVTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSVTest.java index cca68b4d44b..1bcb22e6b80 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSVTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/CarrierReaderFromCSVTest.java @@ -9,20 +9,19 @@ import java.util.Map; import java.util.Set; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; 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.network.Network; import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.controler.FreightUtils; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freight.carrier.CarrierUtils; -import org.matsim.contrib.freight.carrier.CarrierVehicle; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; +import org.matsim.freight.carriers.CarriersUtils; +import org.matsim.freight.carriers.CarrierVehicle; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.network.NetworkUtils; @@ -40,18 +39,18 @@ */ public class CarrierReaderFromCSVTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void carrierCreation() throws IOException { + void carrierCreation() throws IOException { Config config = ConfigUtils.createConfig(); config.network().setInputFile( "https://raw.githubusercontent.com/matsim-org/matsim/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); Scenario scenario = ScenarioUtils.loadScenario(config); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), - FreightConfigGroup.class); - freightConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); @@ -59,160 +58,160 @@ public void carrierCreation() throws IOException { Set allNewCarrierInformation = CarrierReaderFromCSV .readCarrierInformation(carrierCSVLocation); String shapeCategory = "Ortsteil"; - CarrierReaderFromCSV.checkNewCarrier(allNewCarrierInformation, freightConfigGroup, scenario, polygonsInShape, shapeCategory); - CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightConfigGroup, + CarrierReaderFromCSV.checkNewCarrier(allNewCarrierInformation, freightCarriersConfigGroup, scenario, polygonsInShape, shapeCategory); + CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, polygonsInShape, 1, null); - Assert.assertEquals(3, FreightUtils.getCarriers(scenario).getCarriers().size()); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + 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))); // check carrier 1 - Carrier testCarrier1 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier1", Carrier.class)); - Assert.assertEquals(FleetSize.INFINITE, testCarrier1.getCarrierCapabilities().getFleetSize()); - Assert.assertEquals(10, CarrierUtils.getJspritIterations(testCarrier1)); - Assert.assertEquals(4, testCarrier1.getCarrierCapabilities().getCarrierVehicles().size()); + Assertions.assertEquals(FleetSize.INFINITE, testCarrier1.getCarrierCapabilities().getFleetSize()); + Assertions.assertEquals(10, CarriersUtils.getJspritIterations(testCarrier1)); + Assertions.assertEquals(4, testCarrier1.getCarrierCapabilities().getCarrierVehicles().size()); Object2IntMap depotSums = new Object2IntOpenHashMap<>(); Map> typesPerDepot = new HashMap<>(); for (CarrierVehicle carrierVehicle : testCarrier1.getCarrierCapabilities().getCarrierVehicles().values()) { typesPerDepot.computeIfAbsent(carrierVehicle.getLinkId().toString(), ( k) -> new ArrayList<>() ) .add(carrierVehicle.getVehicleTypeId().toString()); depotSums.merge(carrierVehicle.getLinkId().toString(), 1, Integer::sum ); - Assert.assertEquals(3600, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(50000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3600, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(50000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); } - Assert.assertEquals(2, depotSums.size()); - Assert.assertTrue(depotSums.containsKey("i(2,0)")); - Assert.assertEquals(2, depotSums.getInt("i(2,0)")); - Assert.assertTrue(depotSums.containsKey("j(2,4)R")); - Assert.assertEquals(2, depotSums.getInt("j(2,4)R")); - Assert.assertEquals(2, typesPerDepot.size()); - Assert.assertTrue(typesPerDepot.containsKey("i(2,0)")); - Assert.assertEquals(2, typesPerDepot.get("i(2,0)").size()); - Assert.assertTrue(typesPerDepot.get("i(2,0)").contains("testVehicle1")); - Assert.assertTrue(typesPerDepot.get("i(2,0)").contains("testVehicle2")); - Assert.assertTrue(typesPerDepot.containsKey("j(2,4)R")); - Assert.assertEquals(2, typesPerDepot.get("j(2,4)R").size()); - Assert.assertTrue(typesPerDepot.get("j(2,4)R").contains("testVehicle1")); - Assert.assertTrue(typesPerDepot.get("j(2,4)R").contains("testVehicle2")); + Assertions.assertEquals(2, depotSums.size()); + Assertions.assertTrue(depotSums.containsKey("i(2,0)")); + Assertions.assertEquals(2, depotSums.getInt("i(2,0)")); + Assertions.assertTrue(depotSums.containsKey("j(2,4)R")); + Assertions.assertEquals(2, depotSums.getInt("j(2,4)R")); + Assertions.assertEquals(2, typesPerDepot.size()); + Assertions.assertTrue(typesPerDepot.containsKey("i(2,0)")); + Assertions.assertEquals(2, typesPerDepot.get("i(2,0)").size()); + Assertions.assertTrue(typesPerDepot.get("i(2,0)").contains("testVehicle1")); + Assertions.assertTrue(typesPerDepot.get("i(2,0)").contains("testVehicle2")); + Assertions.assertTrue(typesPerDepot.containsKey("j(2,4)R")); + Assertions.assertEquals(2, typesPerDepot.get("j(2,4)R").size()); + Assertions.assertTrue(typesPerDepot.get("j(2,4)R").contains("testVehicle1")); + Assertions.assertTrue(typesPerDepot.get("j(2,4)R").contains("testVehicle2")); // check carrier 2 - Carrier testCarrier2 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier2", Carrier.class)); - Assert.assertEquals(FleetSize.FINITE, testCarrier2.getCarrierCapabilities().getFleetSize()); - Assert.assertEquals(15, CarrierUtils.getJspritIterations(testCarrier2)); - Assert.assertEquals(9, testCarrier2.getCarrierCapabilities().getCarrierVehicles().size()); + Assertions.assertEquals(FleetSize.FINITE, testCarrier2.getCarrierCapabilities().getFleetSize()); + Assertions.assertEquals(15, CarriersUtils.getJspritIterations(testCarrier2)); + Assertions.assertEquals(9, testCarrier2.getCarrierCapabilities().getCarrierVehicles().size()); depotSums = new Object2IntOpenHashMap<>(); typesPerDepot = new HashMap<>(); for (CarrierVehicle carrierVehicle : testCarrier2.getCarrierCapabilities().getCarrierVehicles().values()) { typesPerDepot.computeIfAbsent(carrierVehicle.getLinkId().toString(), ( k) -> new ArrayList<>() ) .add(carrierVehicle.getVehicleTypeId().toString()); depotSums.merge(carrierVehicle.getLinkId().toString(), 1, Integer::sum ); - Assert.assertEquals(3600, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(50000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3600, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(50000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); } - Assert.assertEquals(3, depotSums.size()); - Assert.assertTrue(depotSums.containsKey("j(4,3)R")); - Assert.assertEquals(3, depotSums.getInt("j(4,3)R")); - Assert.assertEquals(3, typesPerDepot.size()); - Assert.assertTrue(typesPerDepot.containsKey("j(4,3)R")); - Assert.assertEquals(3, typesPerDepot.get("j(4,3)R").size()); - Assert.assertTrue(typesPerDepot.get("j(4,3)R").contains("testVehicle2")); + Assertions.assertEquals(3, depotSums.size()); + Assertions.assertTrue(depotSums.containsKey("j(4,3)R")); + Assertions.assertEquals(3, depotSums.getInt("j(4,3)R")); + Assertions.assertEquals(3, typesPerDepot.size()); + Assertions.assertTrue(typesPerDepot.containsKey("j(4,3)R")); + Assertions.assertEquals(3, typesPerDepot.get("j(4,3)R").size()); + Assertions.assertTrue(typesPerDepot.get("j(4,3)R").contains("testVehicle2")); // check carrier 3 Network network = NetworkUtils.readNetwork( "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); - Carrier testCarrier3 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier3", Carrier.class)); - Assert.assertEquals(FleetSize.INFINITE, testCarrier3.getCarrierCapabilities().getFleetSize()); - Assert.assertEquals(1, CarrierUtils.getJspritIterations(testCarrier3)); - Assert.assertEquals(2, testCarrier3.getCarrierCapabilities().getCarrierVehicles().size()); + Assertions.assertEquals(FleetSize.INFINITE, testCarrier3.getCarrierCapabilities().getFleetSize()); + Assertions.assertEquals(1, CarriersUtils.getJspritIterations(testCarrier3)); + Assertions.assertEquals(2, testCarrier3.getCarrierCapabilities().getCarrierVehicles().size()); depotSums = new Object2IntOpenHashMap<>(); typesPerDepot = new HashMap<>(); for (CarrierVehicle carrierVehicle : testCarrier3.getCarrierCapabilities().getCarrierVehicles().values()) { typesPerDepot.computeIfAbsent(carrierVehicle.getLinkId().toString(), ( k) -> new ArrayList<>() ) .add(carrierVehicle.getVehicleTypeId().toString()); depotSums.merge(carrierVehicle.getLinkId().toString(), 1, Integer::sum ); - Assert.assertEquals(50000, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(80000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(50000, carrierVehicle.getEarliestStartTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(80000, carrierVehicle.getLatestEndTime(), MatsimTestUtils.EPSILON); } - Assert.assertEquals(2, depotSums.size()); - Assert.assertTrue(depotSums.containsKey("j(2,6)R")); - Assert.assertEquals(1, depotSums.getInt("j(2,6)R")); + Assertions.assertEquals(2, depotSums.size()); + Assertions.assertTrue(depotSums.containsKey("j(2,6)R")); + Assertions.assertEquals(1, depotSums.getInt("j(2,6)R")); for (String depot : depotSums.keySet()) { if (!depot.equals("j(2,6)R")) { Link link = network.getLinks().get(Id.createLinkId(depot)); - Assert.assertTrue( + Assertions.assertTrue( FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); } } - Assert.assertEquals(2, typesPerDepot.size()); - Assert.assertTrue(typesPerDepot.containsKey("j(2,6)R")); - Assert.assertEquals(1, typesPerDepot.get("j(2,6)R").size()); - Assert.assertTrue(typesPerDepot.get("j(2,6)R").contains("testVehicle1")); + Assertions.assertEquals(2, typesPerDepot.size()); + Assertions.assertTrue(typesPerDepot.containsKey("j(2,6)R")); + Assertions.assertEquals(1, typesPerDepot.get("j(2,6)R").size()); + Assertions.assertTrue(typesPerDepot.get("j(2,6)R").contains("testVehicle1")); } @Test - public void csvCarrierReader() throws IOException { + void csvCarrierReader() throws IOException { Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); Set allNewCarrierInformation = CarrierReaderFromCSV .readCarrierInformation(carrierCSVLocation); - Assert.assertEquals(3, allNewCarrierInformation.size()); + Assertions.assertEquals(3, allNewCarrierInformation.size()); for (CarrierInformationElement carrierInformationElement : allNewCarrierInformation) { if (carrierInformationElement.getName().equals("testCarrier1")) { - Assert.assertNull(carrierInformationElement.getAreaOfAdditionalDepots()); - Assert.assertEquals(0, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); - Assert.assertEquals(FleetSize.INFINITE, carrierInformationElement.getFleetSize()); - Assert.assertEquals(10, carrierInformationElement.getJspritIterations()); - Assert.assertEquals(2, carrierInformationElement.getNumberOfDepotsPerType()); - Assert.assertEquals(3600, carrierInformationElement.getVehicleStartTime()); - Assert.assertEquals(50000, carrierInformationElement.getVehicleEndTime()); - Assert.assertEquals(2, carrierInformationElement.getVehicleDepots().size()); - Assert.assertTrue(carrierInformationElement.getVehicleDepots().contains("i(2,0)") + Assertions.assertNull(carrierInformationElement.getAreaOfAdditionalDepots()); + Assertions.assertEquals(0, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); + Assertions.assertEquals(FleetSize.INFINITE, carrierInformationElement.getFleetSize()); + Assertions.assertEquals(10, carrierInformationElement.getJspritIterations()); + Assertions.assertEquals(2, carrierInformationElement.getNumberOfDepotsPerType()); + Assertions.assertEquals(3600, carrierInformationElement.getVehicleStartTime()); + Assertions.assertEquals(50000, carrierInformationElement.getVehicleEndTime()); + Assertions.assertEquals(2, carrierInformationElement.getVehicleDepots().size()); + Assertions.assertTrue(carrierInformationElement.getVehicleDepots().contains("i(2,0)") && carrierInformationElement.getVehicleDepots().contains("j(2,4)R")); - Assert.assertEquals(2, carrierInformationElement.getVehicleTypes().length); - Assert.assertTrue(carrierInformationElement.getVehicleTypes()[0].equals("testVehicle1") + Assertions.assertEquals(2, carrierInformationElement.getVehicleTypes().length); + Assertions.assertTrue(carrierInformationElement.getVehicleTypes()[0].equals("testVehicle1") || carrierInformationElement.getVehicleTypes()[0].equals("testVehicle2")); - Assert.assertNotEquals(carrierInformationElement.getVehicleTypes()[0], carrierInformationElement.getVehicleTypes()[1]); + Assertions.assertNotEquals(carrierInformationElement.getVehicleTypes()[0], carrierInformationElement.getVehicleTypes()[1]); } else if (carrierInformationElement.getName().equals("testCarrier3")) { - Assert.assertEquals(1, carrierInformationElement.getAreaOfAdditionalDepots().length); - Assert.assertEquals("area1", carrierInformationElement.getAreaOfAdditionalDepots()[0]); - Assert.assertEquals(0, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); - Assert.assertEquals(FleetSize.INFINITE, carrierInformationElement.getFleetSize()); - Assert.assertEquals(0, carrierInformationElement.getJspritIterations()); - Assert.assertEquals(2, carrierInformationElement.getNumberOfDepotsPerType()); - Assert.assertEquals(50000, carrierInformationElement.getVehicleStartTime()); - Assert.assertEquals(80000, carrierInformationElement.getVehicleEndTime()); - Assert.assertEquals(1, carrierInformationElement.getVehicleDepots().size()); - Assert.assertEquals("j(2,6)R", carrierInformationElement.getVehicleDepots().get(0)); - Assert.assertEquals(1, carrierInformationElement.getVehicleTypes().length); - Assert.assertEquals("testVehicle1", carrierInformationElement.getVehicleTypes()[0]); + Assertions.assertEquals(1, carrierInformationElement.getAreaOfAdditionalDepots().length); + Assertions.assertEquals("area1", carrierInformationElement.getAreaOfAdditionalDepots()[0]); + Assertions.assertEquals(0, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); + Assertions.assertEquals(FleetSize.INFINITE, carrierInformationElement.getFleetSize()); + Assertions.assertEquals(0, carrierInformationElement.getJspritIterations()); + Assertions.assertEquals(2, carrierInformationElement.getNumberOfDepotsPerType()); + Assertions.assertEquals(50000, carrierInformationElement.getVehicleStartTime()); + Assertions.assertEquals(80000, carrierInformationElement.getVehicleEndTime()); + Assertions.assertEquals(1, carrierInformationElement.getVehicleDepots().size()); + Assertions.assertEquals("j(2,6)R", carrierInformationElement.getVehicleDepots().get(0)); + Assertions.assertEquals(1, carrierInformationElement.getVehicleTypes().length); + Assertions.assertEquals("testVehicle1", carrierInformationElement.getVehicleTypes()[0]); } else if (carrierInformationElement.getName().equals("testCarrier2")) { - Assert.assertNull(carrierInformationElement.getAreaOfAdditionalDepots()); - Assert.assertEquals(3, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); - Assert.assertEquals(FleetSize.FINITE, carrierInformationElement.getFleetSize()); - Assert.assertEquals(15, carrierInformationElement.getJspritIterations()); - Assert.assertEquals(3, carrierInformationElement.getNumberOfDepotsPerType()); - Assert.assertEquals(3600, carrierInformationElement.getVehicleStartTime()); - Assert.assertEquals(50000, carrierInformationElement.getVehicleEndTime()); - Assert.assertEquals(1, carrierInformationElement.getVehicleDepots().size()); - Assert.assertEquals("j(4,3)R", carrierInformationElement.getVehicleDepots().get(0)); - Assert.assertEquals(1, carrierInformationElement.getVehicleTypes().length); - Assert.assertEquals("testVehicle2", carrierInformationElement.getVehicleTypes()[0]); + Assertions.assertNull(carrierInformationElement.getAreaOfAdditionalDepots()); + Assertions.assertEquals(3, carrierInformationElement.getFixedNumberOfVehiclePerTypeAndLocation()); + Assertions.assertEquals(FleetSize.FINITE, carrierInformationElement.getFleetSize()); + Assertions.assertEquals(15, carrierInformationElement.getJspritIterations()); + Assertions.assertEquals(3, carrierInformationElement.getNumberOfDepotsPerType()); + Assertions.assertEquals(3600, carrierInformationElement.getVehicleStartTime()); + Assertions.assertEquals(50000, carrierInformationElement.getVehicleEndTime()); + Assertions.assertEquals(1, carrierInformationElement.getVehicleDepots().size()); + Assertions.assertEquals("j(4,3)R", carrierInformationElement.getVehicleDepots().get(0)); + Assertions.assertEquals(1, carrierInformationElement.getVehicleTypes().length); + Assertions.assertEquals("testVehicle2", carrierInformationElement.getVehicleTypes()[0]); } else { - Assert.fail("No expected carrierInformationElement found"); + Assertions.fail("No expected carrierInformationElement found"); } } 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 fdc2aa30d12..da396bb7a9e 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java @@ -8,9 +8,9 @@ import java.util.Map; import java.util.Set; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -18,12 +18,7 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierService; -import org.matsim.contrib.freight.carrier.CarrierShipment; -import org.matsim.contrib.freight.carrier.TimeWindow; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.*; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.network.NetworkUtils; @@ -42,11 +37,11 @@ * */ public class DemandReaderFromCSVTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testLinkForPerson() throws IOException { + void testLinkForPerson() throws IOException { Config config = ConfigUtils.createConfig(); config.network().setInputFile( "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); @@ -58,29 +53,29 @@ public void testLinkForPerson() throws IOException { for (Person person : population.getPersons().values()) { DemandReaderFromCSV.findLinksForPersons(scenario, nearestLinkPerPerson, person); } - Assert.assertEquals("j(1,8)",nearestLinkPerPerson.get(Id.createPersonId("person1")).values().iterator().next()); - Assert.assertEquals("j(3,3)",nearestLinkPerPerson.get(Id.createPersonId("person2")).values().iterator().next()); - Assert.assertEquals("j(4,5)R",nearestLinkPerPerson.get(Id.createPersonId("person3")).values().iterator().next()); - Assert.assertEquals("j(5,3)",nearestLinkPerPerson.get(Id.createPersonId("person4")).values().iterator().next()); - Assert.assertEquals("j(5,6)",nearestLinkPerPerson.get(Id.createPersonId("person5")).values().iterator().next()); - Assert.assertEquals("j(8,8)R",nearestLinkPerPerson.get(Id.createPersonId("person6")).values().iterator().next()); - Assert.assertEquals("i(5,9)R",nearestLinkPerPerson.get(Id.createPersonId("person7")).values().iterator().next()); - Assert.assertEquals("i(9,5)R",nearestLinkPerPerson.get(Id.createPersonId("person8")).values().iterator().next()); + Assertions.assertEquals("j(1,8)",nearestLinkPerPerson.get(Id.createPersonId("person1")).values().iterator().next()); + Assertions.assertEquals("j(3,3)",nearestLinkPerPerson.get(Id.createPersonId("person2")).values().iterator().next()); + Assertions.assertEquals("j(4,5)R",nearestLinkPerPerson.get(Id.createPersonId("person3")).values().iterator().next()); + Assertions.assertEquals("j(5,3)",nearestLinkPerPerson.get(Id.createPersonId("person4")).values().iterator().next()); + Assertions.assertEquals("j(5,6)",nearestLinkPerPerson.get(Id.createPersonId("person5")).values().iterator().next()); + Assertions.assertEquals("j(8,8)R",nearestLinkPerPerson.get(Id.createPersonId("person6")).values().iterator().next()); + Assertions.assertEquals("i(5,9)R",nearestLinkPerPerson.get(Id.createPersonId("person7")).values().iterator().next()); + Assertions.assertEquals("i(9,5)R",nearestLinkPerPerson.get(Id.createPersonId("person8")).values().iterator().next()); } @Test - public void demandCreation() throws IOException { + void demandCreation() 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); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), - FreightConfigGroup.class); - freightConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + 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"); String shapeCategory = "Ortsteil"; @@ -94,27 +89,27 @@ public void demandCreation() throws IOException { // run methods Set allNewCarrierInformation = CarrierReaderFromCSV .readCarrierInformation(carrierCSVLocation); - CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightConfigGroup, + CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, polygonsInShape, 1, null); Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, polygonsInShape, shapeCategory); DemandReaderFromCSV.createDemandForCarriers(scenario, polygonsInShape, demandInformation, population, false, null); - Assert.assertEquals(3, FreightUtils.getCarriers(scenario).getCarriers().size()); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); - Assert.assertTrue( - FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + 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))); // 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 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier1", Carrier.class)); - Assert.assertEquals(14, testCarrier1.getServices().size()); - Assert.assertEquals(0, testCarrier1.getShipments().size()); + Assertions.assertEquals(14, testCarrier1.getServices().size()); + Assertions.assertEquals(0, testCarrier1.getShipments().size()); Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>(); Map> locationsPerServiceElement = new HashMap<>(); int countDemand = 0; @@ -122,45 +117,45 @@ public void demandCreation() throws IOException { countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum); countDemand = countDemand + service.getCapacityDemand(); if (service.getCapacityDemand() == 0) { - Assert.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow()); + 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) { - Assert.assertEquals(100, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + 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) { - Assert.assertEquals(200, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + 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 - Assert.fail("Service has a wrong demand."); + Assertions.fail("Service has a wrong demand."); } - Assert.assertEquals(12, countDemand); - Assert.assertEquals(4, countServicesWithCertainDemand.getInt(0)); - Assert.assertEquals(8, countServicesWithCertainDemand.getInt(1)); - Assert.assertEquals(2, countServicesWithCertainDemand.getInt(2)); - Assert.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size()); + 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)); - Assert.assertTrue( + Assertions.assertTrue( FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[] { "area1" }, null)); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[] { "area2" }, null)); } - Assert.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); - Assert.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); + Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); + Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); // check carrier 2 - Carrier testCarrier2 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier2", Carrier.class)); - Assert.assertEquals(0, testCarrier2.getServices().size()); - Assert.assertEquals(11, testCarrier2.getShipments().size()); + Assertions.assertEquals(0, testCarrier2.getServices().size()); + Assertions.assertEquals(11, testCarrier2.getShipments().size()); Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); Map> locationsPerShipmentElement = new HashMap<>(); countDemand = 0; @@ -168,181 +163,181 @@ public void demandCreation() throws IOException { countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); countDemand = countDemand + shipment.getSize(); if (shipment.getSize() == 0) { - Assert.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow()); - Assert.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow()); + 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) { - Assert.assertEquals(400, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(400, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assert.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + 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) { - Assert.assertEquals(600, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(600, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assert.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + 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 - Assert.fail("Shipment has an unexpected demand."); + Assertions.fail("Shipment has an unexpected demand."); } - Assert.assertEquals(15, countDemand); - Assert.assertEquals(4, countShipmentsWithCertainDemand.getInt(0)); - Assert.assertEquals(6, countShipmentsWithCertainDemand.getInt(2)); - Assert.assertEquals(1, countShipmentsWithCertainDemand.getInt(3)); - Assert.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assert.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); - Assert.assertTrue(locationsPerShipmentElement.get("ShipmenElement1_delivery").contains("i(2,0)")); - Assert.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement2_pickup").size()); - Assert.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement2_delivery").size()); + 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()); // check carrier 3 - Carrier testCarrier3 = FreightUtils.getCarriers(scenario).getCarriers() + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create("testCarrier3", Carrier.class)); - Assert.assertEquals(0, testCarrier3.getServices().size()); - Assert.assertEquals(4, testCarrier3.getShipments().size()); + Assertions.assertEquals(0, testCarrier3.getServices().size()); + Assertions.assertEquals(4, 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(); - Assert.assertEquals(5, shipment.getSize()); - Assert.assertEquals(2000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1250, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assert.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); - Assert.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); + Assertions.assertEquals(5, shipment.getSize()); + Assertions.assertEquals(2000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + 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<>()) .add(shipment.getFrom().toString()); locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_delivery", (k) -> new HashSet<>()) .add(shipment.getTo().toString()); } - Assert.assertEquals(20, countDemand); - Assert.assertEquals(4, countShipmentsWithCertainDemand.getInt(5)); - Assert.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assert.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); + 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")) { Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); - Assert.assertTrue( + Assertions.assertTrue( FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[] { "area1" }, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[] { "area2" }, null)); } } @Test - public void csvDemandReader() throws IOException { + void csvDemandReader() throws IOException { Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv"); Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); - Assert.assertEquals(5, demandInformation.size()); + Assertions.assertEquals(5, demandInformation.size()); for (DemandInformationElement demandInformationElement : demandInformation) { if (demandInformationElement.getCarrierName().equals("testCarrier1") && demandInformationElement.getNumberOfJobs() == 4) { - Assert.assertEquals(0, (int) demandInformationElement.getDemandToDistribute()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); - Assert.assertEquals(1, demandInformationElement.getAreasFirstJobElement().length); - Assert.assertEquals("area2", demandInformationElement.getAreasFirstJobElement()[0]); - Assert.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); - Assert.assertEquals(180, (int) demandInformationElement.getFirstJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(3000, 13000), + Assertions.assertEquals(0, (int) demandInformationElement.getDemandToDistribute()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); + Assertions.assertEquals(1, demandInformationElement.getAreasFirstJobElement().length); + Assertions.assertEquals("area2", demandInformationElement.getAreasFirstJobElement()[0]); + Assertions.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); + Assertions.assertEquals(180, (int) demandInformationElement.getFirstJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), demandInformationElement.getFirstJobElementTimeWindow()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); - Assert.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); - Assert.assertNull(demandInformationElement.getSecondJobElementTimePerUnit()); - Assert.assertNull(demandInformationElement.getSecondJobElementTimeWindow()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); + Assertions.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); + Assertions.assertNull(demandInformationElement.getSecondJobElementTimePerUnit()); + Assertions.assertNull(demandInformationElement.getSecondJobElementTimeWindow()); } else if (demandInformationElement.getCarrierName().equals("testCarrier1") && demandInformationElement.getNumberOfJobs() == 10) { - Assert.assertEquals(12, (int) demandInformationElement.getDemandToDistribute()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); - Assert.assertNull(demandInformationElement.getAreasFirstJobElement()); - Assert.assertEquals(4, (int) demandInformationElement.getNumberOfFirstJobElementLocations()); - Assert.assertEquals(1, demandInformationElement.getLocationsOfFirstJobElement().length); - Assert.assertEquals("i(2,0)", demandInformationElement.getLocationsOfFirstJobElement()[0]); - Assert.assertEquals(100, (int) demandInformationElement.getFirstJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(5000, 20000), + Assertions.assertEquals(12, (int) demandInformationElement.getDemandToDistribute()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); + Assertions.assertNull(demandInformationElement.getAreasFirstJobElement()); + Assertions.assertEquals(4, (int) demandInformationElement.getNumberOfFirstJobElementLocations()); + Assertions.assertEquals(1, demandInformationElement.getLocationsOfFirstJobElement().length); + Assertions.assertEquals("i(2,0)", demandInformationElement.getLocationsOfFirstJobElement()[0]); + Assertions.assertEquals(100, (int) demandInformationElement.getFirstJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), demandInformationElement.getFirstJobElementTimeWindow()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); - Assert.assertNull(demandInformationElement.getAreasSecondJobElement()); - Assert.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); - Assert.assertNull(demandInformationElement.getSecondJobElementTimePerUnit()); - Assert.assertNull(demandInformationElement.getSecondJobElementTimeWindow()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); + Assertions.assertNull(demandInformationElement.getAreasSecondJobElement()); + Assertions.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); + Assertions.assertNull(demandInformationElement.getSecondJobElementTimePerUnit()); + Assertions.assertNull(demandInformationElement.getSecondJobElementTimeWindow()); } else if (demandInformationElement.getCarrierName().equals("testCarrier2") && demandInformationElement.getDemandToDistribute() == 0) { - Assert.assertEquals(0, (int) demandInformationElement.getDemandToDistribute()); - Assert.assertEquals(4, (int) demandInformationElement.getNumberOfJobs()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); - Assert.assertNull(demandInformationElement.getAreasFirstJobElement()); - Assert.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); - Assert.assertEquals(300, (int) demandInformationElement.getFirstJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(10000, 45000), + Assertions.assertEquals(0, (int) demandInformationElement.getDemandToDistribute()); + Assertions.assertEquals(4, (int) demandInformationElement.getNumberOfJobs()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); + Assertions.assertNull(demandInformationElement.getAreasFirstJobElement()); + Assertions.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); + Assertions.assertEquals(300, (int) demandInformationElement.getFirstJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), demandInformationElement.getFirstJobElementTimeWindow()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); - Assert.assertNull(demandInformationElement.getAreasSecondJobElement()); - Assert.assertEquals(1, (int) demandInformationElement.getNumberOfSecondJobElementLocations()); - Assert.assertEquals(1, demandInformationElement.getLocationsOfSecondJobElement().length); - Assert.assertTrue(demandInformationElement.getLocationsOfSecondJobElement()[0].equals("i(2,0)")); - Assert.assertEquals(350, (int) demandInformationElement.getSecondJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(11000, 44000), + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); + Assertions.assertNull(demandInformationElement.getAreasSecondJobElement()); + Assertions.assertEquals(1, (int) demandInformationElement.getNumberOfSecondJobElementLocations()); + Assertions.assertEquals(1, demandInformationElement.getLocationsOfSecondJobElement().length); + Assertions.assertTrue(demandInformationElement.getLocationsOfSecondJobElement()[0].equals("i(2,0)")); + Assertions.assertEquals(350, (int) demandInformationElement.getSecondJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), demandInformationElement.getSecondJobElementTimeWindow()); } else if (demandInformationElement.getCarrierName().equals("testCarrier2") && demandInformationElement.getDemandToDistribute() == 15) { - Assert.assertEquals(15, (int) demandInformationElement.getDemandToDistribute()); - Assert.assertEquals(7, (int) demandInformationElement.getNumberOfJobs()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); - Assert.assertNull(demandInformationElement.getAreasFirstJobElement()); - Assert.assertEquals(1, (int) demandInformationElement.getNumberOfFirstJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); - Assert.assertEquals(200, (int) demandInformationElement.getFirstJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(11000, 44000), + Assertions.assertEquals(15, (int) demandInformationElement.getDemandToDistribute()); + Assertions.assertEquals(7, (int) demandInformationElement.getNumberOfJobs()); + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithFirstJobElement()); + Assertions.assertNull(demandInformationElement.getAreasFirstJobElement()); + Assertions.assertEquals(1, (int) demandInformationElement.getNumberOfFirstJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); + Assertions.assertEquals(200, (int) demandInformationElement.getFirstJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), demandInformationElement.getFirstJobElementTimeWindow()); - Assert.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); - Assert.assertNull(demandInformationElement.getAreasSecondJobElement()); - Assert.assertEquals(2, (int) demandInformationElement.getNumberOfSecondJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); - Assert.assertEquals(200, (int) demandInformationElement.getSecondJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(20000, 40000), + Assertions.assertNull(demandInformationElement.getShareOfPopulationWithSecondJobElement()); + Assertions.assertNull(demandInformationElement.getAreasSecondJobElement()); + Assertions.assertEquals(2, (int) demandInformationElement.getNumberOfSecondJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); + Assertions.assertEquals(200, (int) demandInformationElement.getSecondJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), demandInformationElement.getSecondJobElementTimeWindow()); } else if (demandInformationElement.getCarrierName().equals("testCarrier3")) { - Assert.assertEquals(20, (int) demandInformationElement.getDemandToDistribute()); - Assert.assertNull(demandInformationElement.getNumberOfJobs()); - Assert.assertEquals(0.125, (double) demandInformationElement.getShareOfPopulationWithFirstJobElement(), + Assertions.assertEquals(20, (int) demandInformationElement.getDemandToDistribute()); + Assertions.assertNull(demandInformationElement.getNumberOfJobs()); + Assertions.assertEquals(0.125, (double) demandInformationElement.getShareOfPopulationWithFirstJobElement(), MatsimTestUtils.EPSILON); - Assert.assertNull(demandInformationElement.getAreasFirstJobElement()); - Assert.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); - Assert.assertEquals(400, (int) demandInformationElement.getFirstJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(8000, 50000), + Assertions.assertNull(demandInformationElement.getAreasFirstJobElement()); + Assertions.assertNull(demandInformationElement.getNumberOfFirstJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfFirstJobElement()); + Assertions.assertEquals(400, (int) demandInformationElement.getFirstJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), demandInformationElement.getFirstJobElementTimeWindow()); - Assert.assertEquals(0.4, (double) demandInformationElement.getShareOfPopulationWithSecondJobElement(), + Assertions.assertEquals(0.4, (double) demandInformationElement.getShareOfPopulationWithSecondJobElement(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, demandInformationElement.getAreasSecondJobElement().length); - Assert.assertEquals("area1", demandInformationElement.getAreasSecondJobElement()[0]); - Assert.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); - Assert.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); - Assert.assertEquals(250, (int) demandInformationElement.getSecondJobElementTimePerUnit()); - Assert.assertEquals(TimeWindow.newInstance(10000, 60000), + Assertions.assertEquals(1, demandInformationElement.getAreasSecondJobElement().length); + Assertions.assertEquals("area1", demandInformationElement.getAreasSecondJobElement()[0]); + Assertions.assertNull(demandInformationElement.getNumberOfSecondJobElementLocations()); + Assertions.assertNull(demandInformationElement.getLocationsOfSecondJobElement()); + Assertions.assertEquals(250, (int) demandInformationElement.getSecondJobElementTimePerUnit()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), demandInformationElement.getSecondJobElementTimeWindow()); } else - Assert.fail("No expected demandInformationElement found"); + Assertions.fail("No expected demandInformationElement found"); } } } diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationTest.java index 82ee3fc674a..a79ca63b52d 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationTest.java @@ -1,9 +1,9 @@ package org.matsim.freightDemandGeneration; import org.apache.logging.log4j.LogManager; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; import java.nio.file.Path; @@ -15,11 +15,11 @@ */ public class FreightDemandGenerationTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testMain() { + void testMain() { try { Path output = Path.of(utils.getOutputDirectory()); Path vehicleFilePath = Path.of(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); @@ -57,7 +57,7 @@ public void testMain() { LogManager.getLogger(this.getClass()).fatal("there was an exception: \n" + ee); ee.printStackTrace(); // if one catches an exception, then one needs to explicitly fail the test: - Assert.fail(); + Assertions.fail(); } } } diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtilsTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtilsTest.java index c8dbaeff5df..e1528caf871 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtilsTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtilsTest.java @@ -3,9 +3,9 @@ import java.nio.file.Path; import java.util.Collection; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.locationtech.jts.geom.Point; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; @@ -18,81 +18,83 @@ import org.matsim.core.population.PopulationUtils; import org.matsim.core.utils.geometry.geotools.MGC; import org.matsim.testcases.MatsimTestUtils; -import org.opengis.feature.simple.SimpleFeature; - +import org.opengis.feature.simple.SimpleFeature; + /** * @author Ricardo Ewert * */ public class FreightDemandGenerationUtilsTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); - - @Test - public void testPreparePopulation() { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void testPreparePopulation() { String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; Population population = PopulationUtils.readPopulation(populationLocation); FreightDemandGenerationUtils.preparePopulation(population, 1.0, 1.0, "changeNumberOfLocationsWithDemand"); - Assert.assertEquals(8, population.getPersons().size()); - Assert.assertEquals(1.0,population.getAttributes().getAttribute("sampleSize")); - Assert.assertEquals(1.0,population.getAttributes().getAttribute("samplingTo")); - Assert.assertEquals("changeNumberOfLocationsWithDemand",population.getAttributes().getAttribute("samplingOption")); + Assertions.assertEquals(8, population.getPersons().size()); + Assertions.assertEquals(1.0,population.getAttributes().getAttribute("sampleSize")); + Assertions.assertEquals(1.0,population.getAttributes().getAttribute("samplingTo")); + Assertions.assertEquals("changeNumberOfLocationsWithDemand",population.getAttributes().getAttribute("samplingOption")); Person person = population.getPersons().get(Id.createPersonId("person1")); - Assert.assertEquals(1200.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(7700.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(1200.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(7700.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person2")); - Assert.assertEquals(2900.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(2800.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(2900.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(2800.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person3")); - Assert.assertEquals(4200.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(4400.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(4200.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(4400.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person4")); - Assert.assertEquals(5200.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(2600.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(5200.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(2600.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person5")); - Assert.assertEquals(5200.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(5500.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(5200.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(5500.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person6")); - Assert.assertEquals(7900.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(7500.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(7900.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(7500.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person7")); - Assert.assertEquals(4900.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(8900.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); + Assertions.assertEquals(4900.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(8900.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); person = population.getPersons().get(Id.createPersonId("person8")); - Assert.assertEquals(8400.0,person.getAttributes().getAttribute("homeX")); - Assert.assertEquals(5200.0,person.getAttributes().getAttribute("homeY")); - Assert.assertEquals(0, person.getPlans().size()); - Assert.assertNull(person.getSelectedPlan()); - } - @Test - public void testCoordOfMiddlePointOfLink() { + Assertions.assertEquals(8400.0,person.getAttributes().getAttribute("homeX")); + Assertions.assertEquals(5200.0,person.getAttributes().getAttribute("homeY")); + Assertions.assertEquals(0, person.getPlans().size()); + Assertions.assertNull(person.getSelectedPlan()); + } + + @Test + void testCoordOfMiddlePointOfLink() { Network network = NetworkUtils.readNetwork("https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); Link link = network.getLinks().get(Id.createLinkId("i(8,8)")); Coord middlePoint = FreightDemandGenerationUtils.getCoordOfMiddlePointOfLink(link); - Assert.assertEquals(7500, middlePoint.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals(8000, middlePoint.getY(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7500, middlePoint.getX(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8000, middlePoint.getY(), MatsimTestUtils.EPSILON); Link link2 = network.getLinks().get(Id.createLinkId("j(5,8)")); Coord middlePoint2 = FreightDemandGenerationUtils.getCoordOfMiddlePointOfLink(link2); - Assert.assertEquals(5000, middlePoint2.getX(), MatsimTestUtils.EPSILON); - Assert.assertEquals(7500, middlePoint2.getY(), MatsimTestUtils.EPSILON); - } - @Test - public void testReducePopulationToShapeArea() { + Assertions.assertEquals(5000, middlePoint2.getX(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7500, middlePoint2.getY(), MatsimTestUtils.EPSILON); + } + + @Test + void testReducePopulationToShapeArea() { String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; Population population = PopulationUtils.readPopulation(populationLocation); FreightDemandGenerationUtils.preparePopulation(population, 1.0, 1.0, "changeNumberOfLocationsWithDemand"); @@ -100,39 +102,41 @@ public void testReducePopulationToShapeArea() { ShpOptions shp = new ShpOptions(shapeFilePath,"WGS84", null); ShpOptions.Index index = shp.createIndex("WGS84", "_"); FreightDemandGenerationUtils.reducePopulationToShapeArea(population, index); - Assert.assertEquals(6, population.getPersons().size()); - Assert.assertFalse(population.getPersons().containsKey(Id.createPersonId("person2"))); - Assert.assertFalse(population.getPersons().containsKey(Id.createPersonId("person4"))); - } - @Test - public void testCheckPositionInShape_link() { + Assertions.assertEquals(6, population.getPersons().size()); + Assertions.assertFalse(population.getPersons().containsKey(Id.createPersonId("person2"))); + Assertions.assertFalse(population.getPersons().containsKey(Id.createPersonId("person4"))); + } + + @Test + void testCheckPositionInShape_link() { Network network = NetworkUtils.readNetwork("https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); Link link = network.getLinks().get(Id.createLinkId("i(8,8)")); Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); ShpOptions shp = new ShpOptions(shapeFilePath,"WGS84", null); Collection polygonsInShape = shp.readFeatures(); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); link = network.getLinks().get(Id.createLinkId("i(6,3)R")); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, null, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area1"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, polygonsInShape, new String[]{"area2"}, null)); - } - @Test - public void testCheckPositionInShape_point() { + } + + @Test + void testCheckPositionInShape_point() { Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); ShpOptions shp = new ShpOptions(shapeFilePath,"WGS84", null); Collection polygonsInShape = shp.readFeatures(); Point point = MGC.xy2Point(6000, 6000); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, null, null)); - Assert.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area1"}, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area2"}, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area1"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area2"}, null)); point = MGC.xy2Point(2000, 2000); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, null, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area1"}, null)); - Assert.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area2"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, null, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area1"}, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(null, point, polygonsInShape, new String[]{"area2"}, null)); } } diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java index 9ba27596185..6d562e6fbf1 100644 --- a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java @@ -20,21 +20,20 @@ package org.matsim.smallScaleCommercialTrafficGeneration; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.matsim.application.options.ShpOptions; -import org.matsim.application.options.ShpOptions.Index; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; + +import static org.matsim.smallScaleCommercialTrafficGeneration.SCTUtils.*; /** * @author Ricardo Ewert @@ -42,47 +41,43 @@ */ public class LanduseBuildingAnalysisTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap>(); - HashMap>> buildingsPerZone = new HashMap<>(); + void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); - String shapeCRS = "EPSG:4326"; // Test if the reading of the existing data distribution works correctly - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); - Assert.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea1_area1")); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea1_area2")); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea2_area3")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea1_area1")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea1_area2")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea2_area3")); for (String zone : resultingDataPerZone.keySet()) { Object2DoubleMap categories = resultingDataPerZone.get(zone); int employeeSum = 0; - Assert.assertEquals(8, categories.size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(categories.containsKey("Inhabitants")); - Assert.assertTrue(categories.containsKey("Employee")); - Assert.assertTrue(categories.containsKey("Employee Primary Sector")); - Assert.assertTrue(categories.containsKey("Employee Construction")); - Assert.assertTrue(categories.containsKey("Employee Secondary Sector Rest")); - Assert.assertTrue(categories.containsKey("Employee Retail")); - Assert.assertTrue(categories.containsKey("Employee Traffic/Parcels")); - Assert.assertTrue(categories.containsKey("Employee Tertiary Sector Rest")); + Assertions.assertEquals(8, categories.size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(categories.containsKey("Inhabitants")); + Assertions.assertTrue(categories.containsKey("Employee")); + Assertions.assertTrue(categories.containsKey("Employee Primary Sector")); + Assertions.assertTrue(categories.containsKey("Employee Construction")); + Assertions.assertTrue(categories.containsKey("Employee Secondary Sector Rest")); + Assertions.assertTrue(categories.containsKey("Employee Retail")); + Assertions.assertTrue(categories.containsKey("Employee Traffic/Parcels")); + Assertions.assertTrue(categories.containsKey("Employee Tertiary Sector Rest")); employeeSum += (int) categories.getDouble("Employee Primary Sector"); employeeSum += (int) categories.getDouble("Employee Construction"); @@ -91,190 +86,185 @@ public void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOExce employeeSum += (int) categories.getDouble("Employee Traffic/Parcels"); employeeSum += (int) categories.getDouble("Employee Tertiary Sector Rest"); - Assert.assertEquals(categories.getDouble("Employee"), employeeSum, MatsimTestUtils.EPSILON); + Assertions.assertEquals(categories.getDouble("Employee"), employeeSum, MatsimTestUtils.EPSILON); if (zone.equals("testArea1_area1")) { - Assert.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(3500, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(3500, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(0, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } if (zone.equals("testArea1_area2")) { - Assert.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(6500, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(6500, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(2000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(2000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } if (zone.equals("testArea2_area3")) { - Assert.assertEquals(800, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(800, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(50, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(50, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(100, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(100, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(150, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(150, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(300, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(300, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } } // tests if the reading of the buildings works correctly - Index indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS); - ShpOptions shpBuildings = new ShpOptions(shapeFileBuildingsPath, null, StandardCharsets.UTF_8); - List buildingsFeatures = shpBuildings.readFeatures(); - Assert.assertEquals(31, buildingsFeatures.size(), MatsimTestUtils.EPSILON); + List buildingsFeatures = getIndexBuildings(inputDataDirectory).getAllFeatures(); + Assertions.assertEquals(31, buildingsFeatures.size(), MatsimTestUtils.EPSILON); LanduseBuildingAnalysis.analyzeBuildingType(buildingsFeatures, buildingsPerZone, - landuseCategoriesAndDataConnection, shapeFileLandusePath, indexZones, shapeCRS); + landuseCategoriesAndDataConnection, getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory)); - Assert.assertEquals(3, buildingsPerZone.size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(buildingsPerZone.containsKey("testArea1_area1")); - Assert.assertTrue(buildingsPerZone.containsKey("testArea1_area2")); - Assert.assertTrue(buildingsPerZone.containsKey("testArea2_area3")); + Assertions.assertEquals(3, buildingsPerZone.size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(buildingsPerZone.containsKey("testArea1_area1")); + Assertions.assertTrue(buildingsPerZone.containsKey("testArea1_area2")); + Assertions.assertTrue(buildingsPerZone.containsKey("testArea2_area3")); // test for area1 - HashMap> builingsPerArea1 = buildingsPerZone.get("testArea1_area1"); - Assert.assertEquals(7, builingsPerArea1.size(), MatsimTestUtils.EPSILON); - ArrayList inhabitantsBuildings = builingsPerArea1.get("Inhabitants"); - Assert.assertEquals(4, inhabitantsBuildings.size(), MatsimTestUtils.EPSILON); + Map> builingsPerArea1 = buildingsPerZone.get("testArea1_area1"); + Assertions.assertEquals(7, builingsPerArea1.size(), MatsimTestUtils.EPSILON); + List inhabitantsBuildings = builingsPerArea1.get("Inhabitants"); + Assertions.assertEquals(4, inhabitantsBuildings.size(), MatsimTestUtils.EPSILON); for (SimpleFeature singleBuilding : inhabitantsBuildings) { int id = (int) (long) singleBuilding.getAttribute("osm_id"); if (id == 11) { - Assert.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("apartments", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("apartments", String.valueOf(singleBuilding.getAttribute("type"))); } else if (id == 12) { - Assert.assertEquals("1", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("house", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("1", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("house", String.valueOf(singleBuilding.getAttribute("type"))); } else if (id == 13) { - Assert.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("residential", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("residential", String.valueOf(singleBuilding.getAttribute("type"))); } else if (id == 19) { - Assert.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("detached", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("detached", String.valueOf(singleBuilding.getAttribute("type"))); } else - Assert.fail(); + Assertions.fail(); } - Assert.assertFalse(builingsPerArea1.containsKey("Employee Primary Sector")); - Assert.assertEquals(1, builingsPerArea1.get("Employee Construction").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea1.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, builingsPerArea1.get("Employee Retail").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea1.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, builingsPerArea1.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, builingsPerArea1.get("Employee").size(), MatsimTestUtils.EPSILON); + Assertions.assertFalse(builingsPerArea1.containsKey("Employee Primary Sector")); + Assertions.assertEquals(1, builingsPerArea1.get("Employee Construction").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea1.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea1.get("Employee Retail").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea1.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea1.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, builingsPerArea1.get("Employee").size(), MatsimTestUtils.EPSILON); // test for area2 - HashMap> builingsPerArea2 = buildingsPerZone.get("testArea1_area2"); - Assert.assertEquals(8, builingsPerArea2.size(), MatsimTestUtils.EPSILON); - ArrayList employeeRetail = builingsPerArea2.get("Employee Retail"); - Assert.assertEquals(2, employeeRetail.size(), MatsimTestUtils.EPSILON); + Map> builingsPerArea2 = buildingsPerZone.get("testArea1_area2"); + Assertions.assertEquals(8, builingsPerArea2.size(), MatsimTestUtils.EPSILON); + List employeeRetail = builingsPerArea2.get("Employee Retail"); + Assertions.assertEquals(2, employeeRetail.size(), MatsimTestUtils.EPSILON); for (SimpleFeature singleBuilding : employeeRetail) { int id = (int) (long) singleBuilding.getAttribute("osm_id"); if (id == 1) { - Assert.assertEquals("1", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("retail", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("1", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("retail", String.valueOf(singleBuilding.getAttribute("type"))); } else if (id == 3) { - Assert.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("retail", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("retail", String.valueOf(singleBuilding.getAttribute("type"))); } else - Assert.fail(); + Assertions.fail(); } - Assert.assertEquals(2, builingsPerArea2.get("Inhabitants").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea2.get("Employee Primary Sector").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea2.get("Employee Construction").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea2.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, builingsPerArea2.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, builingsPerArea2.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, builingsPerArea2.get("Employee").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea2.get("Inhabitants").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea2.get("Employee Primary Sector").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea2.get("Employee Construction").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea2.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea2.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea2.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, builingsPerArea2.get("Employee").size(), MatsimTestUtils.EPSILON); // test for area3 - HashMap> builingsPerArea3 = buildingsPerZone.get("testArea2_area3"); - Assert.assertEquals(8, builingsPerArea3.size(), MatsimTestUtils.EPSILON); - ArrayList tertiaryRetail = builingsPerArea3.get("Employee Tertiary Sector Rest"); - Assert.assertEquals(1, tertiaryRetail.size(), MatsimTestUtils.EPSILON); + Map> builingsPerArea3 = buildingsPerZone.get("testArea2_area3"); + Assertions.assertEquals(8, builingsPerArea3.size(), MatsimTestUtils.EPSILON); + List tertiaryRetail = builingsPerArea3.get("Employee Tertiary Sector Rest"); + Assertions.assertEquals(1, tertiaryRetail.size(), MatsimTestUtils.EPSILON); for (SimpleFeature singleBuilding : tertiaryRetail) { int id = (int) (long) singleBuilding.getAttribute("osm_id"); if (id == 26) { - Assert.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); - Assert.assertEquals("foundation", String.valueOf(singleBuilding.getAttribute("type"))); + Assertions.assertEquals("2", String.valueOf(singleBuilding.getAttribute("levels"))); + Assertions.assertEquals("foundation", String.valueOf(singleBuilding.getAttribute("type"))); } else - Assert.fail(); + Assertions.fail(); } - Assert.assertEquals(3, builingsPerArea3.get("Inhabitants").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea3.get("Employee Primary Sector").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea3.get("Employee Construction").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea3.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, builingsPerArea3.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, builingsPerArea3.get("Employee Retail").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(7, builingsPerArea3.get("Employee").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, builingsPerArea3.get("Inhabitants").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea3.get("Employee Primary Sector").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea3.get("Employee Construction").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea3.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, builingsPerArea3.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, builingsPerArea3.get("Employee Retail").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7, builingsPerArea3.get("Employee").size(), MatsimTestUtils.EPSILON); } @Test - public void testLanduseDistribution() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap>(); - HashMap>> buildingsPerZone = new HashMap<>(); + void testLanduseDistribution() throws IOException { + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); // Analyze resultingData per zone - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); - Assert.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea1_area1")); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea1_area2")); - Assert.assertTrue(resultingDataPerZone.containsKey("testArea2_area3")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea1_area1")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea1_area2")); + Assertions.assertTrue(resultingDataPerZone.containsKey("testArea2_area3")); for (String zone : resultingDataPerZone.keySet()) { Object2DoubleMap categories = resultingDataPerZone.get(zone); int employeeSum = 0; - Assert.assertEquals(8, categories.size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(categories.containsKey("Inhabitants")); - Assert.assertTrue(categories.containsKey("Employee")); - Assert.assertTrue(categories.containsKey("Employee Primary Sector")); - Assert.assertTrue(categories.containsKey("Employee Construction")); - Assert.assertTrue(categories.containsKey("Employee Secondary Sector Rest")); - Assert.assertTrue(categories.containsKey("Employee Retail")); - Assert.assertTrue(categories.containsKey("Employee Traffic/Parcels")); - Assert.assertTrue(categories.containsKey("Employee Tertiary Sector Rest")); + Assertions.assertEquals(8, categories.size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(categories.containsKey("Inhabitants")); + Assertions.assertTrue(categories.containsKey("Employee")); + Assertions.assertTrue(categories.containsKey("Employee Primary Sector")); + Assertions.assertTrue(categories.containsKey("Employee Construction")); + Assertions.assertTrue(categories.containsKey("Employee Secondary Sector Rest")); + Assertions.assertTrue(categories.containsKey("Employee Retail")); + Assertions.assertTrue(categories.containsKey("Employee Traffic/Parcels")); + Assertions.assertTrue(categories.containsKey("Employee Tertiary Sector Rest")); employeeSum += (int) categories.getDouble("Employee Primary Sector"); employeeSum += (int) categories.getDouble("Employee Construction"); @@ -283,60 +273,60 @@ public void testLanduseDistribution() throws IOException { employeeSum += (int) categories.getDouble("Employee Traffic/Parcels"); employeeSum += (int) categories.getDouble("Employee Tertiary Sector Rest"); - Assert.assertEquals(categories.getDouble("Employee"), employeeSum, MatsimTestUtils.EPSILON); + Assertions.assertEquals(categories.getDouble("Employee"), employeeSum, MatsimTestUtils.EPSILON); if (zone.equals("testArea1_area1")) { - Assert.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(3500, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(3500, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(0, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } if (zone.equals("testArea1_area2")) { - Assert.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(4000, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(6500, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(6500, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(500, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(1500, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(2000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(2000, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } if (zone.equals("testArea2_area3")) { - Assert.assertEquals(800, resultingDataPerZone.get(zone).getDouble("Inhabitants"), + Assertions.assertEquals(800, resultingDataPerZone.get(zone).getDouble("Inhabitants"), MatsimTestUtils.EPSILON); - Assert.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee"), + Assertions.assertEquals(1000, resultingDataPerZone.get(zone).getDouble("Employee"), MatsimTestUtils.EPSILON); - Assert.assertEquals(50, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), + Assertions.assertEquals(50, resultingDataPerZone.get(zone).getDouble("Employee Primary Sector"), MatsimTestUtils.EPSILON); - Assert.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Construction"), + Assertions.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Construction"), MatsimTestUtils.EPSILON); - Assert.assertEquals(100, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), + Assertions.assertEquals(100, resultingDataPerZone.get(zone).getDouble("Employee Secondary Sector Rest"), MatsimTestUtils.EPSILON); - Assert.assertEquals(150, resultingDataPerZone.get(zone).getDouble("Employee Retail"), + Assertions.assertEquals(150, resultingDataPerZone.get(zone).getDouble("Employee Retail"), MatsimTestUtils.EPSILON); - Assert.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), + Assertions.assertEquals(200, resultingDataPerZone.get(zone).getDouble("Employee Traffic/Parcels"), MatsimTestUtils.EPSILON); - Assert.assertEquals(300, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), + Assertions.assertEquals(300, resultingDataPerZone.get(zone).getDouble("Employee Tertiary Sector Rest"), MatsimTestUtils.EPSILON); } } diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java index 7e05a64a48e..62127e7e2f5 100644 --- a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java @@ -19,15 +19,15 @@ * *********************************************************************** */ package org.matsim.smallScaleCommercialTrafficGeneration; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.population.PopulationUtils; @@ -43,11 +43,11 @@ */ public class RunGenerateSmallScaleCommercialTrafficTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testMainRunAndResults() { + void testMainRunAndResults() { String inputDataDirectory = utils.getPackageInputDirectory() + "config_demand.xml"; String output = utils.getOutputDirectory(); String sample = "0.1"; @@ -81,7 +81,7 @@ public void testMainRunAndResults() { Population population = null; String carriersWOSolutionFileLocation = null; String carriersWSolutionFileLocation = null; - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); for (File outputFiles : Objects.requireNonNull(Objects.requireNonNull(outputFolder.listFiles())[0].listFiles())) { @@ -92,29 +92,29 @@ public void testMainRunAndResults() { if (outputFiles.getName().contains("output_CarrierDemandWithPlans.xml")) carriersWSolutionFileLocation = outputFiles.getPath(); if (outputFiles.getName().contains("output_carriersVehicleTypes.xml.gz")) - freightConfigGroup.setCarriersVehicleTypesFile(outputFiles.getPath()); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(outputFiles.getPath()); } - freightConfigGroup.setCarriersFile(carriersWOSolutionFileLocation); - FreightUtils.loadCarriersAccordingToFreightConfig(scenarioWOSolution); - freightConfigGroup.setCarriersFile(carriersWSolutionFileLocation); - FreightUtils.loadCarriersAccordingToFreightConfig(scenarioWSolution); + freightCarriersConfigGroup.setCarriersFile(carriersWOSolutionFileLocation); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenarioWOSolution); + freightCarriersConfigGroup.setCarriersFile(carriersWSolutionFileLocation); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenarioWSolution); assert population != null; for (Person person : population.getPersons().values()) { - Assert.assertNotNull(person.getSelectedPlan()); - Assert.assertTrue(person.getAttributes().getAsMap().containsKey("tourStartArea")); - Assert.assertTrue(person.getAttributes().getAsMap().containsKey("vehicles")); - Assert.assertTrue(person.getAttributes().getAsMap().containsKey("subpopulation")); - Assert.assertTrue(person.getAttributes().getAsMap().containsKey("purpose")); + Assertions.assertNotNull(person.getSelectedPlan()); + Assertions.assertTrue(person.getAttributes().getAsMap().containsKey("tourStartArea")); + Assertions.assertTrue(person.getAttributes().getAsMap().containsKey("vehicles")); + Assertions.assertTrue(person.getAttributes().getAsMap().containsKey("subpopulation")); + Assertions.assertTrue(person.getAttributes().getAsMap().containsKey("purpose")); } - Assert.assertEquals(FreightUtils.addOrGetCarriers(scenarioWSolution).getCarriers().size(), - FreightUtils.addOrGetCarriers(scenarioWOSolution).getCarriers().size(), 0); + Assertions.assertEquals(CarriersUtils.addOrGetCarriers(scenarioWSolution).getCarriers().size(), + CarriersUtils.addOrGetCarriers(scenarioWOSolution).getCarriers().size(), 0); int countedTours = 0; - for (Carrier carrier_withSolution : FreightUtils.addOrGetCarriers(scenarioWSolution).getCarriers().values()) { + for (Carrier carrier_withSolution : CarriersUtils.addOrGetCarriers(scenarioWSolution).getCarriers().values()) { countedTours += carrier_withSolution.getSelectedPlan().getScheduledTours().size(); } - Assert.assertEquals(population.getPersons().size(), countedTours, 0); + Assertions.assertEquals(population.getPersons().size(), countedTours, 0); } } diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java new file mode 100644 index 00000000000..7b16b902d08 --- /dev/null +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java @@ -0,0 +1,27 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import org.matsim.application.options.ShpOptions; + +import java.nio.file.Path; + +/** + * Helper tests methods. + */ +public class SCTUtils { + + static ShpOptions.Index getZoneIndex(Path inputDataDirectory) { + Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); + return new ShpOptions(shapeFileZonePath, null, null).createIndex("areaID"); + } + + static ShpOptions.Index getIndexLanduse(Path inputDataDirectory) { + Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); + return new ShpOptions(shapeFileLandusePath, null, null).createIndex("fclass"); + } + + static ShpOptions.Index getIndexBuildings(Path inputDataDirectory) { + Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); + return new ShpOptions(shapeFileBuildingsPath, null, null).createIndex("type"); + } + +} diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java index 84c5e0bd188..3aedc210cde 100644 --- a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java @@ -19,9 +19,9 @@ * *********************************************************************** */ package org.matsim.smallScaleCommercialTrafficGeneration; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -38,6 +38,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -46,35 +47,34 @@ */ public class SmallScaleCommercialTrafficUtilsTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void findZoneOfLinksTest() throws IOException, URISyntaxException { + void findZoneOfLinksTest() throws IOException, URISyntaxException { Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; Config config = ConfigUtils.createConfig(); config.global().setCoordinateSystem("EPSG:4326"); config.network().setInputFile(networkPath); config.network().setInputCRS("EPSG:4326"); Scenario scenario = ScenarioUtils.loadScenario(config); - HashMap>> buildingsPerZone = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, shpZones, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), buildingsPerZone); - Assert.assertEquals(3, regionLinksMap.size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(60, regionLinksMap.get("testArea1_area1").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(41, regionLinksMap.get("testArea1_area2").size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(28, regionLinksMap.get("testArea2_area3").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, regionLinksMap.size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(60, regionLinksMap.get("testArea1_area1").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(41, regionLinksMap.get("testArea1_area2").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(28, regionLinksMap.get("testArea2_area3").size(), MatsimTestUtils.EPSILON); - Assert.assertNull(SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(5,4)"), regionLinksMap)); - Assert.assertEquals("testArea1_area1", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(6,5)R"), regionLinksMap)); - Assert.assertEquals("testArea1_area2", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(2,7)R"), regionLinksMap)); - Assert.assertEquals("testArea2_area3", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(2,2)R"), regionLinksMap)); + Assertions.assertNull(SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(5,4)"), regionLinksMap)); + Assertions.assertEquals("testArea1_area1", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(6,5)R"), regionLinksMap)); + Assertions.assertEquals("testArea1_area2", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(2,7)R"), regionLinksMap)); + Assertions.assertEquals("testArea2_area3", SmallScaleCommercialTrafficUtils.findZoneOfLink(Id.createLinkId("j(2,2)R"), regionLinksMap)); } } diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java index 1d2109fcec7..ef979568774 100644 --- a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java @@ -20,58 +20,53 @@ package org.matsim.smallScaleCommercialTrafficGeneration; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; 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.application.options.ShpOptions; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freight.carrier.CarrierUtils; -import org.matsim.contrib.freight.controler.FreightUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.testcases.MatsimTestUtils; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; +import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.*; +import static org.matsim.smallScaleCommercialTrafficGeneration.SCTUtils.*; + /** * @author Ricardo Ewert * */ public class TrafficVolumeGenerationTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testTrafficVolumeGenerationCommercialPersonTraffic() throws IOException { + void testTrafficVolumeGenerationCommercialPersonTraffic() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap<>(); - HashMap>> buildingsPerZone = new HashMap<>(); + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); - - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); String usedTrafficType = "commercialPersonTraffic"; @@ -80,57 +75,57 @@ public void testTrafficVolumeGenerationCommercialPersonTraffic() throws IOExcept List.of("total")); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.size()); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.size()); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.size()); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.size()); for (String zone : resultingDataPerZone.keySet()) { TrafficVolumeKey trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey(zone, modesORvehTypes.get(0)); - Assert.assertTrue(trafficVolumePerTypeAndZone_start.containsKey(trafficVolumeKey)); - Assert.assertTrue(trafficVolumePerTypeAndZone_stop.containsKey(trafficVolumeKey)); + Assertions.assertTrue(trafficVolumePerTypeAndZone_start.containsKey(trafficVolumeKey)); + Assertions.assertTrue(trafficVolumePerTypeAndZone_stop.containsKey(trafficVolumeKey)); } TrafficVolumeKey trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area1", modesORvehTypes.get(0)); - Assert.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(124, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(277, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(175, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(250, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - - Assert.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(105, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(426, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(121, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(65, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(124, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(277, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(175, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(250, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(105, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(426, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(121, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(65, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area2", modesORvehTypes.get(0)); - Assert.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(211, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(514, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(441, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(630, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - - Assert.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(202, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(859, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(246, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(102, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(211, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(514, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(441, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(630, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(202, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(859, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(246, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(102, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea2_area3", modesORvehTypes.get(0)); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(34, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(79, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(62, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(88, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(34, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(79, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(62, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(88, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(31, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(128, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(37, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(31, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(128, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(37, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); //test with different sample @@ -140,69 +135,64 @@ public void testTrafficVolumeGenerationCommercialPersonTraffic() throws IOExcept trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.size()); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.size()); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.size()); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.size()); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area1", modesORvehTypes.get(0)); - Assert.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(31, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(69, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(63, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(26, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(106, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(30, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(16, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(31, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(69, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(63, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(26, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(106, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(16, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area2", modesORvehTypes.get(0)); - Assert.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(53, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(129, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(110, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(158, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(50, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(215, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(61, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(25, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(53, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(129, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(110, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(158, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(50, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(215, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(61, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(25, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea2_area3", modesORvehTypes.get(0)); - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(20, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(15, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(22, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - - Assert.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(32, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(9, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(15, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(22, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(32, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(9, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); } @Test - public void testTrafficVolumeGenerationGoodsTraffic() throws IOException { + void testTrafficVolumeGenerationGoodsTraffic() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap<>(); - HashMap>> buildingsPerZone = new HashMap<>(); + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); - - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); - + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); String usedTrafficType = "goodsTraffic"; double sample = 1.; @@ -210,19 +200,19 @@ public void testTrafficVolumeGenerationGoodsTraffic() throws IOException { Arrays.asList("vehTyp1", "vehTyp2", "vehTyp3", "vehTyp4", "vehTyp5")); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Assert.assertEquals(15, trafficVolumePerTypeAndZone_start.size()); - Assert.assertEquals(15, trafficVolumePerTypeAndZone_stop.size()); + Assertions.assertEquals(15, trafficVolumePerTypeAndZone_start.size()); + Assertions.assertEquals(15, trafficVolumePerTypeAndZone_stop.size()); for (String zone : resultingDataPerZone.keySet()) { for (String modesORvehType : modesORvehTypes) { TrafficVolumeKey trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey(zone, modesORvehType); - Assert.assertTrue(trafficVolumePerTypeAndZone_start.containsKey(trafficVolumeKey)); - Assert.assertTrue(trafficVolumePerTypeAndZone_stop.containsKey(trafficVolumeKey)); + Assertions.assertTrue(trafficVolumePerTypeAndZone_start.containsKey(trafficVolumeKey)); + Assertions.assertTrue(trafficVolumePerTypeAndZone_stop.containsKey(trafficVolumeKey)); } } @@ -250,83 +240,83 @@ public void testTrafficVolumeGenerationGoodsTraffic() throws IOException { sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); if (modeORvehType.equals("vehTyp1")) { - Assert.assertEquals(5, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(16, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(101, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(36, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(33, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(54, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(16, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(101, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(36, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(33, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(54, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } if (modeORvehType.equals("vehTyp2")) { - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(21, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(11, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(13, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(7, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(11, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(21, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(11, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(13, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(11, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } if (modeORvehType.equals("vehTyp3")) { - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(42, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(28, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(28, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(15, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(42, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(28, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(28, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(15, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } if (modeORvehType.equals("vehTyp4")) { - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(13, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(13, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } if (modeORvehType.equals("vehTyp5")) { - Assert.assertEquals(2, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(4, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(29, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(72, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(31, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(133, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(4, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(29, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(72, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(31, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(133, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } // test for "testArea1_area2" @@ -353,8 +343,8 @@ public void testTrafficVolumeGenerationGoodsTraffic() throws IOException { sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } // test for "testArea2_area3" @@ -381,17 +371,16 @@ public void testTrafficVolumeGenerationGoodsTraffic() throws IOException { sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } } @Test - public void testAddingExistingScenarios() throws Exception { + void testAddingExistingScenarios() throws Exception { Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; double sample = 1.; Config config = ConfigUtils.createConfig(); @@ -400,64 +389,64 @@ public void testAddingExistingScenarios() throws Exception { config.network().setInputCRS("EPSG:4326"); config.setContext(inputDataDirectory.resolve("config.xml").toUri().toURL()); Scenario scenario = ScenarioUtils.loadScenario(config); - HashMap>> buildingsPerZone = new HashMap<>(); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, shpZones, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), + Map>> buildingsPerZone = new HashMap<>(); + + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), buildingsPerZone); SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); - Assert.assertEquals(3, FreightUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, FreightUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier1", Carrier.class))); - Assert.assertTrue(FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier2", Carrier.class))); - Assert.assertTrue(FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleShipmentCarrier_carrier1", Carrier.class))); - - Carrier addedCarrier1 = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier1", Carrier.class)); - Assert.assertNotNull(addedCarrier1.getSelectedPlan()); - Assert.assertEquals(0, CarrierUtils.getJspritIterations(addedCarrier1), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier1.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier1.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(3, addedCarrier1.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(30, addedCarrier1.getServices().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, addedCarrier1.getAttributes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals("commercialPersonTraffic", addedCarrier1.getAttributes().getAttribute("subpopulation")); - Assert.assertEquals(2, (int) addedCarrier1.getAttributes().getAttribute("purpose")); - Assert.assertEquals("exampleServiceCarrier", addedCarrier1.getAttributes().getAttribute("existingModel")); - Assert.assertEquals("car", addedCarrier1.getAttributes().getAttribute("networkMode")); - Assert.assertNull(addedCarrier1.getAttributes().getAttribute("vehicleType")); - Assert.assertEquals("testArea2_area3", addedCarrier1.getAttributes().getAttribute("tourStartArea")); - - Carrier addedCarrier2 = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier2", Carrier.class)); - Assert.assertNotNull(addedCarrier2.getSelectedPlan()); - Assert.assertEquals(0, CarrierUtils.getJspritIterations(addedCarrier2), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier2.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier2.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, addedCarrier2.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(20, addedCarrier2.getServices().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals("commercialPersonTraffic", addedCarrier2.getAttributes().getAttribute("subpopulation")); - Assert.assertEquals(2, (int) addedCarrier2.getAttributes().getAttribute("purpose")); - Assert.assertEquals("exampleServiceCarrier", addedCarrier2.getAttributes().getAttribute("existingModel")); - Assert.assertEquals("car", addedCarrier2.getAttributes().getAttribute("networkMode")); - Assert.assertNull(addedCarrier2.getAttributes().getAttribute("vehicleType")); - Assert.assertEquals("testArea2_area3", addedCarrier2.getAttributes().getAttribute("tourStartArea")); - - Carrier addedCarrier3 = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleShipmentCarrier_carrier1", Carrier.class)); - Assert.assertNull(addedCarrier3.getSelectedPlan()); - Assert.assertEquals(50, CarrierUtils.getJspritIterations(addedCarrier3), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier3.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier3.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(FleetSize.INFINITE, addedCarrier3.getCarrierCapabilities().getFleetSize()); - Assert.assertEquals(0, addedCarrier3.getServices().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(5, addedCarrier3.getShipments().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier1", Carrier.class))); + Assertions.assertTrue(CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier2", Carrier.class))); + Assertions.assertTrue(CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleShipmentCarrier_carrier1", Carrier.class))); + + Carrier addedCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier1", Carrier.class)); + Assertions.assertNotNull(addedCarrier1.getSelectedPlan()); + Assertions.assertEquals(0, CarriersUtils.getJspritIterations(addedCarrier1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier1.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier1.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, addedCarrier1.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, addedCarrier1.getServices().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, addedCarrier1.getAttributes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals("commercialPersonTraffic", addedCarrier1.getAttributes().getAttribute("subpopulation")); + Assertions.assertEquals(2, (int) addedCarrier1.getAttributes().getAttribute("purpose")); + Assertions.assertEquals("exampleServiceCarrier", addedCarrier1.getAttributes().getAttribute("existingModel")); + Assertions.assertEquals("car", addedCarrier1.getAttributes().getAttribute("networkMode")); + Assertions.assertNull(addedCarrier1.getAttributes().getAttribute("vehicleType")); + Assertions.assertEquals("testArea2_area3", addedCarrier1.getAttributes().getAttribute("tourStartArea")); + + Carrier addedCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier2", Carrier.class)); + Assertions.assertNotNull(addedCarrier2.getSelectedPlan()); + Assertions.assertEquals(0, CarriersUtils.getJspritIterations(addedCarrier2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier2.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier2.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, addedCarrier2.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20, addedCarrier2.getServices().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals("commercialPersonTraffic", addedCarrier2.getAttributes().getAttribute("subpopulation")); + Assertions.assertEquals(2, (int) addedCarrier2.getAttributes().getAttribute("purpose")); + Assertions.assertEquals("exampleServiceCarrier", addedCarrier2.getAttributes().getAttribute("existingModel")); + Assertions.assertEquals("car", addedCarrier2.getAttributes().getAttribute("networkMode")); + Assertions.assertNull(addedCarrier2.getAttributes().getAttribute("vehicleType")); + Assertions.assertEquals("testArea2_area3", addedCarrier2.getAttributes().getAttribute("tourStartArea")); + + Carrier addedCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleShipmentCarrier_carrier1", Carrier.class)); + Assertions.assertNull(addedCarrier3.getSelectedPlan()); + Assertions.assertEquals(50, CarriersUtils.getJspritIterations(addedCarrier3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier3.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier3.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(FleetSize.INFINITE, addedCarrier3.getCarrierCapabilities().getFleetSize()); + Assertions.assertEquals(0, addedCarrier3.getServices().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, addedCarrier3.getShipments().size(), MatsimTestUtils.EPSILON); } @Test - public void testAddingExistingScenariosWithSample() throws Exception { + void testAddingExistingScenariosWithSample() throws Exception { Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; double sample = 0.2; Config config = ConfigUtils.createConfig(); @@ -466,56 +455,52 @@ public void testAddingExistingScenariosWithSample() throws Exception { config.network().setInputCRS("EPSG:4326"); config.setContext(inputDataDirectory.resolve("config.xml").toUri().toURL()); Scenario scenario = ScenarioUtils.loadScenario(config); - HashMap>> buildingsPerZone = new HashMap<>(); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, shpZones, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), + Map>> buildingsPerZone = new HashMap<>(); + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), buildingsPerZone); SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); - Assert.assertEquals(2, FreightUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, FreightUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier1", Carrier.class))); - Assert.assertTrue(FreightUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleShipmentCarrier_carrier1", Carrier.class))); - - Carrier addedCarrier1 = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier1", Carrier.class)); - Assert.assertNotNull(addedCarrier1.getSelectedPlan()); - Assert.assertEquals(0, CarrierUtils.getJspritIterations(addedCarrier1), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier1.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier1.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier1.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, addedCarrier1.getServices().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, addedCarrier1.getAttributes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals("commercialPersonTraffic", addedCarrier1.getAttributes().getAttribute("subpopulation")); - Assert.assertEquals(2, (int) addedCarrier1.getAttributes().getAttribute("purpose")); - Assert.assertEquals("exampleServiceCarrier", addedCarrier1.getAttributes().getAttribute("existingModel")); - Assert.assertEquals("car", addedCarrier1.getAttributes().getAttribute("networkMode")); - Assert.assertNull(addedCarrier1.getAttributes().getAttribute("vehicleType")); - Assert.assertEquals("testArea2_area3", addedCarrier1.getAttributes().getAttribute("tourStartArea")); - - Carrier addedCarrier3 = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleShipmentCarrier_carrier1", Carrier.class)); - Assert.assertNull(addedCarrier3.getSelectedPlan()); - Assert.assertEquals(50, CarrierUtils.getJspritIterations(addedCarrier3), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier3.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier3.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(FleetSize.INFINITE, addedCarrier3.getCarrierCapabilities().getFleetSize()); - Assert.assertEquals(0, addedCarrier3.getServices().size(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, addedCarrier3.getShipments().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, CarriersUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleServiceCarrier_carrier1", Carrier.class))); + Assertions.assertTrue(CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("exampleShipmentCarrier_carrier1", Carrier.class))); + + Carrier addedCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleServiceCarrier_carrier1", Carrier.class)); + Assertions.assertNotNull(addedCarrier1.getSelectedPlan()); + Assertions.assertEquals(0, CarriersUtils.getJspritIterations(addedCarrier1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier1.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier1.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier1.getSelectedPlan().getScheduledTours().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, addedCarrier1.getServices().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, addedCarrier1.getAttributes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals("commercialPersonTraffic", addedCarrier1.getAttributes().getAttribute("subpopulation")); + Assertions.assertEquals(2, (int) addedCarrier1.getAttributes().getAttribute("purpose")); + Assertions.assertEquals("exampleServiceCarrier", addedCarrier1.getAttributes().getAttribute("existingModel")); + Assertions.assertEquals("car", addedCarrier1.getAttributes().getAttribute("networkMode")); + Assertions.assertNull(addedCarrier1.getAttributes().getAttribute("vehicleType")); + Assertions.assertEquals("testArea2_area3", addedCarrier1.getAttributes().getAttribute("tourStartArea")); + + Carrier addedCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("exampleShipmentCarrier_carrier1", Carrier.class)); + Assertions.assertNull(addedCarrier3.getSelectedPlan()); + Assertions.assertEquals(50, CarriersUtils.getJspritIterations(addedCarrier3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier3.getCarrierCapabilities().getCarrierVehicles().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier3.getCarrierCapabilities().getVehicleTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(FleetSize.INFINITE, addedCarrier3.getCarrierCapabilities().getFleetSize()); + Assertions.assertEquals(0, addedCarrier3.getServices().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, addedCarrier3.getShipments().size(), MatsimTestUtils.EPSILON); } @Test - public void testReducingDemandAfterAddingExistingScenarios_goods() throws Exception { - HashMap> landuseCategoriesAndDataConnection = new HashMap<>(); - HashMap>> buildingsPerZone = new HashMap<>(); + void testReducingDemandAfterAddingExistingScenarios_goods() throws Exception { + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; String usedTrafficType = "goodsTraffic"; double sample = 1.; @@ -529,19 +514,18 @@ public void testReducingDemandAfterAddingExistingScenarios_goods() throws Except Scenario scenario = ScenarioUtils.loadScenario(config); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, shpZones, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), - buildingsPerZone); + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, getZoneIndex(inputDataDirectory), buildingsPerZone); SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); @@ -572,23 +556,23 @@ public void testReducingDemandAfterAddingExistingScenarios_goods() throws Except sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); if (modeORvehType.equals("vehTyp3")) { - Assert.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(42, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(28, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(26, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(15, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(44, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(42, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(28, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(23, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(4, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(8, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(26, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(73, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(15, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } // test for "testArea1_area2" @@ -615,8 +599,8 @@ public void testReducingDemandAfterAddingExistingScenarios_goods() throws Except sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } // test for "testArea2_area3" @@ -643,39 +627,35 @@ public void testReducingDemandAfterAddingExistingScenarios_goods() throws Except sumStart += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(i); sumStop += trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(i); if (modeORvehType.equals("vehTyp3")) { - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(17, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(11, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(5, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); - - Assert.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(14, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(7, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(17, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(11, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); + + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(14, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(6), MatsimTestUtils.EPSILON); } } - Assert.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); - Assert.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStart.get(i), sumStart, MatsimTestUtils.EPSILON); + Assertions.assertEquals(estimatesStop.get(i), sumStop, MatsimTestUtils.EPSILON); } } @Test - public void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraffic() throws Exception { - HashMap> landuseCategoriesAndDataConnection = new HashMap<>(); - HashMap>> buildingsPerZone = new HashMap<>(); + void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraffic() throws Exception { + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; String usedTrafficType = "commercialPersonTraffic"; double sample = 1.; @@ -689,19 +669,18 @@ public void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraff Scenario scenario = ScenarioUtils.loadScenario(config); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, shpZones, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem()), - buildingsPerZone); + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, getZoneIndex(inputDataDirectory), buildingsPerZone); SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); @@ -712,58 +691,57 @@ public void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraff double sumOfStartOtherAreas = 0; TrafficVolumeKey trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area1", modesORvehTypes.get(0)); - Assert.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); sumOfStartOtherAreas += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2); - Assert.assertEquals(277, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(175, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(250, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(277, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(175, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(250, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(85, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(426, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(121, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(65, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(85, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(426, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(121, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(65, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea1_area2", modesORvehTypes.get(0)); - Assert.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(30, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); sumOfStartOtherAreas += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2); - Assert.assertEquals(514, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(441, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(630, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(514, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(441, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(630, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(187, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(859, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(246, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(102, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(10, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(187, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(859, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(246, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(102, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); trafficVolumeKey = TrafficVolumeGeneration.makeTrafficVolumeKey("testArea2_area3", modesORvehTypes.get(0)); - Assert.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); sumOfStartOtherAreas += trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(2); - Assert.assertEquals(79, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(62, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(88, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(79, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(62, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(88, trafficVolumePerTypeAndZone_start.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); - Assert.assertEquals(27, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); - Assert.assertEquals(128, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); - Assert.assertEquals(37, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); - Assert.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(27, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(128, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(37, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(4), MatsimTestUtils.EPSILON); + Assertions.assertEquals(17, trafficVolumePerTypeAndZone_stop.get(trafficVolumeKey).getDouble(5), MatsimTestUtils.EPSILON); - Assert.assertEquals(330, sumOfStartOtherAreas, MatsimTestUtils.EPSILON); + Assertions.assertEquals(330, sumOfStartOtherAreas, MatsimTestUtils.EPSILON); } - @Test - public void testTrafficVolumeKeyGeneration() { + void testTrafficVolumeKeyGeneration() { String zone = "zone1"; String mode = "modeA"; TrafficVolumeKey newKey = TrafficVolumeGeneration.makeTrafficVolumeKey(zone, mode); - Assert.assertEquals(newKey.getZone(), zone); - Assert.assertEquals(newKey.getModeORvehType(), mode); + Assertions.assertEquals(newKey.getZone(), zone); + Assertions.assertEquals(newKey.getModeORvehType(), mode); } } diff --git a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java index 4392957d1c9..adc41f61191 100644 --- a/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java +++ b/contribs/application/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java @@ -20,69 +20,65 @@ package org.matsim.smallScaleCommercialTrafficGeneration; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.application.options.ShpOptions; import org.matsim.core.network.NetworkUtils; +import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; -import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; + import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.*; +import static org.matsim.smallScaleCommercialTrafficGeneration.SCTUtils.*; + /** * @author Ricardo Ewert * */ public class TripDistributionMatrixTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testTripDistributionCommercialPersonTrafficTraffic() throws IOException { + void testTripDistributionCommercialPersonTrafficTraffic() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap>(); - HashMap>> buildingsPerZone = new HashMap<>(); + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); String networkLocation = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); Network network = NetworkUtils.readNetwork(networkLocation); - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); String usedTrafficType = "commercialPersonTraffic"; double sample = 1.; double resistanceFactor = 0.005; - ArrayList modesORvehTypes = new ArrayList( - List.of("total")); + List modesORvehTypes = new ArrayList<>(List.of("total")); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); final TripDistributionMatrix odMatrix = TripDistributionMatrix.Builder - .newInstance(shpZones, trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop, usedTrafficType).build(); + .newInstance(getZoneIndex(inputDataDirectory), trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop, usedTrafficType).build(); - Map, Link>> regionLinksMap = new HashMap<>(); + Map, Link>> regionLinksMap = new HashMap<>(); regionLinksMap.put("testArea1_area1", new HashMap<>()); regionLinksMap.get("testArea1_area1").put(Id.createLinkId("i(8,6)"), network.getLinks().get(Id.createLinkId("i(8,6)"))); regionLinksMap.put("testArea1_area2", new HashMap<>()); @@ -104,16 +100,16 @@ public void testTripDistributionCommercialPersonTrafficTraffic() throws IOExcept odMatrix.clearRoundingError(); //tests - Assert.assertEquals(3, odMatrix.getListOfZones().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, odMatrix.getListOfZones().size(), MatsimTestUtils.EPSILON); for (String zone : resultingDataPerZone.keySet()) { - Assert.assertTrue(odMatrix.getListOfZones().contains(zone)); + Assertions.assertTrue(odMatrix.getListOfZones().contains(zone)); } - Assert.assertEquals(1, odMatrix.getListOfModesOrVehTypes().size(), MatsimTestUtils.EPSILON); - Assert.assertTrue(odMatrix.getListOfModesOrVehTypes().contains("total")); + Assertions.assertEquals(1, odMatrix.getListOfModesOrVehTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertTrue(odMatrix.getListOfModesOrVehTypes().contains("total")); - Assert.assertEquals(5, odMatrix.getListOfPurposes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, odMatrix.getListOfPurposes().size(), MatsimTestUtils.EPSILON); for (int i = 1; i <= 5; i++) { - Assert.assertTrue(odMatrix.getListOfPurposes().contains(i)); + Assertions.assertTrue(odMatrix.getListOfPurposes().contains(i)); } double sumStartServices = 0; double sumStopServices = 0; @@ -129,33 +125,29 @@ public void testTripDistributionCommercialPersonTrafficTraffic() throws IOExcept sumStartServices += odMatrix.getSumOfServicesForStartZone(zone, modeORvehType, purpose, usedTrafficType); double planedVolume = trafficVolumePerTypeAndZone_stop.get(key).getDouble(purpose); - Assert.assertEquals(planedVolume, generatedVolume, MatsimTestUtils.EPSILON); + Assertions.assertEquals(planedVolume, generatedVolume, MatsimTestUtils.EPSILON); } } } - Assert.assertEquals(sumStartServices, sumStopServices, MatsimTestUtils.EPSILON); + Assertions.assertEquals(sumStartServices, sumStopServices, MatsimTestUtils.EPSILON); } @Test - public void testTripDistributionGoodsTraffic() throws IOException { + void testTripDistributionGoodsTraffic() throws IOException { - HashMap> landuseCategoriesAndDataConnection = new HashMap>(); - HashMap>> buildingsPerZone = new HashMap<>(); + Map> landuseCategoriesAndDataConnection = new HashMap<>(); + Map>> buildingsPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); - new File(output.resolve("calculatedData").toString()).mkdir(); + assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); String usedLanduseConfiguration = "useExistingDataDistribution"; - Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); - Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); - Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); String networkLocation = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; - ShpOptions shpZones = new ShpOptions(shapeFileZonePath, null, StandardCharsets.UTF_8); Network network = NetworkUtils.readNetwork(networkLocation); - HashMap> resultingDataPerZone = LanduseBuildingAnalysis + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - inputDataDirectory, usedLanduseConfiguration, - shapeFileLandusePath, shapeFileZonePath, shapeFileBuildingsPath, null, buildingsPerZone); + inputDataDirectory, usedLanduseConfiguration, + getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), buildingsPerZone); String usedTrafficType = "goodsTraffic"; double sample = 1.; @@ -165,14 +157,14 @@ public void testTripDistributionGoodsTraffic() throws IOException { Arrays.asList("vehTyp1", "vehTyp2", "vehTyp3", "vehTyp4", "vehTyp5")); TrafficVolumeGeneration.setInputParameters(usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - HashMap> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration + Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); final TripDistributionMatrix odMatrix = TripDistributionMatrix.Builder - .newInstance(shpZones, trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop, usedTrafficType).build(); + .newInstance(getZoneIndex(inputDataDirectory), trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop, usedTrafficType).build(); - Map, Link>> regionLinksMap = new HashMap<>(); + Map, Link>> regionLinksMap = new HashMap<>(); regionLinksMap.put("testArea1_area1", new HashMap<>()); regionLinksMap.get("testArea1_area1").put(Id.createLinkId("i(8,6)"), network.getLinks().get(Id.createLinkId("i(8,6)"))); regionLinksMap.put("testArea1_area2", new HashMap<>()); @@ -194,18 +186,18 @@ public void testTripDistributionGoodsTraffic() throws IOException { odMatrix.clearRoundingError(); //tests - Assert.assertEquals(3, odMatrix.getListOfZones().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, odMatrix.getListOfZones().size(), MatsimTestUtils.EPSILON); for (String zone : resultingDataPerZone.keySet()) { - Assert.assertTrue(odMatrix.getListOfZones().contains(zone)); + Assertions.assertTrue(odMatrix.getListOfZones().contains(zone)); } - Assert.assertEquals(5, odMatrix.getListOfModesOrVehTypes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5, odMatrix.getListOfModesOrVehTypes().size(), MatsimTestUtils.EPSILON); for (String modeORvehType : modesORvehTypes) { - Assert.assertTrue(odMatrix.getListOfModesOrVehTypes().contains(modeORvehType)); + Assertions.assertTrue(odMatrix.getListOfModesOrVehTypes().contains(modeORvehType)); } - Assert.assertEquals(6, odMatrix.getListOfPurposes().size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, odMatrix.getListOfPurposes().size(), MatsimTestUtils.EPSILON); for (int i = 1; i <= 6; i++) { - Assert.assertTrue(odMatrix.getListOfPurposes().contains(i)); + Assertions.assertTrue(odMatrix.getListOfPurposes().contains(i)); } double sumStartServices = 0; double sumStopServices = 0; @@ -221,10 +213,10 @@ public void testTripDistributionGoodsTraffic() throws IOException { sumStartServices += odMatrix.getSumOfServicesForStartZone(zone, modeORvehType, purpose, usedTrafficType); double planedVolume = trafficVolumePerTypeAndZone_stop.get(key).getDouble(purpose); - Assert.assertEquals(planedVolume, generatedVolume, MatsimTestUtils.EPSILON); + Assertions.assertEquals(planedVolume, generatedVolume, MatsimTestUtils.EPSILON); } } } - Assert.assertEquals(sumStartServices, sumStopServices, MatsimTestUtils.EPSILON); + Assertions.assertEquals(sumStartServices, sumStopServices, MatsimTestUtils.EPSILON); } } diff --git a/contribs/application/test/input/org/matsim/application/prepare/CreateLandUseShpTest/andorra-latest-free.shp.zip b/contribs/application/test/input/org/matsim/application/prepare/CreateLandUseShpTest/andorra-latest-free.shp.zip index 3e1b339376e..8c2e290f582 100644 Binary files a/contribs/application/test/input/org/matsim/application/prepare/CreateLandUseShpTest/andorra-latest-free.shp.zip and b/contribs/application/test/input/org/matsim/application/prepare/CreateLandUseShpTest/andorra-latest-free.shp.zip differ diff --git a/contribs/application/test/input/org/matsim/smallScaleCommercialTrafficGeneration/config_demand.xml b/contribs/application/test/input/org/matsim/smallScaleCommercialTrafficGeneration/config_demand.xml index 70e7f37a962..bc64ce1501a 100644 --- a/contribs/application/test/input/org/matsim/smallScaleCommercialTrafficGeneration/config_demand.xml +++ b/contribs/application/test/input/org/matsim/smallScaleCommercialTrafficGeneration/config_demand.xml @@ -47,7 +47,7 @@ - + @@ -70,15 +70,6 @@ - - - - - - - - - @@ -416,24 +407,6 @@ - - - - - - - - - - - - - - - - - - @@ -560,8 +533,6 @@ - - diff --git a/contribs/av/src/main/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExample.java b/contribs/av/src/main/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExample.java index 95fc4ca0f07..9aaecbc61b2 100644 --- a/contribs/av/src/main/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExample.java +++ b/contribs/av/src/main/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExample.java @@ -36,7 +36,7 @@ import org.matsim.contrib.taxi.run.MultiModeTaxiModule; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; import org.matsim.core.scenario.ScenarioUtils; @@ -54,8 +54,8 @@ public class RunTaxiPTIntermodalExample { public void run(URL configUrl, boolean OTFVis) { Config config = ConfigUtils.loadConfig(configUrl, new MultiModeTaxiConfigGroup(), new DvrpConfigGroup()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.plansCalcRoute().setAccessEgressType(PlansCalcRouteConfigGroup.AccessEgressType.accessEgressModeToLink); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.routing().setAccessEgressType(RoutingConfigGroup.AccessEgressType.accessEgressModeToLink); SwissRailRaptorConfigGroup srrConfig = new SwissRailRaptorConfigGroup(); diff --git a/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java b/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java index 5f1646efe1a..5c95006afa8 100644 --- a/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java +++ b/contribs/av/src/main/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExample.java @@ -48,7 +48,7 @@ public static void run(URL configUrl, boolean otfvis) { new DvrpConfigGroup(), new OTFVisConfigGroup()); Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); - config.controler() + config.controller() .setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles); Controler controler = new Controler(scenario); controler.addOverridingModule(new MultiModeDrtModule()); diff --git a/contribs/av/src/test/java/org/matsim/contrib/av/flow/RunAvExampleIT.java b/contribs/av/src/test/java/org/matsim/contrib/av/flow/RunAvExampleIT.java index 442047d0674..ddc697ee825 100644 --- a/contribs/av/src/test/java/org/matsim/contrib/av/flow/RunAvExampleIT.java +++ b/contribs/av/src/test/java/org/matsim/contrib/av/flow/RunAvExampleIT.java @@ -26,19 +26,19 @@ import java.net.MalformedURLException; import java.net.URL; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; /** * @author jbischoff */ public class RunAvExampleIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testAvFlowExample() throws MalformedURLException { + void testAvFlowExample() throws MalformedURLException { URL configUrl = new File(utils.getPackageInputDirectory() + "config.xml").toURI().toURL(); new RunAvExample().run(configUrl, false); } diff --git a/contribs/av/src/test/java/org/matsim/contrib/av/flow/TestAvFlowFactor.java b/contribs/av/src/test/java/org/matsim/contrib/av/flow/TestAvFlowFactor.java index 67837840838..8a486ca716e 100644 --- a/contribs/av/src/test/java/org/matsim/contrib/av/flow/TestAvFlowFactor.java +++ b/contribs/av/src/test/java/org/matsim/contrib/av/flow/TestAvFlowFactor.java @@ -26,9 +26,9 @@ import java.net.MalformedURLException; import java.net.URL; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.events.LinkEnterEvent; @@ -44,11 +44,11 @@ import org.matsim.vis.otfvis.OTFVisConfigGroup; public class TestAvFlowFactor { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testAvFlowFactor() throws MalformedURLException { + void testAvFlowFactor() throws MalformedURLException { URL configUrl = new File(utils.getPackageInputDirectory() + "config.xml").toURI().toURL(); Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup()); Scenario scenario = ScenarioUtils.loadScenario(config); @@ -70,8 +70,8 @@ public void testAvFlowFactor() throws MalformedURLException { controler.getEvents().addHandler(vehicleTimeCounter); controler.run(); - Assert.assertEquals(vehicleTimeCounter.lastAVEnterTime, 32598, 0.1); - Assert.assertEquals(vehicleTimeCounter.lastNonAVEnterTime, 36179, 0.1); + Assertions.assertEquals(vehicleTimeCounter.lastAVEnterTime, 32598, 0.1); + Assertions.assertEquals(vehicleTimeCounter.lastNonAVEnterTime, 36179, 0.1); } diff --git a/contribs/av/src/test/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExampleIT.java b/contribs/av/src/test/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExampleIT.java index 7fe1d1624c6..2721030096d 100644 --- a/contribs/av/src/test/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExampleIT.java +++ b/contribs/av/src/test/java/org/matsim/contrib/av/intermodal/RunTaxiPTIntermodalExampleIT.java @@ -29,9 +29,9 @@ import java.util.List; import java.util.Map; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Leg; @@ -48,11 +48,11 @@ * @author jbischoff */ public class RunTaxiPTIntermodalExampleIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testIntermodalExample() throws MalformedURLException { + void testIntermodalExample() throws MalformedURLException { URL configUrl = new File(utils.getClassInputDirectory() + "config.xml").toURI().toURL(); new RunTaxiPTIntermodalExample().run(configUrl, false); @@ -83,7 +83,7 @@ public void testIntermodalExample() throws MalformedURLException { } } - Assert.assertTrue("no pt agent has any intermodal route (=taxi for access or egress to pt)", - intermodalTripCounter > 0); + Assertions.assertTrue(intermodalTripCounter > 0, + "no pt agent has any intermodal route (=taxi for access or egress to pt)"); } } diff --git a/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExampleTest.java b/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExampleTest.java index 2a85956ae3f..aa513d2a9e5 100644 --- a/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExampleTest.java +++ b/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunDrtAndTaxiExampleTest.java @@ -22,13 +22,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunDrtAndTaxiExampleTest { @Test - public void run() { + void run() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "one_taxi_and_one_shared_taxi_config.xml"); RunDrtAndTaxiExample.run(configUrl, false); diff --git a/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunRobotaxiExampleIT.java b/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunRobotaxiExampleIT.java index 9c56af75336..a256bd46e52 100644 --- a/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunRobotaxiExampleIT.java +++ b/contribs/av/src/test/java/org/matsim/contrib/av/robotaxi/run/RunRobotaxiExampleIT.java @@ -22,7 +22,7 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; @@ -31,7 +31,7 @@ */ public class RunRobotaxiExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_taxi_config.xml"); RunRobotaxiExample.run(configUrl, false); } diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java index 15b2d7f42a9..7bf5a766bf4 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java @@ -86,7 +86,7 @@ static class ConsistencyCheck implements StartupListener { LOG.warn("There is an inconsistency in the specified maximum velocity for " + bicycleConfigGroup.getBicycleMode() + ":" + " Maximum speed specified in the 'bicycle' config group (used for routing): " + bicycleConfigGroup.getMaxBicycleSpeedForRouting() + " vs." + " maximum speed specified for the vehicle type (used in mobsim): " + mobsimSpeed); - if (scenario.getConfig().plansCalcRoute().getRoutingRandomness() == 0.) { + if (scenario.getConfig().routing().getRoutingRandomness() == 0.) { throw new RuntimeException("The recommended way to deal with the inconsistency between routing and scoring/mobsim is to have a randomized router. Aborting... "); } } diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutility.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutility.java index be8c5cca418..8632a8dcf6d 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutility.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutility.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.network.NetworkUtils; import org.matsim.core.router.util.TravelDisutility; @@ -65,9 +65,9 @@ class BicycleTravelDisutility implements TravelDisutility { private Person prevPerson; - BicycleTravelDisutility(BicycleConfigGroup bicycleConfigGroup, PlanCalcScoreConfigGroup cnScoringGroup, - PlansCalcRouteConfigGroup plansCalcRouteConfigGroup, TravelTime timeCalculator, double normalization) { - final PlanCalcScoreConfigGroup.ModeParams bicycleParams = cnScoringGroup.getModes().get(bicycleConfigGroup.getBicycleMode()); + BicycleTravelDisutility(BicycleConfigGroup bicycleConfigGroup, ScoringConfigGroup cnScoringGroup, + RoutingConfigGroup routingConfigGroup, TravelTime timeCalculator, double normalization) { + final ScoringConfigGroup.ModeParams bicycleParams = cnScoringGroup.getModes().get(bicycleConfigGroup.getBicycleMode()); if (bicycleParams == null) { throw new NullPointerException("Mode " + bicycleConfigGroup.getBicycleMode() + " is not part of the valid mode parameters " + cnScoringGroup.getModes().keySet()); } @@ -86,7 +86,7 @@ class BicycleTravelDisutility implements TravelDisutility { this.timeCalculator = timeCalculator; this.normalization = normalization; - this.sigma = plansCalcRouteConfigGroup.getRoutingRandomness(); + this.sigma = routingConfigGroup.getRoutingRandomness(); this.random = sigma != 0 ? MatsimRandom.getLocalInstance() : null; } diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java index 0bd8d6aef8c..135bc7e011f 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java @@ -21,8 +21,8 @@ import com.google.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.router.costcalculators.TravelDisutilityFactory; import org.matsim.core.router.util.TravelDisutility; import org.matsim.core.router.util.TravelTime; @@ -39,17 +39,19 @@ public final class BicycleTravelDisutilityFactory implements TravelDisutilityFac private static final Logger LOG = LogManager.getLogger(BicycleTravelDisutilityFactory.class); @Inject BicycleConfigGroup bicycleConfigGroup; - @Inject PlanCalcScoreConfigGroup cnScoringGroup; - @Inject PlansCalcRouteConfigGroup plansCalcRouteConfigGroup; - + @Inject + ScoringConfigGroup cnScoringGroup; + @Inject + RoutingConfigGroup routingConfigGroup; + private static int normalisationWrnCnt = 0; /* package-private */ BicycleTravelDisutilityFactory(){} - + @Override public TravelDisutility createTravelDisutility(TravelTime timeCalculator) { - double sigma = plansCalcRouteConfigGroup.getRoutingRandomness(); - + double sigma = routingConfigGroup.getRoutingRandomness(); + double normalization = 1; if ( sigma != 0. ) { normalization = 1. / Math.exp(sigma * sigma / 2); @@ -58,6 +60,6 @@ public TravelDisutility createTravelDisutility(TravelTime timeCalculator) { LOG.info(" sigma: " + sigma + "; resulting normalization: " + normalization); } } - return new BicycleTravelDisutility(bicycleConfigGroup, cnScoringGroup, plansCalcRouteConfigGroup, timeCalculator, normalization); + return new BicycleTravelDisutility(bicycleConfigGroup, cnScoringGroup, routingConfigGroup, timeCalculator, normalization); } } diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/run/RunBicycleExample.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/run/RunBicycleExample.java index 134f8bf421e..af6d9d58927 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/run/RunBicycleExample.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/run/RunBicycleExample.java @@ -31,10 +31,10 @@ import org.matsim.contrib.bicycle.BicycleUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ActivityParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; @@ -71,14 +71,14 @@ public static void main(String[] args) { throw new RuntimeException("More than one argument was provided. There is no procedure for this situation. Thus aborting!" + " Provide either (1) only a suitable config file or (2) no argument at all to run example with given example of resources folder."); } - config.controler().setLastIteration(100); // Modify if motorized interaction is used + config.controller().setLastIteration(100); // Modify if motorized interaction is used boolean considerMotorizedInteraction = false; new RunBicycleExample().run(config ); } static void fillConfigWithBicycleStandardValues(Config config) { - config.controler().setWriteEventsInterval(1); + config.controller().setWriteEventsInterval(1); BicycleConfigGroup bicycleConfigGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); bicycleConfigGroup.setMarginalUtilityOfInfrastructure_m(-0.0002); @@ -97,23 +97,23 @@ static void fillConfigWithBicycleStandardValues(Config config) { config.qsim().setMainModes(mainModeList); - config.strategy().setMaxAgentPlanMemorySize(5); - config.strategy().addStrategySettings( new StrategySettings().setStrategyName("ChangeExpBeta" ).setWeight(0.8 ) ); - config.strategy().addStrategySettings( new StrategySettings().setStrategyName("ReRoute" ).setWeight(0.2 ) ); + config.replanning().setMaxAgentPlanMemorySize(5); + config.replanning().addStrategySettings( new StrategySettings().setStrategyName("ChangeExpBeta" ).setWeight(0.8 ) ); + config.replanning().addStrategySettings( new StrategySettings().setStrategyName("ReRoute" ).setWeight(0.2 ) ); - config.planCalcScore().addActivityParams( new ActivityParams("home").setTypicalDuration(12*60*60 ) ); - config.planCalcScore().addActivityParams( new ActivityParams("work").setTypicalDuration(8*60*60 ) ); + config.scoring().addActivityParams( new ActivityParams("home").setTypicalDuration(12*60*60 ) ); + config.scoring().addActivityParams( new ActivityParams("work").setTypicalDuration(8*60*60 ) ); - config.planCalcScore().addModeParams( new ModeParams("bicycle").setConstant(0. ).setMarginalUtilityOfDistance(-0.0004 ).setMarginalUtilityOfTraveling(-6.0 ).setMonetaryDistanceRate(0. ) ); + config.scoring().addModeParams( new ModeParams("bicycle").setConstant(0. ).setMarginalUtilityOfDistance(-0.0004 ).setMarginalUtilityOfTraveling(-6.0 ).setMonetaryDistanceRate(0. ) ); - config.plansCalcRoute().setNetworkModes(mainModeList); + config.routing().setNetworkModes(mainModeList); } public void run(Config config ) { config.global().setNumberOfThreads(1); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.plansCalcRoute().setRoutingRandomness(3.); + config.routing().setRoutingRandomness(3.); BicycleConfigGroup bicycleConfigGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); @@ -137,9 +137,9 @@ public void run(Config config ) { } public void runWithOwnScoring(Config config, boolean considerMotorizedInteraction) { config.global().setNumberOfThreads(1); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.plansCalcRoute().setRoutingRandomness(3.); + config.routing().setRoutingRandomness(3.); if (considerMotorizedInteraction) { BicycleConfigGroup bicycleConfigGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); diff --git a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorTest.java b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorTest.java index 1af7f1aec93..8d58af0313f 100644 --- a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorTest.java +++ b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorTest.java @@ -1,8 +1,8 @@ package org.matsim.contrib.bicycle; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -30,18 +30,19 @@ import java.util.UUID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class BicycleLinkSpeedCalculatorTest { - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); private static final double MAX_BICYCLE_SPEED = 15; private final Config config = ConfigUtils.createConfig(); private BicycleConfigGroup configGroup; private final Network unusedNetwork = NetworkUtils.createNetwork(); - @Before + @BeforeEach public void before() { configGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); configGroup.setMaxBicycleSpeedForRouting(MAX_BICYCLE_SPEED); @@ -58,8 +59,8 @@ private static Vehicle createVehicle(double maxVelocity, long id) { return VehicleUtils.createVehicle(Id.createVehicleId(id), type); } - @Test - public void getMaximumVelocity_bike() { + @Test + void getMaximumVelocity_bike() { Link link = createLinkWithNoGradientAndNoSpecialSurface(); QVehicle vehicle = new QVehicleImpl(createVehicle(link.getFreespeed() * 0.5, 1)); // higher speed than the default @@ -70,8 +71,8 @@ public void getMaximumVelocity_bike() { assertEquals(vehicle.getMaximumVelocity(), speed, 0.0); } - @Test - public void getMaximumVelocity_bike_fasterThanFreespeed() { + @Test + void getMaximumVelocity_bike_fasterThanFreespeed() { Link link = createLinkWithNoGradientAndNoSpecialSurface(); QVehicle vehicle = new QVehicleImpl(createVehicle(link.getFreespeed() * 2, 1)); @@ -82,8 +83,8 @@ public void getMaximumVelocity_bike_fasterThanFreespeed() { assertEquals(link.getFreespeed(), speed, 0.0); } - @Test - public void getMaximumVelocityForLink_bikeIsNull() { + @Test + void getMaximumVelocityForLink_bikeIsNull() { Link link = createLinkWithNoGradientAndNoSpecialSurface(); BicycleLinkSpeedCalculatorDefaultImpl calculator = new BicycleLinkSpeedCalculatorDefaultImpl(config); @@ -93,8 +94,8 @@ public void getMaximumVelocityForLink_bikeIsNull() { assertEquals(configGroup.getMaxBicycleSpeedForRouting(), speed, 0.001); } - @Test - public void getMaximumVelocityForLink_withGradient() { + @Test + void getMaximumVelocityForLink_withGradient() { Link linkForComparison = createLinkWithNoGradientAndNoSpecialSurface(); Link linkWithGradient = createLink(100, "paved", "not-a-cycle-way", 1.0); @@ -108,8 +109,8 @@ public void getMaximumVelocityForLink_withGradient() { assertTrue(comparisonSpeed > gradientSpeed); } - @Test - public void getMaximumVelocityForLink_withReducedSpeedFactor() { + @Test + void getMaximumVelocityForLink_withReducedSpeedFactor() { Link linkForComparison = createLinkWithNoGradientAndNoSpecialSurface(); Link linkWithReducedSpeed = createLink(0, "paved", "not-a-cycle-way", 0.5); @@ -123,8 +124,8 @@ public void getMaximumVelocityForLink_withReducedSpeedFactor() { assertTrue(comparisonSpeed > gradientSpeed); } - @Test - public void getMaximumVelocityForLink_noSpeedFactor() { + @Test + void getMaximumVelocityForLink_noSpeedFactor() { var link = createLinkWithNoGradientAndNoSpecialSurface(); var vehicle = createVehicle(link.getFreespeed() + 1, 1); @@ -135,8 +136,8 @@ public void getMaximumVelocityForLink_noSpeedFactor() { assertEquals(link.getFreespeed(), speed, 0.001); } - @Test - public void getMaximumVelocityForLink_withRoughSurface() { + @Test + void getMaximumVelocityForLink_withRoughSurface() { Link linkForComparison = createLinkWithNoGradientAndNoSpecialSurface(); Link linkWithCobbleStone = createLink(0, "cobblestone", "not-a-cycle-way", 1.0); @@ -177,8 +178,8 @@ private Link createLink(double elevation, String surfaceType, String wayType, do return link; } - @Test - public void getMaximumVelocityForLink_withCycleWay() { + @Test + void getMaximumVelocityForLink_withCycleWay() { Link linkForComparison = createLinkWithNoGradientAndNoSpecialSurface(); Link linkWithCobbleStone = createLink(0, "some-surface", BicycleUtils.CYCLEWAY, 1.0); diff --git a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleUtilityUtilsTest.java b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleUtilityUtilsTest.java index 19697a3afaf..3d9d4ff5c90 100644 --- a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleUtilityUtilsTest.java +++ b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/BicycleUtilityUtilsTest.java @@ -1,41 +1,41 @@ package org.matsim.contrib.bicycle; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.core.network.NetworkUtils; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class BicycleUtilityUtilsTest { @Test - public void getGradientNoFromZ() { + void getGradientNoFromZ() { var link = createLink(new Coord(0, 0), new Coord(100, 0, 100)); assertEquals(0., BicycleUtils.getGradient(link ), 0.00001 ); } @Test - public void getGradientNoToZ() { + void getGradientNoToZ() { var link = createLink(new Coord(0, 0, 100), new Coord(100, 0)); assertEquals(0., BicycleUtils.getGradient(link ), 0.00001 ); } @Test - public void getGradientFlat() { + void getGradientFlat() { var link = createLink(new Coord(0, 0, 100), new Coord(100, 0, 100)); assertEquals(0., BicycleUtils.getGradient(link ), 0.00001 ); } @Test - public void getGradientUphill() { + void getGradientUphill() { var link = createLink(new Coord(0, 0, 0), new Coord(100, 0, 100)); assertEquals(1., BicycleUtils.getGradient(link ), 0.00001 ); } @Test - public void getGradientDownhill() { + void getGradientDownhill() { var link = createLink(new Coord(0, 0, 100), new Coord(100, 0, 0)); assertEquals(0., BicycleUtils.getGradient(link ), 0.00001 ); } diff --git a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/run/BicycleTest.java b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/run/BicycleTest.java index 329e40cc0c5..961e43f0182 100644 --- a/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/run/BicycleTest.java +++ b/contribs/bicycle/src/test/java/org/matsim/contrib/bicycle/run/BicycleTest.java @@ -20,9 +20,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -39,10 +39,10 @@ import org.matsim.contrib.bicycle.BicycleModule; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ActivityParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.config.groups.QSimConfigGroup.VehiclesSource; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; @@ -63,8 +63,8 @@ import java.util.List; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.matsim.utils.eventsfilecomparison.EventsFileComparator.Result.FILES_ARE_EQUAL; /** @@ -75,10 +75,11 @@ public class BicycleTest { private static final String bicycleMode = "bicycle"; - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testNormal() { + void testNormal() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -86,18 +87,19 @@ public void testNormal() { // Normal network config.network().setInputFile("network_normal.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); @@ -106,13 +108,13 @@ public void testNormal() { for (Id personId : scenarioReference.getPopulation().getPersons().keySet()) { double scoreReference = scenarioReference.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); double scoreCurrent = scenarioCurrent.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); - Assert.assertEquals("Scores of persons " + personId + " are different", scoreReference, scoreCurrent, MatsimTestUtils.EPSILON); + Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of persons " + personId + " are different"); } - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } @Test - public void testCobblestone() { + void testCobblestone() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -122,10 +124,10 @@ public void testCobblestone() { config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); { @@ -133,19 +135,20 @@ public void testCobblestone() { Scenario scenarioCurrent = ScenarioUtils.createScenario( ConfigUtils.createConfig() ); new PopulationReader( scenarioReference ).readFile( utils.getInputDirectory() + "output_plans.xml.gz" ); new PopulationReader( scenarioCurrent ).readFile( utils.getOutputDirectory() + "output_plans.xml.gz" ); - assertTrue( "Populations are different", PopulationUtils.equalPopulation( scenarioReference.getPopulation(), scenarioCurrent.getPopulation() ) ); + assertTrue( PopulationUtils.equalPopulation( scenarioReference.getPopulation(), scenarioCurrent.getPopulation() ), "Populations are different" ); } { LOG.info( "Checking MATSim events file ..." ); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals( "Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew )); + assertEquals( FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew ), + "Different event files."); } } @Test - public void testPedestrian() { + void testPedestrian() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -153,28 +156,29 @@ public void testPedestrian() { // Links 4-8 and 13-17 are pedestrian zones config.network().setInputFile("network_pedestrian.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); new PopulationReader(scenarioReference).readFile(utils.getInputDirectory() + "output_plans.xml.gz"); new PopulationReader(scenarioCurrent).readFile(utils.getOutputDirectory() + "output_plans.xml.gz"); - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } @Test - public void testLane() { + void testLane() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -182,28 +186,29 @@ public void testLane() { // Links 2-4/8-10 and 11-13/17-19 have cycle lanes (cycleway=lane) config.network().setInputFile("network_lane.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); new PopulationReader(scenarioReference).readFile(utils.getInputDirectory() + "output_plans.xml.gz"); new PopulationReader(scenarioCurrent).readFile(utils.getOutputDirectory() + "output_plans.xml.gz"); - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } @Test - public void testGradient() { + void testGradient() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -211,28 +216,29 @@ public void testGradient() { // Nodes 5-8 have a z-coordinate > 0, i.e. the links leading to those nodes have a slope config.network().setInputFile("network_gradient.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison( eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); new PopulationReader(scenarioReference).readFile(utils.getInputDirectory() + "output_plans.xml.gz"); new PopulationReader(scenarioCurrent).readFile(utils.getOutputDirectory() + "output_plans.xml.gz"); - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } @Test - public void testGradientLane() { + void testGradientLane() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -241,28 +247,29 @@ public void testGradientLane() { // and links 4-5 and 13-14 have cycle lanes config.network().setInputFile("network_gradient_lane.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); - config.controler().setCreateGraphs(false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison(eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison(eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); new PopulationReader(scenarioReference).readFile(utils.getInputDirectory() + "output_plans.xml.gz"); new PopulationReader(scenarioCurrent).readFile(utils.getOutputDirectory() + "output_plans.xml.gz"); - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } @Test - public void testNormal10It() { + void testNormal10It() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); RunBicycleExample.fillConfigWithBicycleStandardValues(config); @@ -270,30 +277,32 @@ public void testNormal10It() { // Normal network config.network().setInputFile("network_normal.xml"); config.plans().setInputFile("population_1200.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); // 10 iterations - config.controler().setLastIteration(10); - config.controler().setWriteEventsInterval(10); - config.controler().setWritePlansInterval(10); - config.controler().setCreateGraphs(false); + config.controller().setLastIteration(10); + config.controller().setWriteEventsInterval(10); + config.controller().setWritePlansInterval(10); + config.controller().setCreateGraphs(false); new RunBicycleExample().run(config ); LOG.info("Checking MATSim events file ..."); final String eventsFilenameReference = utils.getInputDirectory() + "output_events.xml.gz"; final String eventsFilenameNew = utils.getOutputDirectory() + "output_events.xml.gz"; - assertEquals("Different event files.", FILES_ARE_EQUAL, - new EventsFileComparator().setIgnoringCoordinates( true ).runComparison(eventsFilenameReference, eventsFilenameNew)); + assertEquals(FILES_ARE_EQUAL, + new EventsFileComparator().setIgnoringCoordinates( true ).runComparison(eventsFilenameReference, eventsFilenameNew), + "Different event files."); Scenario scenarioReference = ScenarioUtils.createScenario(ConfigUtils.createConfig()); Scenario scenarioCurrent = ScenarioUtils.createScenario(ConfigUtils.createConfig()); new PopulationReader(scenarioReference).readFile(utils.getInputDirectory() + "output_plans.xml.gz"); new PopulationReader(scenarioCurrent).readFile(utils.getOutputDirectory() + "output_plans.xml.gz"); - assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); + assertTrue(PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation()), "Populations are different"); } - @Test public void testLinkBasedScoring() { + @Test + void testLinkBasedScoring() { // { // Config config = createConfig( 0 ); // BicycleConfigGroup bicycleConfigGroup = (BicycleConfigGroup) config.getModules().get( "bicycle" ); @@ -320,11 +329,13 @@ public void testNormal10It() { for (Id personId : scenarioReference.getPopulation().getPersons().keySet()) { double scoreReference = scenarioReference.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); double scoreCurrent = scenarioCurrent.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); - Assert.assertEquals("Scores of persons " + personId + " are different", scoreReference, scoreCurrent, MatsimTestUtils.EPSILON); + Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of persons " + personId + " are different"); } // assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); } - @Test public void testLinkVsLegMotorizedScoring() { + + @Test + void testLinkVsLegMotorizedScoring() { // --- withOUT additional car traffic: // { // Config config2 = createConfig( 0 ); @@ -345,9 +356,9 @@ public void testNormal10It() { // the following comes from inlining RunBicycleExample, which we need since we need to modify scenario data: config.global().setNumberOfThreads(1 ); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists ); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists ); - config.plansCalcRoute().setRoutingRandomness(3. ); + config.routing().setRoutingRandomness(3. ); final String bicycle = bicycleConfigGroup.getBicycleMode(); @@ -406,10 +417,11 @@ public void testNormal10It() { for (Id personId : scenarioReference.getPopulation().getPersons().keySet()) { double scoreReference = scenarioReference.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); double scoreCurrent = scenarioCurrent.getPopulation().getPersons().get(personId).getSelectedPlan().getScore(); - Assert.assertEquals("Scores of person=" + personId + " are different", scoreReference, scoreCurrent, MatsimTestUtils.EPSILON); + Assertions.assertEquals(scoreReference, scoreCurrent, MatsimTestUtils.EPSILON, "Scores of person=" + personId + " are different"); } // assertTrue("Populations are different", PopulationUtils.equalPopulation(scenarioReference.getPopulation(), scenarioCurrent.getPopulation())); } + // @Test public void testMotorizedInteraction() { //// Config config = ConfigUtils.createConfig("./src/main/resources/bicycle_example/"); // Config config = createConfig( 10 ); @@ -440,14 +452,14 @@ public void testNormal10It() { // } @Test - public void testInfrastructureSpeedFactor() { + void testInfrastructureSpeedFactor() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); config.addModule(new BicycleConfigGroup()); - config.controler().setWriteEventsInterval(0); - config.controler().setWritePlansInterval(0); - config.controler().setCreateGraphs(false); - config.controler().setDumpDataAtEnd(false); + config.controller().setWriteEventsInterval(0); + config.controller().setWritePlansInterval(0); + config.controller().setCreateGraphs(false); + config.controller().setDumpDataAtEnd(false); config.qsim().setStartTime(6. * 3600.); config.qsim().setEndTime(10. * 3600.); @@ -456,43 +468,43 @@ public void testInfrastructureSpeedFactor() { mainModeList.add(TransportMode.car); config.qsim().setMainModes(mainModeList); - config.strategy().setMaxAgentPlanMemorySize(5); + config.replanning().setMaxAgentPlanMemorySize(5); { StrategySettings strategySettings = new StrategySettings(); strategySettings.setStrategyName("ChangeExpBeta"); strategySettings.setWeight(1.0); - config.strategy().addStrategySettings(strategySettings); + config.replanning().addStrategySettings(strategySettings); } ActivityParams homeActivity = new ActivityParams("home"); homeActivity.setTypicalDuration(12*60*60); - config.planCalcScore().addActivityParams(homeActivity); + config.scoring().addActivityParams(homeActivity); ActivityParams workActivity = new ActivityParams("work"); workActivity.setTypicalDuration(8*60*60); - config.planCalcScore().addActivityParams(workActivity); + config.scoring().addActivityParams(workActivity); ModeParams bicycle = new ModeParams( bicycleMode ); bicycle.setConstant(0.); bicycle.setMarginalUtilityOfDistance(-0.0004); // util/m bicycle.setMarginalUtilityOfTraveling(-6.0); // util/h bicycle.setMonetaryDistanceRate(0.); - config.planCalcScore().addModeParams(bicycle); + config.scoring().addModeParams(bicycle); - config.plansCalcRoute().setNetworkModes(mainModeList); + config.routing().setNetworkModes(mainModeList); // link 2 has infrastructure speed factor = 1.0, all other links 0.01 config.network().setInputFile("network_infrastructure-speed-factor.xml"); config.plans().setInputFile("population_4.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); config.global().setNumberOfThreads(1); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.plansCalcRoute().setRoutingRandomness(3.); + config.routing().setRoutingRandomness(3.); // --- @@ -523,26 +535,26 @@ public void install() { controler.run(); - Assert.assertEquals("All bicycle users should use the longest but fastest route where the bicycle infrastructur speed factor is set to 1.0", 3, linkHandler.getLinkId2demand().get(Id.createLinkId("2")), MatsimTestUtils.EPSILON); - Assert.assertEquals("Only the car user should use the shortest route", 1, linkHandler.getLinkId2demand().get(Id.createLinkId("6")), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3, linkHandler.getLinkId2demand().get(Id.createLinkId("2")), MatsimTestUtils.EPSILON, "All bicycle users should use the longest but fastest route where the bicycle infrastructur speed factor is set to 1.0"); + Assertions.assertEquals(1, linkHandler.getLinkId2demand().get(Id.createLinkId("6")), MatsimTestUtils.EPSILON, "Only the car user should use the shortest route"); - Assert.assertEquals("Wrong travel time (bicycle user)", 1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(0), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (bicycle user)", 1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(1), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (bicycle user)", 1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(0), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); + Assertions.assertEquals(1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(1), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); + Assertions.assertEquals(1.0 + Math.ceil( 13000 / (25.0 /3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("2")).get(2), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); - Assert.assertEquals("Wrong travel time (car user)", Math.ceil( 10000 / (13.88) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(0), MatsimTestUtils.EPSILON); + Assertions.assertEquals(Math.ceil( 10000 / (13.88) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(0), MatsimTestUtils.EPSILON, "Wrong travel time (car user)"); } @Test - public void testInfrastructureSpeedFactorDistanceMoreRelevantThanTravelTime() { + void testInfrastructureSpeedFactorDistanceMoreRelevantThanTravelTime() { Config config = ConfigUtils.createConfig(utils.getClassInputDirectory() ); BicycleConfigGroup bicycleConfigGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); - config.controler().setWriteEventsInterval(0); - config.controler().setWritePlansInterval(0); - config.controler().setCreateGraphs(false); - config.controler().setDumpDataAtEnd(false); + config.controller().setWriteEventsInterval(0); + config.controller().setWritePlansInterval(0); + config.controller().setCreateGraphs(false); + config.controller().setDumpDataAtEnd(false); config.qsim().setStartTime(6. * 3600.); config.qsim().setEndTime(14. * 3600.); @@ -551,41 +563,41 @@ public void testInfrastructureSpeedFactorDistanceMoreRelevantThanTravelTime() { mainModeList.add(TransportMode.car); config.qsim().setMainModes(mainModeList); - config.strategy().setMaxAgentPlanMemorySize(5); + config.replanning().setMaxAgentPlanMemorySize(5); { StrategySettings strategySettings = new StrategySettings(); strategySettings.setStrategyName("ChangeExpBeta"); strategySettings.setWeight(1.0); - config.strategy().addStrategySettings(strategySettings); + config.replanning().addStrategySettings(strategySettings); } ActivityParams homeActivity = new ActivityParams("home"); homeActivity.setTypicalDuration(12*60*60); - config.planCalcScore().addActivityParams(homeActivity); + config.scoring().addActivityParams(homeActivity); ActivityParams workActivity = new ActivityParams("work"); workActivity.setTypicalDuration(8*60*60); - config.planCalcScore().addActivityParams(workActivity); + config.scoring().addActivityParams(workActivity); ModeParams bicycle = new ModeParams("bicycle"); bicycle.setConstant(0.); bicycle.setMarginalUtilityOfDistance(-999999); // util/m bicycle.setMarginalUtilityOfTraveling(-6.0); // util/h bicycle.setMonetaryDistanceRate(0.); - config.planCalcScore().addModeParams(bicycle); + config.scoring().addModeParams(bicycle); - config.plansCalcRoute().setNetworkModes(mainModeList); + config.routing().setNetworkModes(mainModeList); // link 2 has infrastructure speed factor = 1.0, all other links 0.01 config.network().setInputFile("network_infrastructure-speed-factor.xml"); config.plans().setInputFile("population_4.xml"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setLastIteration(0); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(0); config.global().setNumberOfThreads(1); - config.plansCalcRoute().setRoutingRandomness(3.); + config.routing().setRoutingRandomness(3.); Scenario scenario = ScenarioUtils.loadScenario(config); var vf = scenario.getVehicles().getFactory(); @@ -610,11 +622,11 @@ public void testInfrastructureSpeedFactorDistanceMoreRelevantThanTravelTime() { controler.run(); - Assert.assertEquals("All bicycle users should use the shortest route even though the bicycle infrastructur speed factor is set to 0.1", 4, linkHandler.getLinkId2demand().get(Id.createLinkId("6")), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (car user)", Math.ceil(10000 / 13.88 ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(0), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (bicycle user)", Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(1), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (bicycle user)", Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(2), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time (bicycle user)", Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(3), MatsimTestUtils.EPSILON); + Assertions.assertEquals(4, linkHandler.getLinkId2demand().get(Id.createLinkId("6")), MatsimTestUtils.EPSILON, "All bicycle users should use the shortest route even though the bicycle infrastructur speed factor is set to 0.1"); + Assertions.assertEquals(Math.ceil(10000 / 13.88 ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(0), MatsimTestUtils.EPSILON, "Wrong travel time (car user)"); + Assertions.assertEquals(Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(1), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); + Assertions.assertEquals(Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(2), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); + Assertions.assertEquals(Math.ceil( 10000 / (25. * 0.1 / 3.6) ), linkHandler.getLinkId2travelTimes().get(Id.createLinkId("6")).get(3), MatsimTestUtils.EPSILON, "Wrong travel time (bicycle user)"); } private Config createConfig( int lastIteration ){ @@ -626,13 +638,13 @@ private Config createConfig( int lastIteration ){ // Normal network config.network().setInputFile( "network_normal.xml" ); config.plans().setInputFile( "population_1200.xml" ); - config.controler().setOverwriteFileSetting( OverwriteFileSetting.deleteDirectoryIfExists ); - config.controler().setOutputDirectory( utils.getOutputDirectory() ); - config.controler().setLastIteration( lastIteration ); - config.controler().setLastIteration( lastIteration ); - config.controler().setWriteEventsInterval( 10 ); - config.controler().setWritePlansInterval( 10 ); - config.controler().setCreateGraphs( false ); + config.controller().setOverwriteFileSetting( OverwriteFileSetting.deleteDirectoryIfExists ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setLastIteration( lastIteration ); + config.controller().setLastIteration( lastIteration ); + config.controller().setWriteEventsInterval( 10 ); + config.controller().setWritePlansInterval( 10 ); + config.controller().setCreateGraphs( false ); return config; } diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsBuilderImpl.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsBuilderImpl.java index 5ed2c548e58..c601376b19b 100644 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsBuilderImpl.java +++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsBuilderImpl.java @@ -25,6 +25,7 @@ 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.Identifiable; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.gbl.MatsimRandom; @@ -44,9 +45,8 @@ public final class CadytsBuilderImpl { private CadytsBuilderImpl(){} // do not instantiate - public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(final Config config, final Counts occupCounts, - LookUpItemFromId lookUp, Class idType) { - + public static > AnalyticalCalibrator buildCalibratorAndAddMeasurements(final Config config, final Counts occupCounts, + LookUpItemFromId lookUp, Class idType) { if (occupCounts.getCounts().size() == 0) { log.warn("Counts container is empty."); } @@ -54,7 +54,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina CadytsConfigGroup cadytsConfig = ConfigUtils.addOrGetModule(config, CadytsConfigGroup.GROUP_NAME, CadytsConfigGroup.class); AnalyticalCalibrator matsimCalibrator = buildCalibrator(config); - + int multiple = cadytsConfig.getTimeBinSize() / 3600 ; // e.g. "3" when timeBinSize_s = 3*3600 = 10800 // If I remember correctly, the following is trying to get around the fact that the counts time bins are fixed at hourly, but we want to @@ -64,16 +64,16 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina // yyyy However, it seems that some of this did not work: We are using "hourly" counts, and dividing the multi-hour values by // the number of hours. ??????? - + // yyyyyy I am currently of the opinion that the multi-hour version should be decoupled from the counts format. There is a // cadyts file format which allows setting mult-hour measurements, and that seems a lot more direct than trying to use a file // format/data structure which is really not meant for this. kai, dec'13 - + //add counts data into calibrator int numberOfAddedMeasurements = 0 ; for (Map.Entry, Count> entry : occupCounts.getCounts().entrySet()) { // (loop over all counting "items" (usually locations/stations) - + T item = lookUp.getItem(Id.create(entry.getKey(), idType)) ; if ( item==null ) { throw new RuntimeException("item is null; entry=" + entry + " idType=" + idType ) ; @@ -83,7 +83,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina double count = -1 ; for (Volume volume : entry.getValue().getVolumes().values()){ // (loop over the different time slots) - + if ( timeBinIndex%multiple == 0 ) { // (i.e. first timeBinIndex belonging to given bin) @@ -95,7 +95,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina log.warn( " NOT adding measurement: timeBinIndex: " + timeBinIndex + "; multiple: " + multiple ) ; } else { // (i.e. last timeBinIndex belonging to given bin) - + int endTimeOfBin_s = volume.getHourOfDayStartingWithOne()*3600 - 1 ; if ( !( cadytsConfig.getStartTime() <= startTimeOfBin_s && endTimeOfBin_s <= cadytsConfig.getEndTime()) ) { log.warn( " NOT adding measurement: cadytsConfigStartTime: " + cadytsConfig.getStartTime() + "; startTimeOfBin_s: " + startTimeOfBin_s + @@ -105,7 +105,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina // matsimCalibrator.addMeasurement(item, startTimeOfBin_s, endTimeOfBin_s, count/multiple, SingleLinkMeasurement.TYPE.FLOW_VEH_H); matsimCalibrator.addMeasurement(item, startTimeOfBin_s, endTimeOfBin_s, count, SingleLinkMeasurement.TYPE.COUNT_VEH ); - // changed this from FLOW_VEH_H to COUNT_VEH on 30/jul/2012 since this is no longer "hourly". + // changed this from FLOW_VEH_H to COUNT_VEH on 30/jul/2012 since this is no longer "hourly". // kai/manuel, jul'12 // Despite the above comment, I am finding this with FLOW_VEH_H. Why? kai, feb'13 // yyyyyy For the test case, this seems to produce weird results. The expected counts are 1 and 5, the expected result is 0 and 4. @@ -120,7 +120,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina if ( numberOfAddedMeasurements==0 ) { log.warn("No measurements were added."); } - + if ( matsimCalibrator.getProportionalAssignment() ) { throw new RuntimeException("Gunnar says that this may not work so do not set to true. kai, sep'14") ; } @@ -129,7 +129,7 @@ public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(fina public static AnalyticalCalibrator buildCalibrator(final Config config) { CadytsConfigGroup cadytsConfig = ConfigUtils.addOrGetModule(config, CadytsConfigGroup.GROUP_NAME, CadytsConfigGroup.class ) ; - + //get timeBinSize_s and validate it if ((Time.MIDNIGHT % cadytsConfig.getTimeBinSize())!= 0 ){ throw new RuntimeException("Cadyts requires a divisor of 86400 as time bin size value ."); @@ -138,10 +138,10 @@ public static AnalyticalCalibrator buildCalibrator(final Config config) { throw new RuntimeException("At this point, time bin sizes need to be multiples of 3600. This is not a restriction " + "of Cadyts, but of the counts file format, which only allows for hourly inputs") ; } - - + + AnalyticalCalibrator matsimCalibrator = new AnalyticalCalibrator<>( - config.controler().getOutputDirectory() + "/cadyts.log", + config.controller().getOutputDirectory() + "/cadyts.log", MatsimRandom.getLocalInstance().nextLong(),cadytsConfig.getTimeBinSize() ) ; @@ -159,9 +159,9 @@ public static AnalyticalCalibrator buildCalibrator(final Config config) { if ( matsimCalibrator.getBruteForce() ) { log.warn("setting bruteForce==true for calibrator, but this won't do anything in the way the cadyts matsim integration is set up. kai, mar'14") ; } - - matsimCalibrator.setStatisticsFile(config.controler().getOutputDirectory() + "/calibration-stats.txt"); + + matsimCalibrator.setStatisticsFile(config.controller().getOutputDirectory() + "/calibration-stats.txt"); return matsimCalibrator; } - + } diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsPlanChanger.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsPlanChanger.java index 4f0be74b8d4..f3a02a0bf4a 100644 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsPlanChanger.java +++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsPlanChanger.java @@ -43,9 +43,9 @@ public class CadytsPlanChanger implements PlanSelector { public CadytsPlanChanger(Scenario scenario, CadytsContextI cadytsContext) { this.cadytsContext = cadytsContext; - this.beta = scenario.getConfig().planCalcScore().getBrainExpBeta() ; + this.beta = scenario.getConfig().scoring().getBrainExpBeta() ; } - + @Override public Plan selectPlan(final HasPlansAndId person) { final Plan currentPlan = person.getSelectedPlan(); @@ -90,4 +90,4 @@ public Plan selectPlan(final HasPlansAndId person) { public void setCadytsWeight(double cadytsWeight) { this.cadytsWeight = cadytsWeight; } -} \ No newline at end of file +} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsScoring.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsScoring.java index a19b191361d..e2841dd19b8 100644 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsScoring.java +++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/general/CadytsScoring.java @@ -45,7 +45,7 @@ public CadytsScoring(final Plan plan, Config config, final CadytsContextI con this.plansTranslator = context.getPlansTranslator(); this.matsimCalibrator = context.getCalibrator(); this.plan = plan; - this.beta = config.planCalcScore().getBrainExpBeta(); + this.beta = config.scoring().getBrainExpBeta(); } @Override diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsBuilderImplGT.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsBuilderImplGT.java deleted file mode 100644 index 1165c45aed3..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsBuilderImplGT.java +++ /dev/null @@ -1,87 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.cadyts.pt; - -import java.util.Map; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Id; -import org.matsim.contrib.cadyts.general.CadytsBuilderImpl; -import org.matsim.contrib.cadyts.general.LookUpItemFromId; -import org.matsim.core.config.Config; -import org.matsim.counts.Count; -import org.matsim.counts.Counts; -import org.matsim.counts.Volume; - -import cadyts.calibrators.analytical.AnalyticalCalibrator; -import cadyts.measurements.SingleLinkMeasurement; - -/** - * @author nagel - * @author mrieser - */ -public final class CadytsBuilderImplGT { - // yyyy why "GT"? Is this a typo and should have been PT (or Pt, to be consistent with other classes)? kai, feb'20 - - // yy I also don't know where and when this is used to I am commenting it out to see if someone complains. kai, feb'20 - -// private static Logger log = LogManager.getLogger( CadytsBuilderImplGT.class ) ; -// -// private CadytsBuilderImplGT(){} // do not instantiate -// -// public static AnalyticalCalibrator buildCalibratorAndAddMeasurements(final Config config, final Counts occupCounts, -// LookUpItemFromId lookUp, Class idType ) { -// -// if (occupCounts.getCounts().size() == 0) { -// log.warn("Counts container is empty."); -// } -// -// AnalyticalCalibrator matsimCalibrator = CadytsBuilderImpl.buildCalibrator(config); -// -// //add counts data into calibrator -// int numberOfAddedMeasurements = 0 ; -// for (Map.Entry, Count> entry : occupCounts.getCounts().entrySet()) { -// // (loop over all counting "items" (usually locations/stations) -// -// T item = lookUp.getItem(Id.create(entry.getKey(), idType)) ; -// if ( item==null ) { -// throw new RuntimeException("item is null; entry=" + entry + " idType=" + idType ) ; -// } -// -// double sum = 0; -// for (Volume volume : entry.getValue().getVolumes().values()){ -// // (loop over the different time slots) -// sum += volume.getValue() ; -// } -// numberOfAddedMeasurements++ ; -// matsimCalibrator.addMeasurement(item, 0, 86400, sum, SingleLinkMeasurement.TYPE.COUNT_VEH ); -// } -// -// if ( numberOfAddedMeasurements==0 ) { -// log.warn("No measurements were added."); -// } -// -// if ( matsimCalibrator.getProportionalAssignment() ) { -// throw new RuntimeException("Gunnar says that this may not work so do not set to true. kai, sep'14") ; -// } -// return matsimCalibrator; -// } -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtContext.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtContext.java deleted file mode 100644 index e1f918c4ac1..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtContext.java +++ /dev/null @@ -1,265 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2013 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.contrib.cadyts.pt; - -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; - -import jakarta.inject.Inject; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.analysis.IterationStopWatch; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.population.Person; -import org.matsim.contrib.cadyts.general.CadytsBuilderImpl; -import org.matsim.contrib.cadyts.general.CadytsConfigGroup; -import org.matsim.contrib.cadyts.general.CadytsContextI; -import org.matsim.contrib.cadyts.general.CadytsCostOffsetsXMLFileIO; -import org.matsim.contrib.cadyts.general.PlansTranslator; -import org.matsim.core.api.experimental.events.EventsManager; -import org.matsim.core.config.Config; -import org.matsim.core.config.groups.PtCountsConfigGroup; -import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.controler.events.AfterMobsimEvent; -import org.matsim.core.controler.events.BeforeMobsimEvent; -import org.matsim.core.controler.events.IterationEndsEvent; -import org.matsim.core.controler.events.StartupEvent; -import org.matsim.core.controler.listener.AfterMobsimListener; -import org.matsim.core.controler.listener.BeforeMobsimListener; -import org.matsim.core.controler.listener.IterationEndsListener; -import org.matsim.core.controler.listener.StartupListener; -import org.matsim.core.utils.geometry.CoordinateTransformation; -import org.matsim.core.utils.geometry.transformations.TransformationFactory; -import org.matsim.counts.Counts; -import org.matsim.counts.MatsimCountsReader; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitRoute; -import org.matsim.pt.transitSchedule.api.TransitRouteStop; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -import cadyts.calibrators.analytical.AnalyticalCalibrator; -import cadyts.measurements.SingleLinkMeasurement.TYPE; -import cadyts.supply.SimResults; - -/** - * @author nagel - * - */ -public class CadytsPtContext implements StartupListener, IterationEndsListener, BeforeMobsimListener, AfterMobsimListener, -CadytsContextI { - // can be/remain public as long as constructor is package-private. kai, feb'20 - - private final static Logger log = LogManager.getLogger(CadytsPtContext.class); - - private final static String LINKOFFSET_FILENAME = "linkCostOffsets.xml"; - private static final String FLOWANALYSIS_FILENAME = "flowAnalysis.txt"; - private static final String OCCUPANCYANALYSIS_FILENAME = "cadytsPtOccupancyAnalysis.txt"; - - private AnalyticalCalibrator calibrator = null; - private final SimResults simResults; - private final Counts occupCounts = new Counts<>(); - // private final Counts boardCounts = new Counts(); - // private final Counts alightCounts = new Counts(); - private final CadytsPtOccupancyAnalyzerI cadytsPtOccupAnalyzer; - private PtPlanToPlanStepBasedOnEvents ptStep ; - - private CadytsConfigGroup cadytsConfig; - private EventsManager events; - private Scenario scenario; - private OutputDirectoryHierarchy controlerIO; - private IterationStopWatch stopWatch; - - @Inject - CadytsPtContext(final Config config, EventsManager events, Scenario scenario, OutputDirectoryHierarchy controlerIO, - IterationStopWatch stopWatch, final CadytsPtOccupancyAnalyzerI cadytsPtOccupancyAnalyzer ) { - this.events = events; - this.scenario = scenario; - this.controlerIO = controlerIO; - this.stopWatch = stopWatch; - cadytsConfig = (CadytsConfigGroup) config.getModule(CadytsConfigGroup.GROUP_NAME); - this.cadytsPtOccupAnalyzer = cadytsPtOccupancyAnalyzer ; - - // === prepare the structure which extracts the measurements from the simulation: - // since there is already some other method, we just need to write a wrapper. - -// this.cadytsPtOccupAnalyzer = new CadytsPtOccupancyAnalyzer(CadytsPtOccupancyAnalyzer.toTransitLineIdSet(cadytsConfig.getCalibratedItems()), cadytsConfig.getTimeBinSize() ); - events.addHandler(this.cadytsPtOccupAnalyzer); - - this.simResults = new SimResults() { - private static final long serialVersionUID = 1L; - @Override - public double getSimValue(TransitStopFacility stop, int startTime_s, int endTime_s, TYPE type) { - final int timeBinSize_s = cadytsConfig.getTimeBinSize() ; - final double countsScaleFactor = config.ptCounts().getCountsScaleFactor() ; - double retval = 0. ; - switch ( type ) { - case COUNT_VEH: - retval = cadytsPtOccupAnalyzer.getOccupancyVolumeForStopAndTime(stop.getId(), startTime_s) * countsScaleFactor ; - break; - case FLOW_VEH_H: - int multiple = timeBinSize_s / 3600 ; // e.g. "3" when timeBinSize_s = 3*3600 = 10800 - retval = cadytsPtOccupAnalyzer.getOccupancyVolumeForStopAndTime(stop.getId(), startTime_s) * countsScaleFactor / multiple ; - break; - default: - throw new RuntimeException("not implemented ...") ; - } -// if ( retval != 0. ) { -// log.warn("retval=" + retval ); -// } - return retval ; - } - @Override - public String toString() { - return cadytsPtOccupAnalyzer.toString() ; - } - } ; - // === end wrapper === - - } - - @Override - public void notifyStartup(StartupEvent event) { - - // === prepare the calibrator by giving measurements to it: - String occupancyCountsFilename = scenario.getConfig().ptCounts().getOccupancyCountsFileName(); - new MatsimCountsReader(this.occupCounts).readFile(occupancyCountsFilename); - - // === build the calibrator: - this.calibrator = CadytsBuilderImpl.buildCalibratorAndAddMeasurements(scenario.getConfig(), this.occupCounts, new TransitStopFacilityLookUp(scenario) , TransitStopFacility.class); - - // === find out which plan is contributing what to each measurement: - this.ptStep = new PtPlanToPlanStepBasedOnEvents<>(scenario, CadytsPtOccupancyAnalyzer.toTransitLineIdSet(cadytsConfig.getCalibratedLines())); - events.addHandler(ptStep); - } - - @Override - public void notifyBeforeMobsim(final BeforeMobsimEvent event) { - this.cadytsPtOccupAnalyzer.reset(event.getIteration()); - for (Person person : scenario.getPopulation().getPersons().values()) { - this.calibrator.addToDemand(ptStep.getCadytsPlan(person.getSelectedPlan())); - } - } - - @Override - public void notifyAfterMobsim(final AfterMobsimEvent event) { - int it = event.getIteration(); - - // Get all stations of all analyzed lines and invoke the method write to get all information of them - Set> stopIds = new HashSet<>(); - for ( String pseudoLineId : this.cadytsConfig.getCalibratedLines()) { - Id lineId = Id.create(pseudoLineId, TransitLine.class); - TransitLine line = scenario.getTransitSchedule().getTransitLines().get(lineId); - for (TransitRoute route : line.getRoutes().values()) { - for (TransitRouteStop stop : route.getStops()) { - stopIds.add(stop.getStopFacility().getId()); - } - } - } - String outFile = controlerIO.getIterationFilename(it, OCCUPANCYANALYSIS_FILENAME); - this.cadytsPtOccupAnalyzer.writeResultsForSelectedStopIds(outFile, this.occupCounts, stopIds); - } - - @Override - public void notifyIterationEnds(final IterationEndsEvent event) { - if (cadytsConfig.isWriteAnalysisFile()) { - String analysisFilepath = controlerIO.getIterationFilename(event.getIteration(), FLOWANALYSIS_FILENAME); - this.calibrator.setFlowAnalysisFile(analysisFilepath); - } - - this.calibrator.afterNetworkLoading(this.simResults); - - // write some output - String filename = controlerIO.getIterationFilename(event.getIteration(), LINKOFFSET_FILENAME); - try { - new CadytsCostOffsetsXMLFileIO<>(new TransitStopFacilityLookUp(scenario), TransitStopFacility.class) - .write(filename, this.calibrator.getLinkCostOffsets()); - } catch (IOException e) { - log.error("Could not write link cost offsets!", e); - } - - generateAndWriteCountsComparisons(event); - } - - // =========================================================================================================================== - // private methods & pure delegate methods only below this line - - private void generateAndWriteCountsComparisons(final IterationEndsEvent event) { - if ( this.cadytsConfig.getTimeBinSize()!=3600 ) { - log.warn("generateAndWriteCountsComparisons() does not work when time bin size != 3600. See comments in code. Skipping the comparison ..." ) ; - return ; - // yyyy there are some conceptual problems behind this which are not resolved: - // () There should reasonably be two methods: one describing what cadyts _thinks_ it is comparing, and one that just - // compares the output. There is one methods writing simCountCompare..., and then this one here - // writing cadytsSimCountCompare... . It is not clarified which one is doing which. - // () The method that just compares the output should not rely on cadyts but compute its own observations. -- - // Unfortunately, this collides with the fact that the time bin size is part of the cadyts configuration. This is, in the end, a - // consequence of the fact that the Counts format assumes hourly counts (other than cadyts, which reasonably allows the - // specify the time span for every observation separately). - // kai, feb'13 - } - - - PtCountsConfigGroup ptCountsConfig = scenario.getConfig().ptCounts(); - if (ptCountsConfig.getOccupancyCountsFileName() == null) { // yyyy this check should reasonably also be done in isActiveInThisIteration. kai,oct'10 - log.warn("generateAndWriteCountsComparisons() does not work since occupancy counts file name not given ") ; - return ; - } - int iter = event.getIteration(); - - stopWatch.beginOperation("compare with pt counts"); - - Network network = scenario.getNetwork(); - CadytsPtCountsComparisonAlgorithm ccaOccupancy = new CadytsPtCountsComparisonAlgorithm(this.cadytsPtOccupAnalyzer, - this.occupCounts, network, scenario.getConfig().ptCounts().getCountsScaleFactor()); - - Double distanceFilter = ptCountsConfig.getDistanceFilter(); - String distanceFilterCenterNodeId = ptCountsConfig.getDistanceFilterCenterNode(); - if ((distanceFilter != null) && (distanceFilterCenterNodeId != null)) { - ccaOccupancy.setDistanceFilter(distanceFilter, distanceFilterCenterNodeId); - } - - ccaOccupancy.calculateComparison(); - - String outputFormat = ptCountsConfig.getOutputFormat(); - if (outputFormat.contains("txt") || outputFormat.contains("all")) { - // As far as I can tell, this file is written twice, the other times without the "cadyts" part. kai, feb'13 - // yyyyyy As far as I can tell, the version here is wrong as soon as the time bin is different from 3600.--?? kai, feb'13 - // See near beginning of method. kai, feb'13 - ccaOccupancy.write(controlerIO.getIterationFilename(iter, "cadytsSimCountCompareOccupancy.txt")); - } - - stopWatch.endOperation("compare with pt counts"); - } - - @Override - public AnalyticalCalibrator getCalibrator() { - return calibrator; - } - - @Override - public PlansTranslator getPlansTranslator() { - return ptStep; - } - -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtCountsComparisonAlgorithm.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtCountsComparisonAlgorithm.java deleted file mode 100644 index 6327a98260f..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtCountsComparisonAlgorithm.java +++ /dev/null @@ -1,185 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.cadyts.pt; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Identifiable; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.Node; -import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.counts.Count; -import org.matsim.counts.CountSimComparison; -import org.matsim.counts.CountSimComparisonImpl; -import org.matsim.counts.Counts; -import org.matsim.counts.Volume; -import org.matsim.pt.counts.SimpleWriter; - -/** - * This is a modified copy of CountsComparisonAlgorithm, in order to realize the same functionality - * for pt counts. - */ -final class CadytsPtCountsComparisonAlgorithm { - /** - * The StopAttributes of the simulation - */ - private final CadytsPtOccupancyAnalyzerI oa; - /** - * The counts object - */ - Counts counts; - // needed in CadytsErrorPlot - - /** - * The result list - */ - private final List countSimComp; - - private Node distanceFilterNode = null; - - private Double distanceFilter = null; - - private final Network network; - - double countsScaleFactor; // needed in CadytsErrorPlot - - final static Logger log = LogManager.getLogger(CadytsPtCountsComparisonAlgorithm.class); - - StringBuffer content = new StringBuffer(); - - CadytsPtCountsComparisonAlgorithm(final CadytsPtOccupancyAnalyzerI oa, final Counts counts, final Network network, final double countsScaleFactor) { - this.oa = oa; - this.counts = counts; - this.countSimComp = new ArrayList(); - this.network = network; - this.countsScaleFactor = countsScaleFactor; - } - - /** - * Creates the List with the counts vs sim values stored in the countAttribute Attribute of this - * class. - */ - final String STR_NOVOLUMES = "No volumes for stop: "; - final String STR_STOPID = "StopId :\t"; - final String STR_HEAD = "\nhour\tsimVal\tscaledSimVal\tcountVal\n"; - final char CHR_HT = '\t'; - final char CHR_NL = '\n'; - - public void calculateComparison() { - double countValue; - for (Count count : this.counts.getCounts().values()) { - Id stopId = count.getId(); - if (!isInRange(count.getCoord())) { - continue; - } - int[] volumes = this.getVolumesForStop(stopId); - if (volumes == null) { - log.warn(this.STR_NOVOLUMES + stopId); - continue; - } else /* volumes!=null */if (volumes.length == 0) { - log.warn(this.STR_NOVOLUMES + stopId); - continue; - } - - this.content.append(this.STR_STOPID); - this.content.append(stopId.toString()); - this.content.append(this.STR_HEAD); - - for (int hour = 1; hour <= volumes.length; hour++) { - // real volumes: - Volume volume = count.getVolume(hour); - if (volume != null) { - - this.content.append(hour); - this.content.append(this.CHR_HT); - - countValue = volume.getValue(); - double simValue = volumes[hour - 1]; - - this.content.append(simValue); - this.content.append(this.CHR_HT); - - simValue *= this.countsScaleFactor; - - this.content.append(simValue); - this.content.append(this.CHR_HT); - this.content.append(countValue); - this.content.append(this.CHR_NL); - - this.countSimComp.add(new CountSimComparisonImpl(stopId, hour, countValue, simValue)); - - } else { - countValue = 0.0; - } - - } - } - } - - int[] getVolumesForStop(final Id stopId) { - return this.oa.getOccupancyVolumesForStop(stopId); - } - - /** - * - * @param stopCoord - * @return true if the Link with the given Id is not farther away than the - * distance specified by the distance filter from the center node of the filter. - */ - boolean isInRange(final Coord stopCoord) { - if ((this.distanceFilterNode == null) || (this.distanceFilter == null)) { - return true; - } - - double dist = CoordUtils.calcEuclideanDistance(stopCoord, this.distanceFilterNode.getCoord()); - return dist < this.distanceFilter.doubleValue(); - } - - /** - * - * @return the result list - */ - public List getComparison() { - return this.countSimComp; - } - - /** - * Set a distance filter, dropping everything out which is not in the distance given in meters - * around the given Node Id. - * - * @param distance - * @param nodeId - */ - public void setDistanceFilter(final Double distance, final String nodeId) { - this.distanceFilter = distance; - this.distanceFilterNode = this.network.getNodes().get(Id.create(nodeId, Node.class)); - } - - public void write(final String outputFilename) { - final SimpleWriter simpleWriter = new SimpleWriter(outputFilename); - simpleWriter.write(this.content.toString()); - simpleWriter.close(); - } -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtModule.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtModule.java deleted file mode 100644 index d9f459047b3..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtModule.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.matsim.contrib.cadyts.pt; - - -import org.matsim.core.controler.AbstractModule; - -import jakarta.inject.Singleton; - -public class CadytsPtModule extends AbstractModule { - @Override - public void install() { - bind(CadytsPtContext.class).in( Singleton.class ); - addControlerListenerBinding().to(CadytsPtContext.class); - bind(CadytsPtOccupancyAnalyzerI.class).to(CadytsPtOccupancyAnalyzer.class); - } -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzer.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzer.java deleted file mode 100644 index c116c652e0c..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzer.java +++ /dev/null @@ -1,299 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.cadyts.pt; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import jakarta.inject.Inject; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.events.PersonEntersVehicleEvent; -import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent; -import org.matsim.api.core.v01.events.TransitDriverStartsEvent; -import org.matsim.api.core.v01.network.Link; -import org.matsim.contrib.cadyts.general.CadytsConfigGroup; -import org.matsim.core.api.experimental.events.VehicleArrivesAtFacilityEvent; -import org.matsim.core.api.experimental.events.VehicleDepartsAtFacilityEvent; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.utils.misc.Time; -import org.matsim.counts.Count; -import org.matsim.counts.Counts; -import org.matsim.counts.Volume; -import org.matsim.pt.counts.SimpleWriter; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; -import org.matsim.vehicles.Vehicle; - -/** - * Collects occupancy data of transit-line stations - *

- * This is probably similar to code elsewhere. However, it makes some sense to keep this here since the correct workings of cadyts - * (obviously) depends on the fact that the counts are actually what it thinks, and so it makes sense to decouple this from the upstream - * counting method and leave it here. kai, sep'13 - */ -final class CadytsPtOccupancyAnalyzer implements CadytsPtOccupancyAnalyzerI { - // can be/remain public as long as constructor is package-private. kai, feb'20 - - private final int timeBinSize, maxSlotIndex; - private final double maxTime; - private Map, int[]> occupancies; // Map< stopFacilityId,value[]> - private final Map, Id> vehStops = new HashMap<>(); // Map< vehId,stopFacilityId> - private final Map, Integer> vehPassengers = new HashMap<>(); // Map - private StringBuffer occupancyRecord = new StringBuffer("time\tvehId\tStopId\tno.ofPassengersInVeh\n"); - private final Set analyzedTransitDrivers = new HashSet<>(); - private final Set analyzedTransitVehicles = new HashSet<>(); - private final Set> calibratedLines; - - @Inject - CadytsPtOccupancyAnalyzer( Config config ) { - CadytsConfigGroup ccc = ConfigUtils.addOrGetModule(config, CadytsConfigGroup.class ) ; - - this.calibratedLines = toTransitLineIdSet( ccc.getCalibratedLines() ) ; - this.timeBinSize = ccc.getTimeBinSize() ; - - this.maxTime = Time.MIDNIGHT-1; //24 * 3600 - 1; - // (yy not completely clear if it might be better to use 24*this.timeBimSize, but it is overall not so great - // to have this hardcoded. kai/manuel, jul'12) - - this.maxSlotIndex = ((int) this.maxTime) / this.timeBinSize + 1; - this.occupancies = new HashMap<>(); - } - - @Override - public void reset(final int iteration) { - this.occupancies.clear(); - this.vehStops.clear(); - this.vehPassengers.clear(); - this.occupancyRecord = new StringBuffer("time\tvehId\tStopId\tno.ofPassengersInVeh\n"); - this.analyzedTransitDrivers.clear(); - this.analyzedTransitVehicles.clear(); - } - - @Override - public void handleEvent(final TransitDriverStartsEvent event) { - if (this.calibratedLines.contains(event.getTransitLineId())) { - this.analyzedTransitDrivers.add(event.getDriverId()); - this.analyzedTransitVehicles.add(event.getVehicleId()); - } - } - - @Override - public void handleEvent(final PersonEntersVehicleEvent event) { - if (this.analyzedTransitDrivers.contains(event.getPersonId()) || !this.analyzedTransitVehicles.contains(event.getVehicleId())) { - return; // ignore transit drivers or persons entering non-(analyzed-)transit vehicles - } - - // ------------------veh_passenger- (for occupancy)----------------- - Id vehId = event.getVehicleId(); - Id stopId = this.vehStops.get(vehId); - double time = event.getTime(); - Integer nPassengers = this.vehPassengers.get(vehId); - this.vehPassengers.put(vehId, (nPassengers != null) ? (nPassengers + 1) : 1); - this.occupancyRecord.append("time :\t").append(time).append(" veh :\t").append(vehId).append(" has Passenger\t").append(this.vehPassengers.get(vehId)).append(" \tat stop :\t").append(stopId).append(" ENTERING PERSON :\t").append(event.getPersonId()).append("\n"); - } - - @Override - public void handleEvent(final PersonLeavesVehicleEvent event) { - if (this.analyzedTransitDrivers.contains(event.getPersonId()) || !this.analyzedTransitVehicles.contains(event.getVehicleId())) { - return; // ignore transit drivers or persons entering non-(analyzed-)transit vehicles - } - - // ----------------veh_passenger-(for occupancy)-------------------------- - Id vehId = event.getVehicleId(); - double time = event.getTime(); - Integer nPassengers = this.vehPassengers.get(vehId); - if (nPassengers == null) { - throw new RuntimeException("null passenger-No. in vehicle ?"); - } - this.vehPassengers.put(vehId, nPassengers - 1); - if (this.vehPassengers.get(vehId) == 0) { - this.vehPassengers.remove(vehId); - } - Integer passengers = this.vehPassengers.get(vehId); - this.occupancyRecord.append("time :\t").append(time).append(" veh :\t").append(vehId).append(" has Passenger\t").append((passengers != null) ? passengers : 0).append("\n"); - } - - @Override - public void handleEvent(final VehicleDepartsAtFacilityEvent event) { - Id vehId = event.getVehicleId(); - Id facId = event.getFacilityId(); - - // -----------------------occupancy-------------------------------- - this.vehStops.remove(vehId); - int[] occupancyAtStop = this.occupancies.get(facId); - if (occupancyAtStop == null) { // no previous departure from this stop, therefore no occupancy - // record yet. Create this: - occupancyAtStop = new int[this.maxSlotIndex + 1]; - this.occupancies.put(facId, occupancyAtStop); - } - - Integer noPassengersInVeh = this.vehPassengers.get(vehId); - - if (noPassengersInVeh != null) { - occupancyAtStop[this.getTimeSlotIndex(event.getTime())] += noPassengersInVeh; - this.occupancyRecord.append(event.getTime()); - this.occupancyRecord.append("\t"); - this.occupancyRecord.append(vehId); - this.occupancyRecord.append("\t"); - this.occupancyRecord.append(facId); - this.occupancyRecord.append("\t"); - this.occupancyRecord.append(noPassengersInVeh); - this.occupancyRecord.append("\n"); - } - } - - @Override - public void handleEvent(final VehicleArrivesAtFacilityEvent event) { - Id stopId = event.getFacilityId(); - - this.vehStops.put(event.getVehicleId(), stopId); - // (constructing a table with vehId as key, and stopId as value; constructed when veh arrives at - // stop; necessary - // since personEnters/LeavesVehicle does not carry stop id) - } - - private int getTimeSlotIndex(final double time) { - if (time > this.maxTime) { - return this.maxSlotIndex; - } - return ((int) time / this.timeBinSize); - } - - /** - * @param stopId - * @return Array containing the number of passengers in bus after the transfer at the stop - * {@code stopId} per time bin, starting with time bin 0 from 0 seconds to - * (timeBinSize-1)seconds. - */ - @Override - public int[] getOccupancyVolumesForStop(final Id stopId) { - return this.occupancies.get(stopId); - } - /* (non-Javadoc) - * @see org.matsim.contrib.cadyts.pt.CadytsPtOccupancyAnalyzerI#getOccupancyVolumeForStopAndTime(org.matsim.api.core.v01.Id, int) - */ - @Override - public int getOccupancyVolumeForStopAndTime(final Id stopId, final int time_s ) { - if ( this.occupancies.get(stopId) != null ) { - int timeBinIndex = getTimeSlotIndex( time_s ) ; - return this.occupancies.get(stopId)[timeBinIndex] ; - } else { - return 0 ; - } - } - - public Set> getOccupancyStopIds() { - return this.occupancies.keySet(); - } - - @Override - public void writeResultsForSelectedStopIds(final String filename, final Counts occupCounts, final Collection> stopIds) { - SimpleWriter writer = new SimpleWriter(filename); - - final String TAB = "\t"; - final String NL = "\n"; - - // write header - writer.write("stopId\t"); - for (int i = 0; i < 24; i++) { - writer.write("oc" + i + "-" + (i + 1) + TAB); - } - for (int i = 0; i < 24; i++) { - writer.write("scalSim" + i + "-" + (i + 1) + TAB); - } - writer.write("coordinate\tcsId\n"); - - // write content - for (Id stopId : stopIds) { - // get count data - Count count = occupCounts.getCounts().get(Id.create(stopId, TransitStopFacility.class)); - if (!occupCounts.getCounts().containsKey(Id.create(stopId, TransitStopFacility.class))) { - continue; - } - - // get sim-Values - int[] ocuppancy = this.occupancies.get(stopId); - writer.write(stopId.toString() + TAB); - for (int i = 0; i < ocuppancy.length; i++) { - Volume v = count.getVolume(i + 1); - if (v != null) { - writer.write(v.getValue() + TAB); - } else { - writer.write("n/a" + TAB); - } - } - for (int anOcuppancy : ocuppancy) { - writer.write((anOcuppancy) + TAB); - } - writer.write(count.getCoord().toString() + TAB + count.getCsLabel() + NL); - } - writer.write(this.occupancyRecord.toString()); - writer.close(); - } - - @Override - public String toString() { - final StringBuilder stringBuffer2 = new StringBuilder(); - final String STOPID = "stopId: "; - final String VALUES = "; values:"; - final char TAB = '\t'; - final char RETURN = '\n'; - - for (Id stopId : this.getOccupancyStopIds()) { // Only occupancy! - StringBuilder stringBuffer = new StringBuilder(); - stringBuffer.append(STOPID); - stringBuffer.append(stopId); - stringBuffer.append(VALUES); - - boolean hasValues = false; // only prints stops with volumes > 0 - int[] values = this.getOccupancyVolumesForStop(stopId); - - for (int value : values) { - hasValues = hasValues || (value > 0); - - stringBuffer.append(TAB); - stringBuffer.append(value); - } - stringBuffer.append(RETURN); - if (hasValues) - stringBuffer2.append(stringBuffer.toString()); - - } - return stringBuffer2.toString(); - } - - public static Set> toTransitLineIdSet(Set list) { - Set> converted = new LinkedHashSet<>(); - - for ( String id : list) { - converted.add(Id.create(id, TransitLine.class)); - } - - return converted; - } - - -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzerI.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzerI.java deleted file mode 100644 index 069fe358fd9..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/CadytsPtOccupancyAnalyzerI.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.matsim.contrib.cadyts.pt; - -import java.util.Collection; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler; -import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler; -import org.matsim.api.core.v01.events.handler.TransitDriverStartsEventHandler; -import org.matsim.api.core.v01.network.Link; -import org.matsim.core.api.experimental.events.handler.VehicleArrivesAtFacilityEventHandler; -import org.matsim.core.api.experimental.events.handler.VehicleDepartsAtFacilityEventHandler; -import org.matsim.counts.Counts; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -public interface CadytsPtOccupancyAnalyzerI extends TransitDriverStartsEventHandler, PersonEntersVehicleEventHandler, -PersonLeavesVehicleEventHandler, VehicleArrivesAtFacilityEventHandler, VehicleDepartsAtFacilityEventHandler { - - int getOccupancyVolumeForStopAndTime(Id stopId, int time_s); - - void writeResultsForSelectedStopIds(String filename, Counts occupCounts, Collection> stopIds); - - int[] getOccupancyVolumesForStop(Id stopId); - -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/PtPlanToPlanStepBasedOnEvents.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/PtPlanToPlanStepBasedOnEvents.java deleted file mode 100644 index f9ab329ad5a..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/PtPlanToPlanStepBasedOnEvents.java +++ /dev/null @@ -1,238 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.cadyts.pt; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.events.PersonEntersVehicleEvent; -import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent; -import org.matsim.api.core.v01.events.TransitDriverStartsEvent; -import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler; -import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler; -import org.matsim.api.core.v01.events.handler.TransitDriverStartsEventHandler; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Plan; -import org.matsim.contrib.cadyts.general.PlansTranslator; -import org.matsim.core.api.experimental.events.VehicleDepartsAtFacilityEvent; -import org.matsim.core.api.experimental.events.handler.VehicleDepartsAtFacilityEventHandler; -import org.matsim.core.scenario.MutableScenario; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -import cadyts.demand.PlanBuilder; - -/*package*/ class PtPlanToPlanStepBasedOnEvents implements TransitDriverStartsEventHandler, PersonEntersVehicleEventHandler, - PersonLeavesVehicleEventHandler, VehicleDepartsAtFacilityEventHandler, PlansTranslator { - private static final Logger log = LogManager.getLogger(PtPlanToPlanStepBasedOnEvents.class); - - private final Scenario sc; - private final TransitSchedule schedule; - - private final Map> personsFromVehId = new HashMap<>(); - - private int iteration = -1; - - // this is _only_ there for output: - Set plansEverSeen = new HashSet<>(); - - private static final String STR_PLANSTEPFACTORY = "planStepFactory"; - private static final String STR_ITERATION = "iteration"; - // (better to do it this way since when plans are removed, this additional info is removed as well) - - private final Set transitDrivers = new HashSet<>(); - private final Set transitVehicles = new HashSet<>(); - private final Set> calibratedLines; - - PtPlanToPlanStepBasedOnEvents(final Scenario sc, final Set> calibratedLines) { - this.sc = sc; - this.schedule = ((MutableScenario) sc).getTransitSchedule(); - this.calibratedLines = calibratedLines; - } - - private long plansFound = 0; - private long plansNotFound = 0; - - @Override - public final cadyts.demand.Plan getCadytsPlan(final Plan plan) { - @SuppressWarnings("unchecked") // getting stuff from custom attributes has to be untyped. - PlanBuilder planStepFactory = (PlanBuilder) plan.getCustomAttributes().get(STR_PLANSTEPFACTORY); - if (planStepFactory == null) { - this.plansNotFound++; - return null; - } - this.plansFound++; - final cadyts.demand.Plan planSteps = planStepFactory.getResult(); - return planSteps; - } - - @Override - public void reset(final int it) { - this.iteration = it; - - log.warn("found " + this.plansFound + " out of " + (this.plansFound + this.plansNotFound) + " (" - + (100. * this.plansFound / (this.plansFound + this.plansNotFound)) + "%)"); - log.warn("(above values may both be at zero for a couple of iterations if multiple plans per agent all have no score)"); - - long nPlans = 0 ; - long nMemorizedPlans = 0 ; - - for ( Person person : this.sc.getPopulation().getPersons().values() ) { - for ( Plan plan : person.getPlans() ) { - nPlans ++ ; - @SuppressWarnings("unchecked") // getting stuff from custom attributes has to be untyped. - PlanBuilder planStepFactory = (PlanBuilder) plan.getCustomAttributes().get(STR_PLANSTEPFACTORY); - if ( planStepFactory!=null ) { - nMemorizedPlans ++ ; - } - } - } - - log.warn( "nPlans=" + nPlans + ", nMemorizedPlans=" + nMemorizedPlans ); - - this.personsFromVehId.clear(); - this.transitDrivers.clear(); - this.transitVehicles.clear(); - } - - @Override - public void handleEvent(final TransitDriverStartsEvent event) { - if (this.calibratedLines.contains(event.getTransitLineId())) { - this.transitDrivers.add(event.getDriverId()); - this.transitVehicles.add(event.getVehicleId()); - } - } - - @Override - public void handleEvent(final PersonEntersVehicleEvent event) { - if (this.transitDrivers.contains(event.getPersonId()) || !this.transitVehicles.contains(event.getVehicleId())) { - return; // ignore transit drivers or persons entering non-(analyzed-)transit vehicles - } - addPersonToVehicleContainer(event.getPersonId(), event.getVehicleId()); - } - - @Override - public void handleEvent(final PersonLeavesVehicleEvent event) { - if (this.transitDrivers.contains(event.getPersonId()) || !this.transitVehicles.contains(event.getVehicleId())) { - return; // ignore transit drivers or persons entering non-(analyzed-)transit vehicles - } - removePersonFromVehicleContainer(event.getPersonId(), event.getVehicleId()); - } - - @Override - public void handleEvent(final VehicleDepartsAtFacilityEvent event) { - double time = event.getTime(); - Id vehId = event.getVehicleId(); - Id facId = event.getFacilityId(); - if (this.personsFromVehId.get(vehId) == null) { - // (means nobody has entered the vehicle yet) - return; - } - TransitStopFacility fac = this.schedule.getFacilities().get(facId); - - for (Id personId : this.personsFromVehId.get(vehId)) { - // get the "Person" behind the id: - Person person = this.sc.getPopulation().getPersons().get(personId); - - // get the selected plan: - Plan selectedPlan = person.getSelectedPlan(); - - // get the planStepFactory for the plan (or create one): - PlanBuilder tmpPlanStepFactory = getPlanStepFactoryForPlan(selectedPlan); - - if (tmpPlanStepFactory != null) { - // add the "turn" to the planStepfactory - tmpPlanStepFactory.addTurn(fac, (int) time); - } - } - } - - // ################################################################################### - // only private functions below here (low level functionality) - - private void addPersonToVehicleContainer(final Id personId, final Id vehId) { - // get the personsContainer that belongs to the vehicle: - Collection personsInVehicle = this.personsFromVehId.get(vehId); - - if (personsInVehicle == null) { - // means does not exist yet - personsInVehicle = new ArrayList<>(); - this.personsFromVehId.put(vehId, personsInVehicle); - } - - personsInVehicle.add(personId); - } - - private void removePersonFromVehicleContainer(final Id personId, final Id vehId) { - // get the personsContainer that belongs to the vehicle: - Collection personsInVehicle = this.personsFromVehId.get(vehId); - - if (personsInVehicle == null) { - throw new RuntimeException("should not be possible: person should enter before leaving, and then construct the container"); - } - - // remove the person from the personsContainer: - personsInVehicle.remove(personId); // linear time operation; a HashMap might be better. - } - - private PlanBuilder getPlanStepFactoryForPlan(final Plan selectedPlan) { - PlanBuilder planStepFactory = null; - - planStepFactory = (PlanBuilder) selectedPlan.getCustomAttributes().get(STR_PLANSTEPFACTORY); - Integer factoryIteration = (Integer) selectedPlan.getCustomAttributes().get(STR_ITERATION); - if (planStepFactory == null || factoryIteration == null || factoryIteration != this.iteration) { - // attach the iteration number to the plan: - selectedPlan.getCustomAttributes().put(STR_ITERATION, this.iteration); - - // construct a new PlanBulder and attach it to the plan: - planStepFactory = new PlanBuilder<>(); - selectedPlan.getCustomAttributes().put(STR_PLANSTEPFACTORY, planStepFactory); - - // memorize the plan as being seen: - this.plansEverSeen.add(selectedPlan); - } - - return planStepFactory; - } - - static void printCadytsPlan(final cadyts.demand.Plan cadytsPlan) { - // prints Cadyts plan - String sepCadStr = "==printing Cadyts Plan=="; - System.err.println(sepCadStr); - if (cadytsPlan != null) { - for (int ii = 0; ii < cadytsPlan.size(); ii++) { - cadyts.demand.PlanStep cadytsPlanStep = cadytsPlan.getStep(ii); - System.err.println("stopId" + cadytsPlanStep.getLink().getId() + " time: " + cadytsPlanStep.getEntryTime_s()); - } - } else { - System.err.println(" cadyts plan is null "); - } - } - -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/TransitStopFacilityLookUp.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/TransitStopFacilityLookUp.java deleted file mode 100644 index 651b2a99c66..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/TransitStopFacilityLookUp.java +++ /dev/null @@ -1,48 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* * - * * - * *********************************************************************** * - * * - * copyright : (C) 2008 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.contrib.cadyts.pt; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.cadyts.general.LookUpItemFromId; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -/** - * @author nagel - * - */ -class TransitStopFacilityLookUp implements LookUpItemFromId { - - private TransitSchedule schedule; - - public TransitStopFacilityLookUp( Scenario sc ) { - this.schedule = sc.getTransitSchedule() ; - } - - public TransitStopFacilityLookUp( TransitSchedule schedule ) { - this.schedule = schedule ; - } - - @Override - public TransitStopFacility getItem(Id id) { - return this.schedule.getFacilities().get(id); - } - -} diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/package-info.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/package-info.java deleted file mode 100644 index 0b45babafa5..00000000000 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/pt/package-info.java +++ /dev/null @@ -1,74 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* * - * * - * *********************************************************************** * - * * - * copyright : (C) 2008 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 * - * * - * *********************************************************************** */ -/** - * Integrates automatic calibration upon public transport line occupancies using Cadyts into MATSim. - * - *

Entry point / How to use

- *
    - *
  • Use org.matsim.contrib.cadyts.pt.CadytsPtPlanStrategy as a replanning strategy.
  • - *
  • Add the following configuration parameters (approximately; this has changed since inception; - * check auto-generated config comments; use second config dump for that): - *
    - * <module name="cadytsPt">
    - *   <param name="startTime" value="05:00:00" />
    - *
    - *   <param name="endTime" value="21:00:00" />
    - *
    - *   <!-- Comma-separated list of transit lines to be calibrated. ->
    - *   <param name="calibratedLines" value="M44" />
    - *
    - *   <param name="writeAnalysisFile" value="false" />
    - *
    - *   <!-- see cadyts documentation for the meaning of the following values. -->
    - *   <param name="regressionInertia" value="0.95" />
    - *   <param name="minFlowStddevVehH" value="8.0" />
    - *   <param name="freezeIteration" value="2147483647" />
    - *   <param name="preparatoryIterations" value="1" />
    - *   <param name="varianceScale" value="1.0" />
    - *   <param name="useBruteForce" value="true" />
    - *
    - * </module>
    - * These parameters are defined in {@link org.matsim.contrib.cadyts.general.CadytsConfigGroup} - * - *
  • - *
  • There also needs to be a ptCounts entry, something like: - *
    - *
    - * 	<module name="ptCounts">
    - *		<param name="inputOccupancyCountsFile" value="path-to-counts-file" />
    - *	</module>
    - * And (obviously) a working ptCounts file. - *
  • - *
  • It is a unfortunate that the counts file takes measurements in hourly values, while cadyts takes arbitrary time spans. - * (The cadyts convention seems more powerful, thus we did not want to reduce it to the "Counts" convention.) - * As long as the cadytsPt timeBinSize is set to 3600, things should be straightforward, and there is also (I think) no - * problem if there are measurements for times outside the cadytsPt startTime/endTime interval. yyyy Unfortunately, - * I cannot remember how the counts file is interpreted once the cadytsPt timeBinSize is set to something different: Does the - * Counts file than think in terms of time bins rather than in terms of hours? In fact, I think not; rather, it is probably as - * follows: Counts still refer to hours. If, say, you use timeBinSize of 7200 and start/endTime as 05:00/09:00, then the code - * will aggregate counts from the 6th and 7th hour into one time bin, etc. If things do not correspond, the code will probably - * complain. See CadytsBuilder.buildCalibrator, since there are some consistency checks. (kai, oct'12) - *
  • Typically, {@link org.matsim.contrib.cadyts.pt.CadytsPtPlanStrategy} should be the only - * plan strategy being used. So it is advised to first run the simulation until every - * agent has a few (different) plans, and then do some iterations using only the - * calibration strategy.
  • - *
- * - */ -package org.matsim.contrib.cadyts.pt; diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/run/RunCadyts4CarExample.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/run/RunCadyts4CarExample.java index 4ad3a583ad5..1e1e8d5e95e 100644 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/run/RunCadyts4CarExample.java +++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/run/RunCadyts4CarExample.java @@ -74,7 +74,7 @@ public ScoringFunction createNewScoringFunction(Person person) { scoringFunctionAccumulator.addScoringFunction(new CharyparNagelAgentStuckScoring(params)); final CadytsScoring scoringFunction = new CadytsScoring<>(person.getSelectedPlan(), config, cadytsContext); - scoringFunction.setWeightOfCadytsCorrection(30. * config.planCalcScore().getBrainExpBeta()) ; + scoringFunction.setWeightOfCadytsCorrection(30. * config.scoring().getBrainExpBeta()) ; scoringFunctionAccumulator.addScoringFunction(scoringFunction ); return scoringFunctionAccumulator; diff --git a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarIT.java b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarIT.java index b07564f0a8f..848b371c711 100644 --- a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarIT.java +++ b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarIT.java @@ -23,9 +23,9 @@ import cadyts.measurements.SingleLinkMeasurement; import cadyts.utilities.io.tabularFileParser.TabularFileParser; import cadyts.utilities.misc.DynamicData; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -38,9 +38,9 @@ import org.matsim.contrib.cadyts.utils.CalibrationStatReader; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup.MobsimType; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ControllerConfigGroup.MobsimType; +import org.matsim.core.config.groups.ScoringConfigGroup.ActivityParams; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.ControlerDefaultsModule; import org.matsim.core.controler.ControlerI; @@ -78,23 +78,23 @@ */ public class CadytsCarIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public final void testInitialization() { + final void testInitialization() { final String CADYTS_STRATEGY_NAME = "ccc"; String inputDir = this.utils.getClassInputDirectory(); String outputDir = this.utils.getOutputDirectory(); Config config = createTestConfig(inputDir, outputDir); - config.controler().setLastIteration(0); + config.controller().setLastIteration(0); StrategySettings strategySettings = new StrategySettings(Id.create(1, StrategySettings.class)); strategySettings.setStrategyName(CADYTS_STRATEGY_NAME) ; strategySettings.setWeight(1.0) ; - config.strategy().addStrategySettings(strategySettings); + config.replanning().addStrategySettings(strategySettings); CadytsConfigGroup cadytsCar = ConfigUtils.addOrGetModule(config, CadytsConfigGroup.GROUP_NAME, CadytsConfigGroup.class); // cadytsCar.addParam("startTime", "04:00:00"); cadytsCar.setStartTime( 4*3600 ); @@ -141,20 +141,20 @@ public PlanStrategy get() { CadytsContext context = injector.getInstance(CadytsContext.class); //test calibration settings - Assert.assertEquals(true, context.getCalibrator().getBruteForce()); - Assert.assertEquals(false, context.getCalibrator().getCenterRegression()); - Assert.assertEquals(Integer.MAX_VALUE, context.getCalibrator().getFreezeIteration()); - Assert.assertEquals(8.0, context.getCalibrator().getMinStddev(SingleLinkMeasurement.TYPE.FLOW_VEH_H), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, context.getCalibrator().getPreparatoryIterations()); - Assert.assertEquals(0.95, context.getCalibrator().getRegressionInertia(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1.0, context.getCalibrator().getVarianceScale(), MatsimTestUtils.EPSILON); - Assert.assertEquals(3600.0, context.getCalibrator().getTimeBinSize_s(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(true, context.getCalibrator().getBruteForce()); + Assertions.assertEquals(false, context.getCalibrator().getCenterRegression()); + Assertions.assertEquals(Integer.MAX_VALUE, context.getCalibrator().getFreezeIteration()); + Assertions.assertEquals(8.0, context.getCalibrator().getMinStddev(SingleLinkMeasurement.TYPE.FLOW_VEH_H), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, context.getCalibrator().getPreparatoryIterations()); + Assertions.assertEquals(0.95, context.getCalibrator().getRegressionInertia(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1.0, context.getCalibrator().getVarianceScale(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3600.0, context.getCalibrator().getTimeBinSize_s(), MatsimTestUtils.EPSILON); } //-------------------------------------------------------------- @Test - public final void testCalibrationAsScoring() throws IOException { + final void testCalibrationAsScoring() throws IOException { final double beta=30. ; final int lastIteration = 20 ; @@ -164,11 +164,11 @@ public final void testCalibrationAsScoring() throws IOException { final Config config = createTestConfig(inputDir, outputDir); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); - config.planCalcScore().setBrainExpBeta(beta); + config.scoring().setBrainExpBeta(beta); - config.strategy().addStrategySettings( new StrategySettings().setStrategyName( DefaultSelector.ChangeExpBeta ).setWeight( 1.0 ) ); + config.replanning().addStrategySettings( new StrategySettings().setStrategyName( DefaultSelector.ChangeExpBeta ).setWeight( 1.0 ) ); // === @@ -212,26 +212,26 @@ public ScoringFunction createNewScoringFunction(Person person) { //scenario data test Scenario scenario = injector.getInstance(Scenario.class); - Assert.assertEquals("Different number of links in network.", scenario.getNetwork().getLinks().size() , 23 ); - Assert.assertEquals("Different number of nodes in network.", scenario.getNetwork().getNodes().size() , 15 ); + Assertions.assertEquals(scenario.getNetwork().getLinks().size() , 23, "Different number of links in network." ); + Assertions.assertEquals(scenario.getNetwork().getNodes().size() , 15, "Different number of nodes in network." ); - Assert.assertNotNull("Population is null.", scenario.getPopulation()); + Assertions.assertNotNull(scenario.getPopulation(), "Population is null."); - Assert.assertEquals("Num. of persons in population is wrong.", scenario.getPopulation().getPersons().size(), 5); - Assert.assertEquals("Scale factor is wrong.", scenario.getConfig().counts().getCountsScaleFactor(), 1.0, MatsimTestUtils.EPSILON); + Assertions.assertEquals(scenario.getPopulation().getPersons().size(), 5, "Num. of persons in population is wrong."); + Assertions.assertEquals(scenario.getConfig().counts().getCountsScaleFactor(), 1.0, MatsimTestUtils.EPSILON, "Scale factor is wrong."); //counts - Assert.assertEquals("Count file is wrong.", scenario.getConfig().counts().getCountsFileName(), inputDir + "counts5.xml"); + Assertions.assertEquals(scenario.getConfig().counts().getCountsFileName(), inputDir + "counts5.xml", "Count file is wrong."); Counts occupCounts = new Counts<>(); new MatsimCountsReader(occupCounts).readFile(scenario.getConfig().counts().getCountsFileName()); Count count = occupCounts.getCount(Id.create(19, Link.class)); - Assert.assertEquals("Occupancy counts description is wrong", occupCounts.getDescription(), "counts values for equil net"); - Assert.assertEquals("CsId is wrong.", count.getCsLabel() , "link_19"); - Assert.assertEquals("Volume of hour 6 is wrong", count.getVolume(7).getValue(), 5.0 , MatsimTestUtils.EPSILON); - Assert.assertEquals("Max count volume is wrong.", count.getMaxVolume().getValue(), 5.0 , MatsimTestUtils.EPSILON); + Assertions.assertEquals(occupCounts.getDescription(), "counts values for equil net", "Occupancy counts description is wrong"); + Assertions.assertEquals(count.getCsLabel() , "link_19", "CsId is wrong."); + Assertions.assertEquals(count.getVolume(7).getValue(), 5.0 , MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong"); + Assertions.assertEquals(count.getMaxVolume().getValue(), 5.0 , MatsimTestUtils.EPSILON, "Max count volume is wrong."); String outCounts = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".countscompare.txt"; AdHocCountsReaderCar reader = new AdHocCountsReaderCar(outCounts); @@ -240,29 +240,29 @@ public ScoringFunction createNewScoringFunction(Person person) { { double[] simValues = reader.getSimulatedValues( locId11 ); double[] realValues = reader.getRealValues( locId11 ); - Assert.assertEquals( "Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON ); - Assert.assertEquals( "Volume of hour 6 is wrong", 0.0, realValues[6], MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 0.0, simValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); + Assertions.assertEquals( 0.0, realValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); } { Id locId12 = Id.create( "12", Link.class ); double[] simValues = reader.getSimulatedValues( locId12 ); double[] realValues = reader.getRealValues( locId12 ); - Assert.assertEquals( "Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON ); - Assert.assertEquals( "Volume of hour 6 is wrong", 0.0, realValues[6], MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 0.0, simValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); + Assertions.assertEquals( 0.0, realValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); } Id locId19 = Id.create( "19", Link.class ); { double[] simValues = reader.getSimulatedValues( locId19 ); double[] realValues = reader.getRealValues( locId19 ); - Assert.assertEquals( "Volume of hour 6 is wrong", 5.0, simValues[6], MatsimTestUtils.EPSILON ); - Assert.assertEquals( "Volume of hour 6 is wrong", 5.0, realValues[6], MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 5.0, simValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); + Assertions.assertEquals( 5.0, realValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); } { Id locId21 = Id.create( "21", Link.class ); double[] simValues = reader.getSimulatedValues( locId21 ); double[] realValues = reader.getRealValues( locId21 ); - Assert.assertEquals( "Volume of hour 6 is wrong", 5.0, simValues[6], MatsimTestUtils.EPSILON ); - Assert.assertEquals( "Volume of hour 6 is wrong", 5.0, realValues[6], MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 5.0, simValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); + Assertions.assertEquals( 5.0, realValues[6], MatsimTestUtils.EPSILON, "Volume of hour 6 is wrong" ); } // test calibration statistics String testCalibStatPath = outputDir + "calibration-stats.txt"; @@ -273,7 +273,7 @@ public ScoringFunction createNewScoringFunction(Person person) { // Assert.assertEquals("different Count_ll", "-0.046875", outStatData.getCount_ll() ); // Assert.assertEquals("different Count_ll_pred_err", "0.01836234363152515" , outStatData.getCount_ll_pred_err() ); // Assert.assertEquals("different Link_lambda_avg", "-2.2604922388914356E-10", outStatData.getLink_lambda_avg() ); - Assert.assertEquals("different Link_lambda_avg", "3.2261421242498865E-5", outStatData.getLink_lambda_avg() ); + Assertions.assertEquals("3.2261421242498865E-5", outStatData.getLink_lambda_avg(), "different Link_lambda_avg" ); // Assert.assertEquals("different Link_lambda_max", "0.0" , outStatData.getLink_lambda_max() ); // Assert.assertEquals("different Link_lambda_min", "-7.233575164452593E-9", outStatData.getLink_lambda_min() ); // Assert.assertEquals("different Link_lambda_stddev", "1.261054219517188E-9", outStatData.getLink_lambda_stddev()); @@ -283,7 +283,7 @@ public ScoringFunction createNewScoringFunction(Person person) { // Assert.assertEquals("different Plan_lambda_min", "-7.233575164452593E-9" , outStatData.getPlan_lambda_min() ); // Assert.assertEquals("different Plan_lambda_stddev", "0.0" , outStatData.getPlan_lambda_stddev()); // Assert.assertEquals("different Total_ll", "-0.046875", outStatData.getTotal_ll() ); - Assert.assertEquals("different Total_ll", "0.0", outStatData.getTotal_ll() ); + Assertions.assertEquals("0.0", outStatData.getTotal_ll(), "different Total_ll" ); //test link offsets final Network network = scenario.getNetwork(); @@ -304,10 +304,10 @@ public ScoringFunction createNewScoringFunction(Person person) { isZero = (Math.abs(linkOffsets.getBinValue(link19 , binIndex) - 0.0) < MatsimTestUtils.EPSILON); }while (isZero && binIndex<86400); - Assert.assertEquals("Wrong bin index for first link offset", 6, binIndex); + Assertions.assertEquals(6, binIndex, "Wrong bin index for first link offset"); - Assert.assertEquals("Wrong link offset of link 11", 0.0, linkOffsets.getBinValue(link11 , binIndex), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong link offset of link 19", 0.0014707121641471912, linkOffsets.getBinValue(link19 , binIndex), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, linkOffsets.getBinValue(link11 , binIndex), MatsimTestUtils.EPSILON, "Wrong link offset of link 11"); + Assertions.assertEquals(0.0014707121641471912, linkOffsets.getBinValue(link19 , binIndex), MatsimTestUtils.EPSILON, "Wrong link offset of link 19"); } @@ -320,22 +320,22 @@ private static Config createTestConfig(String inputDir, String outputDir) { config.global().setRandomSeed(4711) ; config.network().setInputFile(inputDir + "network.xml") ; config.plans().setInputFile(inputDir + "plans5.xml") ; - config.controler().setFirstIteration(1) ; - config.controler().setLastIteration(10) ; - config.controler().setOutputDirectory(outputDir) ; - config.controler().setWriteEventsInterval(1) ; - config.controler().setMobsim(MobsimType.qsim.toString()) ; + config.controller().setFirstIteration(1) ; + config.controller().setLastIteration(10) ; + config.controller().setOutputDirectory(outputDir) ; + config.controller().setWriteEventsInterval(1) ; + config.controller().setMobsim(MobsimType.qsim.toString()) ; config.qsim().setFlowCapFactor(1.) ; config.qsim().setStorageCapFactor(1.) ; config.qsim().setStuckTime(10.) ; config.qsim().setRemoveStuckVehicles(false) ; { ActivityParams params = new ActivityParams("h") ; - config.planCalcScore().addActivityParams(params ) ; + config.scoring().addActivityParams(params ) ; params.setTypicalDuration(12*60*60.) ; }{ ActivityParams params = new ActivityParams("w") ; - config.planCalcScore().addActivityParams(params ) ; + config.scoring().addActivityParams(params ) ; params.setTypicalDuration(8*60*60.) ; } config.counts().setInputFile(inputDir + "counts5.xml"); diff --git a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarWithPtScenarioIT.java b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarWithPtScenarioIT.java index 538a47ae917..943cebbe4f0 100644 --- a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarWithPtScenarioIT.java +++ b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/car/CadytsCarWithPtScenarioIT.java @@ -1,11 +1,11 @@ package org.matsim.contrib.cadyts.car; -import static org.junit.Assert.assertTrue; - import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.events.handler.LinkLeaveEventHandler; @@ -22,11 +22,12 @@ public class CadytsCarWithPtScenarioIT { - @Test @Ignore - public void testCadytsWithPtVehicles() { + @Test + @Disabled + void testCadytsWithPtVehicles() { final Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("siouxfalls-2014"), "config_default.xml")); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles); - config.controler().setLastIteration(0); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles); + config.controller().setLastIteration(0); final Scenario scenario = ScenarioUtils.loadScenario(config); final Counts calibrationCounts = new Counts<>(); final Id testLink = Id.createLinkId("6_1"); @@ -43,8 +44,8 @@ public void testCadytsWithPtVehicles() { } }); controler.run(); - assertTrue("There's at least one bus on the test link", bussesSeenOnLink.get() > 0); - assertTrue("This test runs to the end, meaning cadyts doesn't throw an exception with pt", true); + assertTrue(bussesSeenOnLink.get() > 0, "There's at least one bus on the test link"); + assertTrue(true, "This test runs to the end, meaning cadyts doesn't throw an exception with pt"); } } diff --git a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CadytsPtIT.java b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CadytsPtIT.java deleted file mode 100644 index 9ea725add52..00000000000 --- a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CadytsPtIT.java +++ /dev/null @@ -1,690 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * CadytsIntegrationTest.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2011 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.contrib.cadyts.pt; - -import cadyts.measurements.SingleLinkMeasurement; -import cadyts.utilities.io.tabularFileParser.TabularFileParser; -import cadyts.utilities.misc.DynamicData; -import com.google.inject.Provider; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -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.network.Network; -import org.matsim.api.core.v01.population.Person; -import org.matsim.contrib.cadyts.general.CadytsConfigGroup; -import org.matsim.contrib.cadyts.general.CadytsCostOffsetsXMLFileIO; -import org.matsim.contrib.cadyts.general.CadytsPlanChanger; -import org.matsim.contrib.cadyts.general.CadytsScoring; -import org.matsim.contrib.cadyts.utils.CalibrationStatReader; -import org.matsim.core.api.experimental.events.EventsManager; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigGroup; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup.MobsimType; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.PlansConfigGroup.HandlingOfPlansWithoutRoutingMode; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; -import org.matsim.core.controler.AbstractModule; -import org.matsim.core.controler.Controler; -import org.matsim.core.mobsim.framework.Mobsim; -import org.matsim.core.mobsim.framework.MobsimFactory; -import org.matsim.core.replanning.PlanStrategy; -import org.matsim.core.replanning.PlanStrategyImpl; -import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.core.scoring.ScoringFunction; -import org.matsim.core.scoring.ScoringFunctionFactory; -import org.matsim.core.scoring.SumScoringFunction; -import org.matsim.core.scoring.functions.CharyparNagelActivityScoring; -import org.matsim.core.scoring.functions.CharyparNagelAgentStuckScoring; -import org.matsim.core.scoring.functions.CharyparNagelLegScoring; -import org.matsim.core.scoring.functions.ScoringParameters; -import org.matsim.core.scoring.functions.ScoringParametersForPerson; -import org.matsim.counts.Count; -import org.matsim.counts.Counts; -import org.matsim.counts.MatsimCountsReader; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; -import org.matsim.testcases.MatsimTestUtils; - -import jakarta.inject.Inject; -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; - -public class CadytsPtIT { - - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); - - @Test - public final void testInitialization() { - String inputDir = this.utils.getClassInputDirectory(); - - Config config = createTestConfig(inputDir, this.utils.getOutputDirectory()); - config.controler().setLastIteration(0); - StrategySettings stratSets = new StrategySettings(); - stratSets.setStrategyName("ccc") ; - stratSets.setWeight(1.) ; - config.strategy().addStrategySettings(stratSets) ; - - final Scenario scenario = ScenarioUtils.loadScenario(config) ; - final Controler controler = new Controler(scenario); - controler.addOverridingModule(new CadytsPtModule()); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - addPlanStrategyBinding("ccc").toProvider(new jakarta.inject.Provider() { - @Inject CadytsPtContext context; - @Override - public PlanStrategy get() { - return new PlanStrategyImpl(new CadytsPlanChanger<>(scenario, context)); - } - }); - } - }); - - controler.getConfig().controler().setCreateGraphs(false); - controler.getConfig().controler().setWriteEventsInterval(0); - controler.getConfig().controler().setDumpDataAtEnd(true); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - bindMobsim().toProvider(new Provider() { - @Override - public Mobsim get() { - return new DummyMobsimFactory().createMobsim(controler.getScenario(), controler.getEvents()); - } - }); - } - }); - controler.run(); - - CadytsPtContext context = controler.getInjector().getInstance(CadytsPtContext.class); - - //test calibration settings - Assert.assertEquals(true, context.getCalibrator().getBruteForce()); - Assert.assertEquals(false, context.getCalibrator().getCenterRegression()); - Assert.assertEquals(Integer.MAX_VALUE, context.getCalibrator().getFreezeIteration()); - Assert.assertEquals(8.0, context.getCalibrator().getMinStddev(SingleLinkMeasurement.TYPE.FLOW_VEH_H), MatsimTestUtils.EPSILON); - Assert.assertEquals(1, context.getCalibrator().getPreparatoryIterations()); - Assert.assertEquals(0.95, context.getCalibrator().getRegressionInertia(), MatsimTestUtils.EPSILON); - Assert.assertEquals(1.0, context.getCalibrator().getVarianceScale(), MatsimTestUtils.EPSILON); - Assert.assertEquals(3600.0, context.getCalibrator().getTimeBinSize_s(), MatsimTestUtils.EPSILON); - } - - - @Test - public final void testCalibrationAsScoring() throws IOException { - final double beta=30. ; - final int lastIteration = 20 ; - - String inputDir = this.utils.getClassInputDirectory(); - String outputDir = this.utils.getOutputDirectory(); - - final Config config = createTestConfig(inputDir, outputDir); - - config.controler().setLastIteration(lastIteration) ; - - config.planCalcScore().setBrainExpBeta(beta) ; - - StrategySettings stratSets = new StrategySettings() ; - stratSets.setStrategyName("ChangeExpBeta") ; - stratSets.setWeight(1.0) ; - config.strategy().addStrategySettings(stratSets) ; - - // === - - final Controler controler = new Controler(config); - controler.getConfig().controler().setCreateGraphs(false); - controler.addOverridingModule(new CadytsPtModule()); - - controler.setScoringFunctionFactory(new ScoringFunctionFactory() { - @Inject ScoringParametersForPerson parameters; - @Inject Network network; - @Inject CadytsPtContext cContext; - @Override - public ScoringFunction createNewScoringFunction(Person person) { - final ScoringParameters params = parameters.getScoringParameters(person); - - SumScoringFunction scoringFunctionAccumulator = new SumScoringFunction(); - scoringFunctionAccumulator.addScoringFunction(new CharyparNagelLegScoring(params, network, config.transit().getTransitModes())); - scoringFunctionAccumulator.addScoringFunction(new CharyparNagelActivityScoring(params)) ; - scoringFunctionAccumulator.addScoringFunction(new CharyparNagelAgentStuckScoring(params)); - - final CadytsScoring scoringFunction = new CadytsScoring(person.getSelectedPlan() ,config, cContext); - scoringFunction.setWeightOfCadytsCorrection(beta*30.) ; - scoringFunctionAccumulator.addScoringFunction(scoringFunction ); - - return scoringFunctionAccumulator; - } - }) ; - - controler.run(); - - //scenario data test - Assert.assertNotNull("Config is null" , controler.getConfig()); - Assert.assertEquals("Different number of links in network.", controler.getScenario().getNetwork().getLinks().size() , 23 ); - Assert.assertEquals("Different number of nodes in network.", controler.getScenario().getNetwork().getNodes().size() , 15 ); - Assert.assertNotNull("Transit schedule is null.", controler.getScenario().getTransitSchedule()); - Assert.assertEquals("Num. of trLines is wrong.", 2, controler.getScenario().getTransitSchedule().getTransitLines().size() ); - Assert.assertEquals("Num of facilities in schedule is wrong.", controler.getScenario().getTransitSchedule().getFacilities().size() , 5); - Assert.assertNotNull("Population is null.", controler.getScenario().getPopulation()); - Assert.assertEquals("Num. of persons in population is wrong.", controler.getScenario().getPopulation().getPersons().size() , 4); - Assert.assertEquals("Scale factor is wrong.", controler.getScenario().getConfig().ptCounts().getCountsScaleFactor(), 1.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("Distance filter is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilter() , 30000.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("DistanceFilterCenterNode is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilterCenterNode(), "7"); - //counts - Assert.assertEquals("Occupancy count file is wrong.", controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName(), inputDir + "counts/counts_occupancy.xml"); - Counts occupCounts = new Counts(); - new MatsimCountsReader(occupCounts).readFile(controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName()); - Count count = occupCounts.getCount(Id.create("stop1", Link.class)); // casting id from stop to link, not nice - Assert.assertEquals("Occupancy counts description is wrong", occupCounts.getDescription(), "counts values for equil net"); - Assert.assertEquals("CsId is wrong.", count.getCsLabel() , "stop1"); - Assert.assertEquals("Volume of hour 4 is wrong", count.getVolume(7).getValue(), 4.0 , MatsimTestUtils.EPSILON); - Assert.assertEquals("Max count volume is wrong.", count.getMaxVolume().getValue(), 4.0 , MatsimTestUtils.EPSILON); - - // test resulting simulation volumes - { - String outCounts = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".simCountCompareOccupancy.txt"; - CountsReaderPt reader = new CountsReaderPt(outCounts); - double[] simValues; - double[] realValues; - - Id stopId1 = Id.create("stop1", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId1); - realValues= reader.getRealValues(stopId1); - Assert.assertEquals("Volume of hour 6 is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 4.0, realValues[6], MatsimTestUtils.EPSILON); - - Id stopId2 = Id.create("stop2", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId2); - realValues= reader.getRealValues(stopId2); -// Assert.assertEquals("Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 2.0, simValues[6], MatsimTestUtils.EPSILON); // Altered after using ChangeExpBeta instead of "ccc" - Assert.assertEquals("Volume of hour 6 is wrong", 1.0, realValues[6] , MatsimTestUtils.EPSILON); - - Id stopId6 = Id.create("stop6", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId6); - realValues= reader.getRealValues(stopId6); - Assert.assertEquals("Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 2.0, realValues[6], MatsimTestUtils.EPSILON); - - Id stopId10 = Id.create("stop10", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId10); - realValues= reader.getRealValues(stopId10); -// Assert.assertEquals("Volume of hour 6 is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 2.0, simValues[6], MatsimTestUtils.EPSILON); // Altered after using ChangeExpBeta instead of "ccc" - Assert.assertEquals("Volume of hour 6 is wrong", 5.0, realValues[6], MatsimTestUtils.EPSILON); - - // test calibration statistics - String testCalibStatPath = outputDir + "calibration-stats.txt"; - CalibrationStatReader calibrationStatReader = new CalibrationStatReader(); - new TabularFileParser().parse(testCalibStatPath, calibrationStatReader); - - CalibrationStatReader.StatisticsData outStatData= calibrationStatReader.getCalStatMap().get(lastIteration); -// Assert.assertEquals("different Count_ll", "-0.046875", outStatData.getCount_ll() ); - Assert.assertEquals("different Count_ll", "-0.109375", outStatData.getCount_ll() ); // Altered after using ChangeExpBeta instead of "ccc" -// Assert.assertEquals("different Count_ll_pred_err", "0.01836234363152515" , outStatData.getCount_ll_pred_err() ); - Assert.assertEquals("different Count_ll_pred_err", "0.008411478550953913" , outStatData.getCount_ll_pred_err() ); // Altered after using ChangeExpBeta instead of "ccc" - // Assert.assertEquals("different Link_lambda_avg", "-2.2604922388914356E-10", outStatData.getLink_lambda_avg() ); - // Assert.assertEquals("different Link_lambda_max", "0.0" , outStatData.getLink_lambda_max() ); - // Assert.assertEquals("different Link_lambda_min", "-7.233575164452593E-9", outStatData.getLink_lambda_min() ); - // Assert.assertEquals("different Link_lambda_stddev", "1.261054219517188E-9", outStatData.getLink_lambda_stddev()); - // Assert.assertEquals("different P2p_ll", "--" , outStatData.getP2p_ll()); - // Assert.assertEquals("different Plan_lambda_avg", "-7.233575164452594E-9", outStatData.getPlan_lambda_avg() ); - // Assert.assertEquals("different Plan_lambda_max", "-7.233575164452593E-9" , outStatData.getPlan_lambda_max() ); - // Assert.assertEquals("different Plan_lambda_min", "-7.233575164452593E-9" , outStatData.getPlan_lambda_min() ); - // Assert.assertEquals("different Plan_lambda_stddev", "0.0" , outStatData.getPlan_lambda_stddev()); -// Assert.assertEquals("different Total_ll", "-0.046875", outStatData.getTotal_ll() ); - Assert.assertEquals("different Total_ll", "-0.109375", outStatData.getTotal_ll() ); // Altered after using ChangeExpBeta instead of "ccc" - - - //test link offsets - final TransitSchedule schedule = controler.getScenario().getTransitSchedule(); - String linkOffsetFile = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".linkCostOffsets.xml"; - // CadytsPtLinkCostOffsetsXMLFileIO offsetReader = new CadytsPtLinkCostOffsetsXMLFileIO (schedule); - CadytsCostOffsetsXMLFileIO offsetReader - = new CadytsCostOffsetsXMLFileIO (new TransitStopFacilityLookUp(controler.getScenario()), TransitStopFacility.class); - DynamicData stopOffsets = offsetReader.read(linkOffsetFile); - - TransitStopFacility stop2 = schedule.getFacilities().get(stopId2); - TransitStopFacility stop10 = schedule.getFacilities().get(stopId10); - - //find first offset value different from null to compare. Useful to test with different time bin sizes - int binIndex=-1; - boolean isZero; - do { - binIndex++; - isZero = (Math.abs(stopOffsets.getBinValue(stop2 , binIndex) - 0.0) < MatsimTestUtils.EPSILON); - } while (isZero && binIndex<86400); - - Assert.assertEquals("Wrong bin index for first link offset", 6, binIndex); -// Assert.assertEquals("Wrong link offset of stop 10", 0.03515757824042241, stopOffsets.getBinValue(stop10 , binIndex), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong link offset of stop 10", 0.022383938774904025, stopOffsets.getBinValue(stop10 , binIndex), MatsimTestUtils.EPSILON); // Altered after using ChangeExpBeta instead of "ccc" -// Assert.assertEquals("Wrong link offset of stop 2", -0.011353248321030008, stopOffsets.getBinValue(stop2 , binIndex), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong link offset of stop 2", -0.008477236625252698, stopOffsets.getBinValue(stop2 , binIndex), MatsimTestUtils.EPSILON); // Altered after using ChangeExpBeta instead of "ccc" - } - } - - - @Test - public final void testCalibration() throws IOException { - final double beta = 30. ; - final int lastIteration = 20 ; - - String inputDir = this.utils.getClassInputDirectory(); - String outputDir = this.utils.getOutputDirectory(); - - Config config = createTestConfig(inputDir, outputDir) ; - - config.controler().setWriteEventsInterval(0) ; - config.controler().setLastIteration(lastIteration) ; - // seems to need 15 iterations as "warm-up"; at least the cadyts corrections are much smaller until then. - - config.planCalcScore().setBrainExpBeta(beta) ; - - StrategySettings stratSets = new StrategySettings(); - stratSets.setStrategyName("ccc") ; - stratSets.setWeight(1.) ; - config.strategy().addStrategySettings(stratSets) ; - - final Scenario scenario = ScenarioUtils.loadScenario(config) ; - - final Controler controler = new Controler( scenario ); - controler.getConfig().controler().setCreateGraphs(false); - controler.getConfig().controler().setDumpDataAtEnd(true); - - controler.addOverridingModule(new CadytsPtModule()); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - addPlanStrategyBinding("ccc").toProvider(new jakarta.inject.Provider() { - @Inject CadytsPtContext context; - @Override - public PlanStrategy get() { - final CadytsPlanChanger planSelector = new CadytsPlanChanger(scenario, context); - planSelector.setCadytsWeight(beta * 30.); - return new PlanStrategyImpl(planSelector); - } - }); - } - }); - - controler.run(); - - //scenario data test - Assert.assertNotNull("config is null" , controler.getConfig()); - Assert.assertEquals("Different number of links in network.", controler.getScenario().getNetwork().getLinks().size() , 23 ); - Assert.assertEquals("Different number of nodes in network.", controler.getScenario().getNetwork().getNodes().size() , 15 ); - Assert.assertNotNull("Transit schedule is null.", controler.getScenario().getTransitSchedule()); - Assert.assertEquals("Num. of trLines is wrong.", 2, controler.getScenario().getTransitSchedule().getTransitLines().size() ); - Assert.assertEquals("Num of facilities in schedule is wrong.", controler.getScenario().getTransitSchedule().getFacilities().size() , 5); - Assert.assertNotNull("Population is null.", controler.getScenario().getPopulation()); - Assert.assertEquals("Num. of persons in population is wrong.", controler.getScenario().getPopulation().getPersons().size() , 4); - Assert.assertEquals("Scale factor is wrong.", controler.getScenario().getConfig().ptCounts().getCountsScaleFactor(), 1.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("Distance filter is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilter() , 30000.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("DistanceFilterCenterNode is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilterCenterNode(), "7"); - //counts - Assert.assertEquals("Occupancy count file is wrong.", controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName(), inputDir + "counts/counts_occupancy.xml"); - Counts occupCounts = new Counts(); - new MatsimCountsReader(occupCounts).readFile(controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName()); - Count count = occupCounts.getCount(Id.create("stop1", Link.class)); // casting the id from a stop to a link, not nice.. - Assert.assertEquals("Occupancy counts description is wrong", occupCounts.getDescription(), "counts values for equil net"); - Assert.assertEquals("CsId is wrong.", count.getCsLabel() , "stop1"); - Assert.assertEquals("Volume of hour 4 is wrong", count.getVolume(7).getValue(), 4.0 , MatsimTestUtils.EPSILON); - Assert.assertEquals("Max count volume is wrong.", count.getMaxVolume().getValue(), 4.0 , MatsimTestUtils.EPSILON); - - // test resulting simulation volumes - { - String outCounts = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".simCountCompareOccupancy.txt"; - CountsReaderPt reader = new CountsReaderPt(outCounts); - double[] simValues; - double[] realValues; - - Id stopId1 = Id.create("stop1", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId1); - realValues= reader.getRealValues(stopId1); - Assert.assertEquals("Volume of hour 6 is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 4.0, realValues[6], MatsimTestUtils.EPSILON); - - Id stopId2 = Id.create("stop2", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId2); - realValues= reader.getRealValues(stopId2); - Assert.assertEquals("Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 1.0, realValues[6] , MatsimTestUtils.EPSILON); - - Id stopId6 = Id.create("stop6", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId6); - realValues= reader.getRealValues(stopId6); - Assert.assertEquals("Volume of hour 6 is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 2.0, realValues[6], MatsimTestUtils.EPSILON); - - Id stopId10 = Id.create("stop10", TransitStopFacility.class); - simValues = reader.getSimulatedValues(stopId10); - realValues= reader.getRealValues(stopId10); - Assert.assertEquals("Volume of hour 6 is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 is wrong", 5.0, realValues[6], MatsimTestUtils.EPSILON); - - // test calibration statistics - String testCalibStatPath = outputDir + "calibration-stats.txt"; - CalibrationStatReader calibrationStatReader = new CalibrationStatReader(); - new TabularFileParser().parse(testCalibStatPath, calibrationStatReader); - - CalibrationStatReader.StatisticsData outStatData= calibrationStatReader.getCalStatMap().get(lastIteration); - Assert.assertEquals("different Count_ll", "-0.046875", outStatData.getCount_ll() ); - Assert.assertEquals("different Count_ll_pred_err", "0.008670972399424905" , outStatData.getCount_ll_pred_err() ); - Assert.assertEquals("different Link_lambda_avg", "3.642292018550638E-4", outStatData.getLink_lambda_avg() ); - Assert.assertEquals("different Link_lambda_max", "0.032081715026130615" , outStatData.getLink_lambda_max() ); - Assert.assertEquals("different Link_lambda_min", "-0.008771046107406533", outStatData.getLink_lambda_min() ); - Assert.assertEquals("different Link_lambda_stddev", "0.0041495140513996154", outStatData.getLink_lambda_stddev()); - Assert.assertEquals("different P2p_ll", "--" , outStatData.getP2p_ll()); - Assert.assertEquals("different Plan_lambda_avg", "0.011655334459362041", outStatData.getPlan_lambda_avg() ); - Assert.assertEquals("different Plan_lambda_max", "0.032081715026130615" , outStatData.getPlan_lambda_max() ); - Assert.assertEquals("different Plan_lambda_min", "-0.008771046107406533" , outStatData.getPlan_lambda_min() ); - Assert.assertEquals("different Plan_lambda_stddev", "0.02183671935220152" , outStatData.getPlan_lambda_stddev()); - Assert.assertEquals("different Total_ll", "-0.046875", outStatData.getTotal_ll() ); - - //test link offsets - final TransitSchedule schedule = controler.getScenario().getTransitSchedule(); - String linkOffsetFile = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".linkCostOffsets.xml"; - // CadytsPtLinkCostOffsetsXMLFileIO offsetReader = new CadytsPtLinkCostOffsetsXMLFileIO (schedule); - CadytsCostOffsetsXMLFileIO offsetReader - = new CadytsCostOffsetsXMLFileIO (new TransitStopFacilityLookUp(controler.getScenario()), TransitStopFacility.class); - DynamicData stopOffsets = offsetReader.read(linkOffsetFile); - - TransitStopFacility stop2 = schedule.getFacilities().get(stopId2); - TransitStopFacility stop10 = schedule.getFacilities().get(stopId10); - - //find first offset value different from null to compare. Useful to test with different time bin sizes - int binIndex=-1; - boolean isZero; - do { - binIndex++; - isZero = (Math.abs(stopOffsets.getBinValue(stop2 , binIndex) - 0.0) < MatsimTestUtils.EPSILON); - }while (isZero && binIndex<86400); - - Assert.assertEquals("Wrong bin index for first link offset", 6, binIndex); - Assert.assertEquals("Wrong link offset of stop 10", 0.031842616249416734, stopOffsets.getBinValue(stop10 , binIndex), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong link offset of stop 2", -0.0079478186053482, stopOffsets.getBinValue(stop2 , binIndex), MatsimTestUtils.EPSILON); - } - } - - - /** - * @author mmoyo - */ - @Test - public final void testCalibrationTwo() throws IOException { - // yyyy I cannot fully certify that this test is doing something reasonable, since simCountComparisonOccupancy.txt and - // cadytsSimCountComparisonOccupancy.txt are returning different results. kai, feb'13 - // There is a comment in CadytsContext that the "cadyts" version may be wrong for time bins different from one hour. kai, dec'13 - - final double beta = 30. ; - final int lastIteration = 20 ; - - String inputDir = this.utils.getClassInputDirectory(); - String outputDir = this.utils.getOutputDirectory(); - - Config config = createTestConfig(inputDir, this.utils.getOutputDirectory()); - - config.controler().setLastIteration(lastIteration) ; - config.controler().setWritePlansInterval(1) ; - config.controler().setWriteEventsInterval(1) ; - - config.ptCounts().setPtCountsInterval(1) ; - - StrategySettings stratSets = new StrategySettings(); - stratSets.setStrategyName("ccc") ; - stratSets.setWeight(1.) ; - config.strategy().addStrategySettings(stratSets) ; - - CadytsConfigGroup cConfig = (CadytsConfigGroup) config.getModule(CadytsConfigGroup.GROUP_NAME) ; - cConfig.setTimeBinSize(7200) ; - - // --- - - final Controler controler = new Controler(config); - controler.addOverridingModule(new CadytsPtModule()); -// controler.setOverwriteFiles(true); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - addPlanStrategyBinding("ccc").toProvider(new jakarta.inject.Provider() { - @Inject Scenario scenario; - @Inject CadytsPtContext context; - @Override - public PlanStrategy get() { - final CadytsPlanChanger planSelector = new CadytsPlanChanger(scenario, context); - planSelector.setCadytsWeight(beta * 30.); - return new PlanStrategyImpl(planSelector); - } - }); - } - }); - - controler.getConfig().controler().setCreateGraphs(false); - controler.getConfig().controler().setWriteEventsInterval(0); - controler.getConfig().controler().setDumpDataAtEnd(true); - controler.run(); - - // ==================================== - - //scenario data test - Assert.assertNotNull("config is null" , controler.getConfig()); - Assert.assertEquals("Different number of links in network.", controler.getScenario().getNetwork().getLinks().size() , 23 ); - Assert.assertEquals("Different number of nodes in network.", controler.getScenario().getNetwork().getNodes().size() , 15 ); - Assert.assertNotNull("Transit schedule is null.", controler.getScenario().getTransitSchedule()); - Assert.assertEquals("Num. of trLines is wrong.", 2, controler.getScenario().getTransitSchedule().getTransitLines().size() ); - Assert.assertEquals("Num of facilities in schedule is wrong.", controler.getScenario().getTransitSchedule().getFacilities().size() , 5); - Assert.assertNotNull("Population is null.", controler.getScenario().getPopulation()); - Assert.assertEquals("Num. of persons in population is wrong.", controler.getScenario().getPopulation().getPersons().size() , 4); - Assert.assertEquals("Scale factor is wrong.", controler.getScenario().getConfig().ptCounts().getCountsScaleFactor(), 1.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("Distance filter is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilter() , 30000.0, MatsimTestUtils.EPSILON); - // Assert.assertEquals("DistanceFilterCenterNode is wrong.", controler.getTestScenarioURL().getConfig().ptCounts().getDistanceFilterCenterNode(), "7"); - //counts - Assert.assertEquals("Occupancy count file is wrong.", controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName(), inputDir + "counts/counts_occupancy.xml"); - Counts occupCounts = new Counts(); - new MatsimCountsReader(occupCounts).readFile(controler.getScenario().getConfig().ptCounts().getOccupancyCountsFileName()); - Count count = occupCounts.getCount(Id.create("stop1", Link.class)); - Assert.assertEquals("Occupancy counts description is wrong", occupCounts.getDescription(), "counts values for equil net"); - Assert.assertEquals("CsId is wrong.", count.getCsLabel() , "stop1"); - - Assert.assertEquals("Volume of hour 4 is wrong", count.getVolume(7).getValue(), 4.0 , MatsimTestUtils.EPSILON); - // yy I don't know why it says "hour 4" but "getVolume(7)". kai, sep'14 - - Assert.assertEquals("Max count volume is wrong.", count.getMaxVolume().getValue(), 4.0 , MatsimTestUtils.EPSILON); - - // test resulting simulation volumes - String outCounts = outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".simCountCompareOccupancy.txt"; - CountsReaderPt reader = new CountsReaderPt(outCounts); - Id stopId1 = Id.create("stop1", TransitStopFacility.class); - { - double[] simValues = reader.getSimulatedValues(stopId1); - double[] realValues= reader.getRealValues(stopId1); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 4.0, realValues[6], MatsimTestUtils.EPSILON); - } - Id stopId2 = Id.create("stop2", TransitStopFacility.class); - { - double[] simValues = reader.getSimulatedValues(stopId2); - double[] realValues= reader.getRealValues(stopId2); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 1.0, realValues[6] , MatsimTestUtils.EPSILON); - } - Id stopId6 = Id.create("stop6", TransitStopFacility.class); - { - double[] simValues = reader.getSimulatedValues(stopId6); - double[] realValues= reader.getRealValues(stopId6); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 0.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 2.0, realValues[6], MatsimTestUtils.EPSILON); - } - Id stopId10 = Id.create("stop10", TransitStopFacility.class); - { - double[] simValues = reader.getSimulatedValues(stopId10); - double[] realValues= reader.getRealValues(stopId10); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 4.0, simValues[6], MatsimTestUtils.EPSILON); - Assert.assertEquals("Volume of hour 6 (probably: 7) is wrong", 5.0, realValues[6], MatsimTestUtils.EPSILON); - } - // 2 bus lines, one using stops 1, 2, 12, the other using 1, 10, 12. Counts say: - // stop1: 4 (should always be satisfied) - // stop2: 1 (should be possible to satisfy bus see below) - // stop6: 2 (not possible to satisfy (no line going there)) - // stop10: 5 (not possible to satisfy (we have not enough plans) but see below) - // and they say this at h=7 (which may, or may not, be the entry "6" in the counts array, but then the error messages are wrong). - // - // stop2 and stop10 are pulling in different directions; would need 7 plans to satisfy but have only 4. Satisfying the higher - // volume station better is the cadyts-conforming solution. - - // test calibration statistics - String testCalibStatPath = outputDir + "calibration-stats.txt"; - CalibrationStatReader calibrationStatReader = new CalibrationStatReader(); - new TabularFileParser().parse(testCalibStatPath, calibrationStatReader); - - CalibrationStatReader.StatisticsData outStatData= calibrationStatReader.getCalStatMap().get(lastIteration); - // Assert.assertEquals("different Count_ll", "-0.01171875", outStatData.getCount_ll() ); - // Assert.assertEquals("different Count_ll_pred_err", "0.004590585907794875" , outStatData.getCount_ll_pred_err() ); - // Assert.assertEquals("different Link_lambda_avg", "-1.8081427328702926E-9", outStatData.getLink_lambda_avg() ); - // Assert.assertEquals("different Link_lambda_max", "0.0" , outStatData.getLink_lambda_max() ); - // Assert.assertEquals("different Link_lambda_min", "-1.4465142715757458E-8", outStatData.getLink_lambda_min() ); - // Assert.assertEquals("different Link_lambda_stddev", "4.501584893410135E-9" , outStatData.getLink_lambda_stddev()); - // Assert.assertEquals("different P2p_ll", "--" , outStatData.getP2p_ll()); - // Assert.assertEquals("different Plan_lambda_avg", "-2.5313998260184097E-8", outStatData.getPlan_lambda_avg() ); - // Assert.assertEquals("different Plan_lambda_max", "-2.5313998260184097E-8" , outStatData.getPlan_lambda_max() ); - // Assert.assertEquals("different Plan_lambda_min", "-2.5313998260184097E-8" , outStatData.getPlan_lambda_min() ); - // Assert.assertEquals("different Plan_lambda_stddev", "NaN" , outStatData.getPlan_lambda_stddev()); - // Assert.assertEquals("different Total_ll", "-0.01171875", outStatData.getTotal_ll() ); - // - // I think that the above quantities change when changing between FLOW_VEH_H and COUNT_VEH. The calibration result, though, - // seems the same. - - - //test link offsets - final TransitSchedule schedule = controler.getScenario().getTransitSchedule(); - CadytsCostOffsetsXMLFileIO offsetReader = - new CadytsCostOffsetsXMLFileIO (new TransitStopFacilityLookUp(controler.getScenario()), TransitStopFacility.class); - DynamicData stopOffsets = - offsetReader.read(outputDir + "ITERS/it." + lastIteration + "/" + lastIteration + ".linkCostOffsets.xml"); - - TransitStopFacility stop1 = schedule.getFacilities().get(stopId1); - TransitStopFacility stop2 = schedule.getFacilities().get(stopId2); - //TransitStopFacility stop6 = schedule.getFacilities().get(stopId6); - TransitStopFacility stop10 = schedule.getFacilities().get(stopId10); - - //find first offset value different from zero to compare. Useful to test with different time bin sizes - int binIndex=-1; - boolean isZero; - do { - binIndex++; - isZero = (Math.abs(stopOffsets.getBinValue(stop2 , binIndex) - 0.0) < MatsimTestUtils.EPSILON); - }while (isZero && binIndex<86400); - - Assert.assertEquals("Wrong Bin index for first link offset", 3, binIndex); // bin size = 3600; fix! //done manuel jul.2012 - Assert.assertEquals("Wrong link offset of stop 1", 0.0, stopOffsets.getBinValue(stop1 , binIndex), MatsimTestUtils.EPSILON); -// Assert.assertEquals("Wrong link offset of stop 2", -0.0028383120802772956, stopOffsets.getBinValue(stop2 , binIndex), MatsimTestUtils.EPSILON); -// Assert.assertEquals("Wrong link offset of stop 10", 0.00878939456017082, stopOffsets.getBinValue(stop10 , binIndex), MatsimTestUtils.EPSILON); - - Assert.assertTrue("Offset at stop 2 has wrong sign.", stopOffsets.getBinValue(stop2, binIndex) < 0. ) ; - Assert.assertTrue("Offset at stop 10 has wrong sign.", stopOffsets.getBinValue(stop10, binIndex) > 0. ) ; - } - - - private static Config createTestConfig(String inputDir, String outputDir) { - Config config = ConfigUtils.createConfig() ; - // --- - config.global().setRandomSeed(4711) ; - // --- - config.network().setInputFile(inputDir + "network.xml") ; - // --- - config.plans().setInputFile(inputDir + "4plans.xml") ; - config.plans().setHandlingOfPlansWithoutRoutingMode(HandlingOfPlansWithoutRoutingMode.useMainModeIdentifier); - // --- - config.transit().setUseTransit(true) ; - // --- - config.controler().setFirstIteration(1) ; - config.controler().setLastIteration(10) ; - config.controler().setOutputDirectory(outputDir) ; - config.controler().setWriteEventsInterval(1) ; - config.controler().setMobsim(MobsimType.qsim.toString()) ; - // --- - - config.qsim().setFlowCapFactor(0.02) ; - config.qsim().setStorageCapFactor(0.06) ; - config.qsim().setStuckTime(10.) ; - config.qsim().setRemoveStuckVehicles(false) ; // ?? - // --- - config.transit().setTransitScheduleFile(inputDir + "transitSchedule1bus.xml") ; - config.transit().setVehiclesFile(inputDir + "vehicles.xml") ; - Set modes = new HashSet() ; - modes.add("pt") ; - config.transit().setTransitModes(modes) ; - // --- - { - ActivityParams params = new ActivityParams("h") ; - config.planCalcScore().addActivityParams(params ) ; - params.setTypicalDuration(12*60*60.) ; - }{ - ActivityParams params = new ActivityParams("w") ; - config.planCalcScore().addActivityParams(params ) ; - params.setTypicalDuration(8*60*60.) ; - } - // --- -// ConfigGroup cadytsPtConfig = config.createModule(CadytsConfigGroup.GROUP_NAME ) ; - CadytsConfigGroup cadytsPtConfig = ConfigUtils.addOrGetModule( config, CadytsConfigGroup.class ); - -// cadytsPtConfig.addParam(CadytsConfigGroup.START_TIME, "04:00:00") ; - cadytsPtConfig.setStartTime( 4*3600 ); -// cadytsPtConfig.addParam(CadytsConfigGroup.END_TIME, "20:00:00" ) ; - cadytsPtConfig.setEndTime( 20*3600 ); - cadytsPtConfig.addParam(CadytsConfigGroup.REGRESSION_INERTIA, "0.95") ; - cadytsPtConfig.addParam(CadytsConfigGroup.USE_BRUTE_FORCE, "true") ; - cadytsPtConfig.addParam(CadytsConfigGroup.MIN_FLOW_STDDEV, "8") ; - cadytsPtConfig.addParam(CadytsConfigGroup.PREPARATORY_ITERATIONS, "1") ; - cadytsPtConfig.addParam(CadytsConfigGroup.TIME_BIN_SIZE, "3600") ; - cadytsPtConfig.addParam(CadytsConfigGroup.CALIBRATED_LINES, "M44,M43") ; - -// CadytsConfigGroup ccc = new CadytsConfigGroup() ; -// config.addModule(ccc) ; - - - // --- - config.ptCounts().setOccupancyCountsFileName(inputDir + "counts/counts_occupancy.xml") ; - config.ptCounts().setBoardCountsFileName(inputDir + "counts/counts_boarding.xml") ; - config.ptCounts().setAlightCountsFileName(inputDir + "counts/counts_alighting.xml") ; - // config.ptCounts().setDistanceFilter(30000.) ; // why? - // config.ptCounts().setDistanceFilterCenterNode("7") ; // why? - config.ptCounts().setOutputFormat("txt"); - config.ptCounts().setCountsScaleFactor(1.) ; - // --- - return config; - } - - private static class DummyMobsimFactory implements MobsimFactory { - @Override - public Mobsim createMobsim(final Scenario sc, final EventsManager eventsManager) { - return new Mobsim() { - @Override public void run() { } - } ; - } - } -} diff --git a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CountsReaderPt.java b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CountsReaderPt.java deleted file mode 100644 index a312c472c48..00000000000 --- a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/pt/CountsReaderPt.java +++ /dev/null @@ -1,130 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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.contrib.cadyts.pt; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.util.Map; -import java.util.TreeMap; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Id; -import org.matsim.core.utils.misc.StringUtils; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -/** - * parses a output text file containing counts comparisons - * - * this class is only there in order to read the column-oriented output back in for testing. - * It should not be used elsewhere without further thinking. kai, sep'14 - * */ -final class CountsReaderPt { - - private final static Logger log = LogManager.getLogger(CountsReaderPt.class); - - final String STOP_ID_STRING_0 = "StopId :"; - final String HEAD_STRING_0 = "hour"; - final String ZERO = "0.0"; - - String countsTextFile; - Map, Map> count = new TreeMap<>(); - - CountsReaderPt(final String countsTextFile){ - this.countsTextFile = countsTextFile; - readValues(); - } - - private void readValues() { - try { - FileReader fileReader = new FileReader(this.countsTextFile); - // ->:correct this : reads first row - BufferedReader bufferedReader = new BufferedReader(fileReader); - String row = bufferedReader.readLine(); // TODO : include the first row inside the iteration - String[] values = StringUtils.explode(row, '\t'); - - Id id = Id.create(values[1], TransitStopFacility.class); - while (row != null) { - row = bufferedReader.readLine(); - if (row != null && row != "") { - values = StringUtils.explode(row, '\t'); - if (values[0].equals(this.STOP_ID_STRING_0)) { - id = Id.create(values[1], TransitStopFacility.class); - } else if (values[0].equals(this.HEAD_STRING_0)) { - // it does nothing, correct this condition - } else { - if (!this.count.containsKey(id)) { - this.count.put(id, new TreeMap()); - } - this.count.get(id).put(values[0], - new double[] { Double.parseDouble(values[1]), Double.parseDouble(values[2]), Double.parseDouble(values[3]) }); - } - } - } - bufferedReader.close(); - fileReader.close(); - } catch (Exception e) { - log.error(e); - } - } - - /** - * I am reasonably sure that the first entry (hour 1) is at array-position 0. kai, sep'14 - */ - double[]getSimulatedValues(final Id stopId) { - return this.getCountValues(stopId, 0); - } - - /** - * I am reasonably sure that the first entry (hour 1) is at array-position 0. kai, sep'14 - */ - double[]getSimulatedScaled(final Id stopId) { - return this.getCountValues(stopId, 1); - } - - /** - * I am reasonably sure that the first entry (hour 1) is at array-position 0. kai, sep'14 - */ - double[]getRealValues(final Id stopId) { - return this.getCountValues(stopId, 2); - } - - /** - * I am reasonably sure that the first entry (hour 1) is at array-position 0. kai, sep'14 - */ - double[]getCountValues(final Id stopId, final int col) { - double[] valueArray = new double[24]; - for (byte i= 0; i<24 ; i++) { - String hour = String.valueOf(i+1); - if (this.count.keySet().contains(stopId)) { - double[] value = this.count.get(stopId).get(hour); - if (value == null){ - valueArray[i] = 0.0; - } else { - valueArray[i] = value[col] ; //0 = simulated; 1= simulatedEscaled ; 2=realValues - } - } else { - valueArray = null; - } - } - return valueArray; - } - -} diff --git a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/utils/CalibrationStatReaderTest.java b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/utils/CalibrationStatReaderTest.java index 5733a037c50..98cc6caaebe 100644 --- a/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/utils/CalibrationStatReaderTest.java +++ b/contribs/cadytsIntegration/src/test/java/org/matsim/contrib/cadyts/utils/CalibrationStatReaderTest.java @@ -20,39 +20,36 @@ package org.matsim.contrib.cadyts.utils; import java.io.IOException; -import java.net.URL; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.matsim.contrib.cadyts.pt.CadytsPtIT; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.testcases.MatsimTestUtils; import cadyts.utilities.io.tabularFileParser.TabularFileParser; public class CalibrationStatReaderTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testReader() throws IOException { + void testReader() throws IOException { TabularFileParser tabularFileParser = new TabularFileParser(); String calibStatFile = this.utils.getInputDirectory() + "calibration-stats.txt"; CalibrationStatReader calibrationStatReader = new CalibrationStatReader(); tabularFileParser.parse(calibStatFile, calibrationStatReader); CalibrationStatReader.StatisticsData statData6= calibrationStatReader.getCalStatMap().get(Integer.valueOf(6)); - Assert.assertEquals("differrent Count_ll", "-1.546875", statData6.getCount_ll() ); - Assert.assertEquals("differrent Count_ll_pred_err", "9.917082938182276E-8" , statData6.getCount_ll_pred_err() ); - Assert.assertEquals("differrent Link_lambda_avg", "0.0013507168476099964", statData6.getLink_lambda_avg() ); - Assert.assertEquals("differrent Link_lambda_max", "0.031434867572002166" , statData6.getLink_lambda_max() ); - Assert.assertEquals("differrent Link_lambda_min", "0.0", statData6.getLink_lambda_min() ); - Assert.assertEquals("differrent Link_lambda_stddev", "0.0058320747961925256" , statData6.getLink_lambda_stddev()); - Assert.assertEquals("differrent P2p_ll", "--" , statData6.getP2p_ll()); - Assert.assertEquals("differrent Plan_lambda_avg", "0.04322293912351989", statData6.getPlan_lambda_avg() ); - Assert.assertEquals("differrent Plan_lambda_max", "0.04715229919344063" , statData6.getPlan_lambda_max() ); - Assert.assertEquals("differrent Plan_lambda_min", "0.03929357905359915" , statData6.getPlan_lambda_min() ); - Assert.assertEquals("differrent Plan_lambda_stddev", "0.004200662608832472" , statData6.getPlan_lambda_stddev()); - Assert.assertEquals("differrent Total_ll", "-1.546875", statData6.getTotal_ll() ); + Assertions.assertEquals("-1.546875", statData6.getCount_ll(), "different Count_ll" ); + Assertions.assertEquals("9.917082938182276E-8" , statData6.getCount_ll_pred_err(), "different Count_ll_pred_err" ); + Assertions.assertEquals("0.0013507168476099964", statData6.getLink_lambda_avg(), "different Link_lambda_avg" ); + Assertions.assertEquals("0.031434867572002166" , statData6.getLink_lambda_max(), "different Link_lambda_max" ); + Assertions.assertEquals("0.0", statData6.getLink_lambda_min(), "different Link_lambda_min" ); + Assertions.assertEquals("0.0058320747961925256" , statData6.getLink_lambda_stddev(), "different Link_lambda_stddev"); + Assertions.assertEquals("--" , statData6.getP2p_ll(), "different P2p_ll"); + Assertions.assertEquals("0.04322293912351989", statData6.getPlan_lambda_avg(), "different Plan_lambda_avg" ); + Assertions.assertEquals("0.04715229919344063" , statData6.getPlan_lambda_max(), "different Plan_lambda_max" ); + Assertions.assertEquals("0.03929357905359915" , statData6.getPlan_lambda_min(), "different Plan_lambda_min" ); + Assertions.assertEquals("0.004200662608832472" , statData6.getPlan_lambda_stddev(), "different Plan_lambda_stddev"); + Assertions.assertEquals("-1.546875", statData6.getTotal_ll(), "different Total_ll" ); } } diff --git a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/control/listeners/CarsharingListener.java b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/control/listeners/CarsharingListener.java index 3409c505f63..42c2d594c05 100644 --- a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/control/listeners/CarsharingListener.java +++ b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/control/listeners/CarsharingListener.java @@ -69,7 +69,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { e.printStackTrace(); } - if (event.getIteration() == controler.getConfig().controler().getLastIteration()) { + if (event.getIteration() == controler.getConfig().controller().getLastIteration()) { final BufferedWriter outLinkStats = IOUtils .getBufferedWriter(this.controler.getControlerIO().getOutputFilename("CS.txt")); try { diff --git a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/manager/demand/VehicleChoiceAgentImpl.java b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/manager/demand/VehicleChoiceAgentImpl.java index 9906d235e08..455f57a72f4 100644 --- a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/manager/demand/VehicleChoiceAgentImpl.java +++ b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/manager/demand/VehicleChoiceAgentImpl.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -15,7 +14,7 @@ import org.matsim.contrib.carsharing.manager.supply.CarsharingSupplyInterface; import org.matsim.contrib.carsharing.manager.supply.costs.CostsCalculatorContainer; import org.matsim.contrib.carsharing.vehicles.CSVehicle; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.router.costcalculators.TravelDisutilityFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.LeastCostPathCalculator.Path; @@ -72,7 +71,7 @@ public CSVehicle chooseVehicleActivityTimeIncluded(List vehicleOption CSVehicle chosenVehicle = null; double maxUtility = Integer.MIN_VALUE; - double marginalUtilityOfMoney = ((PlanCalcScoreConfigGroup) scenario.getConfig().getModule("planCalcScore")) + double marginalUtilityOfMoney = ((ScoringConfigGroup) scenario.getConfig().getModule("planCalcScore")) .getMarginalUtilityOfMoney(); for (CSVehicle vehicle : vehicleOptions) { Link vehicleLocation = this.carsharingSupply.getCompany(vehicle.getCompanyId()) diff --git a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/scoring/CarsharingLegScoringFunction.java b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/scoring/CarsharingLegScoringFunction.java index 4c41d77c15e..f30d27c9ad3 100644 --- a/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/scoring/CarsharingLegScoringFunction.java +++ b/contribs/carsharing/src/main/java/org/matsim/contrib/carsharing/scoring/CarsharingLegScoringFunction.java @@ -11,15 +11,15 @@ import org.matsim.contrib.carsharing.manager.supply.costs.CostsCalculatorContainer; import org.matsim.contrib.carsharing.vehicles.CSVehicle; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.scoring.functions.ScoringParameters; public class CarsharingLegScoringFunction extends org.matsim.core.scoring.functions.CharyparNagelLegScoring { - - private Config config; - + + private Config config; + private CostsCalculatorContainer costsCalculatorContainer; private DemandHandler demandHandler; private Person person; @@ -27,11 +27,11 @@ public class CarsharingLegScoringFunction extends org.matsim.core.scoring.functi /* private static final Set walkingLegs = ImmutableSet.of("egress_walk_ow", "access_walk_ow", "egress_walk_tw", "access_walk_tw", "egress_walk_ff", "access_walk_ff"); - + private static final Set carsharingLegs = ImmutableSet.of("oneway_vehicle", "twoway_vehicle", "freefloating_vehicle");*/ - - public CarsharingLegScoringFunction(ScoringParameters params, + + public CarsharingLegScoringFunction(ScoringParameters params, Config config, Network network, DemandHandler demandHandler, CostsCalculatorContainer costsCalculatorContainer, CarsharingSupplyInterface carsharingSupplyContainer, Person person) @@ -41,62 +41,62 @@ public CarsharingLegScoringFunction(ScoringParameters params, this.demandHandler = demandHandler; this.carsharingSupplyContainer = carsharingSupplyContainer; this.costsCalculatorContainer = costsCalculatorContainer; - this.person = person; + this.person = person; } @Override public void handleEvent(Event event) { - super.handleEvent(event); - } - + super.handleEvent(event); + } + @Override - public void finish() { - super.finish(); - + public void finish() { + super.finish(); + AgentRentals agentRentals = this.demandHandler.getAgentRentalsMap().get(person.getId()); if (agentRentals != null) { - double marginalUtilityOfMoney = ((PlanCalcScoreConfigGroup)this.config.getModule("planCalcScore")).getMarginalUtilityOfMoney(); + double marginalUtilityOfMoney = this.config.scoring().getMarginalUtilityOfMoney(); for(RentalInfo rentalInfo : agentRentals.getArr()) { CSVehicle vehicle = this.carsharingSupplyContainer.getAllVehicles().get(rentalInfo.getVehId().toString()); if (marginalUtilityOfMoney != 0.0) - score += -1 * this.costsCalculatorContainer.getCost(vehicle.getCompanyId(), + score += -1 * this.costsCalculatorContainer.getCost(vehicle.getCompanyId(), rentalInfo.getCarsharingType(), rentalInfo) * marginalUtilityOfMoney; - } - } - } - + } + } + } + @Override protected double calcLegScore(double departureTime, double arrivalTime, Leg leg) { - - + + double tmpScore = 0.0D; /*double travelTime = arrivalTime - departureTime; String mode = leg.getMode(); if (carsharingLegs.contains(mode)) { - - if (("oneway_vehicle").equals(mode)) { + + if (("oneway_vehicle").equals(mode)) { tmpScore += Double.parseDouble(this.config.getModule("OneWayCarsharing").getParams().get("constantOneWayCarsharing")); tmpScore += travelTime * Double.parseDouble(this.config.getModule("OneWayCarsharing").getParams().get("travelingOneWayCarsharing")) / 3600.0; - } - - else if (("freefloating_vehicle").equals(mode)) { - + } + + else if (("freefloating_vehicle").equals(mode)) { + tmpScore += Double.parseDouble(this.config.getModule("FreeFloating").getParams().get("constantFreeFloating")); tmpScore += travelTime * Double.parseDouble(this.config.getModule("FreeFloating").getParams().get("travelingFreeFloating")) / 3600.0; - } - - else if (("twoway_vehicle").equals(mode)) { - + } + + else if (("twoway_vehicle").equals(mode)) { + tmpScore += Double.parseDouble(this.config.getModule("TwoWayCarsharing").getParams().get("constantTwoWayCarsharing")); tmpScore += travelTime * Double.parseDouble(this.config.getModule("TwoWayCarsharing").getParams().get("travelingTwoWayCarsharing")) / 3600.0; } } - + else if (walkingLegs.contains(mode)) { - + tmpScore += getWalkScore(leg.getRoute().getDistance(), travelTime); - - }*/ + + }*/ return tmpScore; } diff --git a/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingIT.java b/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingIT.java index a73015e0dd5..045303dc9c2 100644 --- a/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingIT.java +++ b/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingIT.java @@ -19,15 +19,15 @@ package org.matsim.contrib.carsharing.runExample; -import static org.matsim.core.config.groups.PlansCalcRouteConfigGroup.AccessEgressType; -import static org.matsim.core.config.groups.PlansCalcRouteConfigGroup.TeleportedModeParams; +import static org.matsim.core.config.groups.RoutingConfigGroup.AccessEgressType; +import static org.matsim.core.config.groups.RoutingConfigGroup.TeleportedModeParams; import com.google.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.analysis.LegHistogram; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -55,10 +55,10 @@ public class RunCarsharingIT { private final static Logger log = LogManager.getLogger(RunCarsharingIT.class); - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public final void test() { + final void test() { Config config = ConfigUtils.loadConfig(utils.getClassInputDirectory() + "/config.xml", new FreeFloatingConfigGroup(), new OneWayCarsharingConfigGroup(), @@ -66,8 +66,8 @@ public final void test() { new CarsharingConfigGroup(), new DvrpConfigGroup()); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.overwriteExistingFiles); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.overwriteExistingFiles); config.network().setInputFile("network.xml"); @@ -79,8 +79,8 @@ public final void test() { config.facilities().setInputFile("facilities.xml"); config.facilities().setFacilitiesSource(FacilitiesConfigGroup.FacilitiesSource.fromFile); - config.plansCalcRoute().setAccessEgressType(AccessEgressType.none); // otherwise does not work. kai,feb'16 - config.plansCalcRoute().setRoutingRandomness(0.); + config.routing().setAccessEgressType(AccessEgressType.none); // otherwise does not work. kai,feb'16 + config.routing().setRoutingRandomness(0.); // config.plansCalcRoute().setInsertingAccessEgressWalk(AccessEgressType.directWalk); CarsharingConfigGroup csConfig = (CarsharingConfigGroup) config.getModule(CarsharingConfigGroup.GROUP_NAME); @@ -103,21 +103,21 @@ public final void test() { params.setTeleportedModeSpeed(0.83333333333); // params.setTeleportedModeSpeed( 2.0 ); params.setBeelineDistanceFactor(1.3); - config.plansCalcRoute().addModeRoutingParams(params); + config.routing().addModeRoutingParams(params); } { - config.plansCalcRoute().removeModeRoutingParams(TransportMode.walk); + config.routing().removeModeRoutingParams(TransportMode.walk); TeleportedModeParams params = new TeleportedModeParams(TransportMode.walk); params.setTeleportedModeSpeed(0.83333333333); // params.setTeleportedModeSpeed( 2.0 ); params.setBeelineDistanceFactor(1.3); - config.plansCalcRoute().addModeRoutingParams(params); + config.routing().addModeRoutingParams(params); } // --- Scenario scenario = ScenarioUtils.loadScenario(config); - config.plansCalcRoute().setAccessEgressType(AccessEgressType.accessEgressModeToLink); + config.routing().setAccessEgressType(AccessEgressType.accessEgressModeToLink); // --- @@ -162,63 +162,63 @@ void testOutput(int iteration) { if (TransportMode.walk.equals(legMode)) { // walk is used for access+egress to car // -> number of walk legs for access+egress equals twice the number of car legs = 44 - Assert.assertEquals(44, nOfModeLegs); + Assertions.assertEquals(44, nOfModeLegs); } else if ("oneway_vehicle".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if (TransportMode.car.equals(legMode)) { - Assert.assertEquals(22, nOfModeLegs); + Assertions.assertEquals(22, nOfModeLegs); } else if ("egress_walk_ow".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("access_walk_ow".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } } else if (iteration == 10) { if (TransportMode.walk.equals(legMode)) { - Assert.assertEquals(2, nOfModeLegs); + Assertions.assertEquals(2, nOfModeLegs); } else if ("bike".equals(legMode)) { - Assert.assertEquals(2, nOfModeLegs); + Assertions.assertEquals(2, nOfModeLegs); } else if (TransportMode.car.equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("twoway_vehicle".equals(legMode)) { - Assert.assertEquals(6, nOfModeLegs); + Assertions.assertEquals(6, nOfModeLegs); } else if ("oneway_vehicle".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("egress_walk_ow".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("access_walk_ow".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("egress_walk_tw".equals(legMode)) { - Assert.assertEquals(3, nOfModeLegs); + Assertions.assertEquals(3, nOfModeLegs); } else if ("access_walk_tw".equals(legMode)) { - Assert.assertEquals(3, nOfModeLegs); + Assertions.assertEquals(3, nOfModeLegs); } else if ("egress_walk_ff".equals(legMode)) { - Assert.assertEquals(2, nOfModeLegs); + Assertions.assertEquals(2, nOfModeLegs); } else if ("access_walk_ff".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } } else if (iteration == 20) { if (TransportMode.walk.equals(legMode)) { - Assert.assertEquals(5, nOfModeLegs); + Assertions.assertEquals(5, nOfModeLegs); } else if ("bike".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("twoway_vehicle".equals(legMode)) { - Assert.assertEquals(6, nOfModeLegs); + Assertions.assertEquals(6, nOfModeLegs); } else if ("freefloating_vehicle".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("egress_walk_tw".equals(legMode)) { - Assert.assertEquals(3, nOfModeLegs); + Assertions.assertEquals(3, nOfModeLegs); } else if ("access_walk_tw".equals(legMode)) { - Assert.assertEquals(3, nOfModeLegs); + Assertions.assertEquals(3, nOfModeLegs); } else if ("access_walk_ff".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } else if ("egress_walk_ff".equals(legMode)) { - Assert.assertEquals(0, nOfModeLegs); + Assertions.assertEquals(0, nOfModeLegs); } } diff --git a/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingRelocationIT.java b/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingRelocationIT.java deleted file mode 100644 index 64f0d96606b..00000000000 --- a/contribs/carsharing/src/test/java/org/matsim/contrib/carsharing/runExample/RunCarsharingRelocationIT.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.matsim.contrib.carsharing.runExample; - -public class RunCarsharingRelocationIT { - - - - - -} diff --git a/contribs/carsharing/test/input/org/matsim/contrib/carsharing/runExample/RunCarsharingIT/config.xml b/contribs/carsharing/test/input/org/matsim/contrib/carsharing/runExample/RunCarsharingIT/config.xml index 0be55d6d96c..adb6c05c1a0 100644 --- a/contribs/carsharing/test/input/org/matsim/contrib/carsharing/runExample/RunCarsharingIT/config.xml +++ b/contribs/carsharing/test/input/org/matsim/contrib/carsharing/runExample/RunCarsharingIT/config.xml @@ -23,8 +23,6 @@ - - @@ -45,11 +43,11 @@ - - + + - + @@ -254,7 +252,7 @@ - + diff --git a/contribs/commercialTrafficApplications/scenarios/grid/jointDemand_config.xml b/contribs/commercialTrafficApplications/scenarios/grid/jointDemand_config.xml index a50d4e78394..d7c91a56d08 100644 --- a/contribs/commercialTrafficApplications/scenarios/grid/jointDemand_config.xml +++ b/contribs/commercialTrafficApplications/scenarios/grid/jointDemand_config.xml @@ -1,15 +1,6 @@ - - - - - - - - - @@ -47,7 +38,7 @@ - + @@ -392,24 +383,6 @@ - - - - - - - - - - - - - - - - - - @@ -544,8 +517,6 @@ - - diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperator.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperator.java index 29c3c8662e9..f1862ee3842 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperator.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperator.java @@ -23,8 +23,8 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Carriers; import org.matsim.core.config.groups.GlobalConfigGroup; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.population.algorithms.PlanAlgorithm; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialJobGenerator.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialJobGenerator.java index 024ab6e45e6..77b82e6208b 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialJobGenerator.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialJobGenerator.java @@ -21,7 +21,7 @@ import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Population; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carriers; import org.matsim.core.controler.listener.AfterMobsimListener; import org.matsim.core.controler.listener.BeforeMobsimListener; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficAnalysisListener.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficAnalysisListener.java index fb67736cd99..d41196496c1 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficAnalysisListener.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficAnalysisListener.java @@ -25,8 +25,8 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.matsim.api.core.v01.Id; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Carriers; import org.matsim.core.controler.MatsimServices; import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.controler.listener.IterationEndsListener; @@ -77,7 +77,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { writeIterationCarrierStats(event); writeJobStats(services.getControlerIO().getIterationFilename(event.getIteration(), "commercialJobStats.csv")); analyzeCarrierMarketShares(event.getIteration()); - + firstIteration = false; } diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficChecker.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficChecker.java index 88e68e04d36..8c561e9217c 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficChecker.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficChecker.java @@ -27,8 +27,8 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.Population; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Carriers; import java.util.Collection; import java.util.Map; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialJobGenerator.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialJobGenerator.java index 657770b272b..3327f46292c 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialJobGenerator.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialJobGenerator.java @@ -36,20 +36,10 @@ import org.matsim.api.core.v01.population.Population; import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierPlanWriter; -import org.matsim.contrib.freight.carrier.CarrierService; -import org.matsim.contrib.freight.carrier.CarrierUtils; -import org.matsim.contrib.freight.carrier.CarrierVehicle; -import org.matsim.contrib.freight.carrier.CarrierVehicleTypes; -import org.matsim.contrib.freight.carrier.Carriers; -import org.matsim.contrib.freight.carrier.CarrierConstants; -import org.matsim.contrib.freight.carrier.ScheduledTour; -import org.matsim.contrib.freight.carrier.TimeWindow; -import org.matsim.contrib.freight.carrier.Tour; -import org.matsim.contrib.freight.jsprit.VRPTransportCostsFactory; +import org.matsim.freight.carriers.*; +import org.matsim.freight.carriers.jsprit.VRPTransportCostsFactory; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.events.AfterMobsimEvent; import org.matsim.core.controler.events.BeforeMobsimEvent; import org.matsim.core.population.PopulationUtils; @@ -127,7 +117,7 @@ private void buildVehicleAndDriver(Carrier carrier, Person driverPerson, Carrier if (!scenario.getVehicles().getVehicleTypes().containsKey(carrierVehicle.getType().getId())) scenario.getVehicles().addVehicleType(carrierVehicle.getType()); Id vid = Id.createVehicleId(driverPerson.getId()); - VehicleUtils.insertVehicleIdsIntoAttributes(driverPerson, Map.of(CarrierUtils.getCarrierMode(carrier), vid)); + VehicleUtils.insertVehicleIdsIntoAttributes(driverPerson, Map.of(CarriersUtils.getCarrierMode(carrier), vid)); scenario.getVehicles() .addVehicle(scenario.getVehicles().getFactory().createVehicle(vid, carrierVehicle.getType())); freightVehicles.add(vid); @@ -211,7 +201,7 @@ private void manageJspritDepartureTimes(Plan plan) { */ private Plan createPlainPlanFromTour(Carrier carrier, ScheduledTour scheduledTour) { - String carrierMode = CarrierUtils.getCarrierMode(carrier); + String carrierMode = CarriersUtils.getCarrierMode(carrier); // Create empty plan Plan plan = PopulationUtils.createPlan(); @@ -223,7 +213,7 @@ private Plan createPlainPlanFromTour(Carrier carrier, ScheduledTour scheduledTou plan.addActivity(startActivity); for (Tour.TourElement tourElement : scheduledTour.getTour().getTourElements()) { - if (tourElement instanceof org.matsim.contrib.freight.carrier.Tour.Leg) { + if (tourElement instanceof Tour.Leg) { // Take information from scheduled leg and create a defaultLeg Tour.Leg tourLeg = (Tour.Leg) tourElement; @@ -301,7 +291,7 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { createAndAddFreightAgents(this.carriers, this.scenario.getPopulation()); event.getServices().getInjector().getInstance(ScoreCommercialJobs.class).prepareTourArrivalsForDay(); - String dir = event.getServices().getConfig().controler().getOutputDirectory() + "/ITERS/it." + event.getIteration() + "/"; + String dir = event.getServices().getConfig().controller().getOutputDirectory() + "/ITERS/it." + event.getIteration() + "/"; log.info("writing carrier file of iteration " + event.getIteration() + " to " + dir); CarrierPlanWriter planWriter = new CarrierPlanWriter(carriers); planWriter.write(dir + "carriers_it" + event.getIteration() + ".xml"); @@ -415,7 +405,7 @@ private void toggleChangeCommercialJobOperatorStrategy(int currentIteration) { log.info("Toggle " + ChangeCommercialJobOperator.SELECTOR_NAME); } - Collection allStrategies = this.scenario.getConfig().strategy().getStrategySettings(); + Collection allStrategies = this.scenario.getConfig().replanning().getStrategySettings(); for (StrategySettings strategy : allStrategies) { if (strategy.getStrategyName().equals(ChangeCommercialJobOperator.SELECTOR_NAME)) { diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandModule.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandModule.java index 5860e8a5cd9..a4f182cf17a 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandModule.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandModule.java @@ -27,10 +27,10 @@ import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtModule; import org.matsim.contrib.dvrp.run.DvrpModule; -import org.matsim.contrib.freight.carrier.Carriers; -import org.matsim.contrib.freight.jsprit.NetworkBasedTransportCostsFactory; -import org.matsim.contrib.freight.jsprit.VRPTransportCostsFactory; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.CarriersUtils; +import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCostsFactory; +import org.matsim.freight.carriers.jsprit.VRPTransportCostsFactory; import org.matsim.core.config.Config; import org.matsim.core.controler.AbstractModule; import org.matsim.core.replanning.PlanStrategy; @@ -92,7 +92,7 @@ private CarrierProvider() { } public Carriers get() { - return FreightUtils.getCarriers(this.scenario); + return CarriersUtils.getCarriers(this.scenario); } } diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandUtils.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandUtils.java index 5089e8b9e87..e433a3651e6 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandUtils.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/JointDemandUtils.java @@ -22,9 +22,9 @@ import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierVehicle; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierVehicle; +import org.matsim.freight.carriers.Carriers; import javax.annotation.Nullable; import java.util.*; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample.java index 9a0df38130b..905102b912c 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample.java @@ -22,12 +22,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; @@ -70,17 +70,17 @@ public void run(URL configUrl){ jointDemandConfigGroup.setFirstLegTraveltimeBufferFactor(1.5); jointDemandConfigGroup.setChangeCommercialJobOperatorInterval(2); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setTravelTimeSliceWidth(3600); - freightConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); - freightConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setTravelTimeSliceWidth(3600); + freightCarriersConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); + freightCarriersConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); prepareConfig(config); Scenario scenario = loadScenario(config); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightConfigGroup + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightCarriersConfigGroup //alternatively, one can read in the input Carriers and CarrierVehicleTypes manually and use - //FreightUtils.getCarriers(scenario) and FreightUtils.getCarrierVehicleTypes(scenario) + //CarrierControlerUtils.getCarriers(scenario) and CarrierControlerUtils.getCarrierVehicleTypes(scenario) Controler controler = new Controler(scenario); controler.addOverridingModule(new JointDemandModule() ); @@ -88,28 +88,28 @@ public void run(URL configUrl){ } private static void prepareConfig(Config config) { - StrategyConfigGroup.StrategySettings changeExpBeta = new StrategyConfigGroup.StrategySettings(); + ReplanningConfigGroup.StrategySettings changeExpBeta = new ReplanningConfigGroup.StrategySettings(); changeExpBeta.setStrategyName(DefaultPlanStrategiesModule.DefaultSelector.ChangeExpBeta); changeExpBeta.setWeight(0.5); - config.strategy().addStrategySettings(changeExpBeta); + config.replanning().addStrategySettings(changeExpBeta); - StrategyConfigGroup.StrategySettings changeJobOperator = new StrategyConfigGroup.StrategySettings(); + ReplanningConfigGroup.StrategySettings changeJobOperator = new ReplanningConfigGroup.StrategySettings(); changeJobOperator.setStrategyName(ChangeCommercialJobOperator.SELECTOR_NAME); changeJobOperator.setWeight(0.5); - config.strategy().addStrategySettings(changeJobOperator); + config.replanning().addStrategySettings(changeJobOperator); - config.strategy().setFractionOfIterationsToDisableInnovation(.8); - PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + config.replanning().setFractionOfIterationsToDisableInnovation(.8); + ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(14 * 3600); - config.planCalcScore().addActivityParams(home); - PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + config.scoring().addActivityParams(home); + ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(14 * 3600); work.setOpeningTime(8 * 3600); work.setClosingTime(8 * 3600); - config.planCalcScore().addActivityParams(work); - config.controler().setWriteEventsInterval(5); - config.controler().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample"); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(5); + config.scoring().addActivityParams(work); + config.controller().setWriteEventsInterval(5); + config.controller().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandCarToggleJspritExample"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(5); } } diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ScoreCommercialJobs.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ScoreCommercialJobs.java index 7cdab223e4b..c3a6a068701 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ScoreCommercialJobs.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ScoreCommercialJobs.java @@ -30,10 +30,10 @@ import org.matsim.api.core.v01.events.handler.ActivityStartEventHandler; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.*; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierService; -import org.matsim.contrib.freight.carrier.Carriers; -import org.matsim.contrib.freight.carrier.CarrierConstants; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierService; +import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.CarrierConstants; import org.matsim.core.api.experimental.events.EventsManager; import java.util.*; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourLengthAnalyzer.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourLengthAnalyzer.java index 5ea36ca6528..c1434c351b9 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourLengthAnalyzer.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourLengthAnalyzer.java @@ -33,7 +33,7 @@ import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Person; -import org.matsim.contrib.freight.carrier.CarrierConstants; +import org.matsim.freight.carriers.CarrierConstants; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.vehicles.Vehicle; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java index 1a3fd7e9713..2c1e9d82e2e 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java @@ -31,14 +31,15 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.CarrierPlan; -import org.matsim.contrib.freight.carrier.CarrierUtils; -import org.matsim.contrib.freight.carrier.Carriers; -import org.matsim.contrib.freight.jsprit.MatsimJspritFactory; -import org.matsim.contrib.freight.jsprit.NetworkBasedTransportCosts; -import org.matsim.contrib.freight.jsprit.VRPTransportCosts; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierPlan; +import org.matsim.freight.carriers.CarriersUtils; +import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.jsprit.MatsimJspritFactory; +import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts; +import org.matsim.freight.carriers.jsprit.VRPTransportCosts; import org.matsim.core.router.util.TravelTime; +import org.matsim.freight.carriers.jsprit.NetworkRouter; import org.matsim.vehicles.VehicleType; import java.util.ArrayList; @@ -91,8 +92,8 @@ static void runTourPlanningForCarriers(Carriers carriers, Scenario scenario, VRP HashMap, Integer> sortedMap = carrierServiceCounterMap.entrySet().stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new)); - - + + ArrayList> tempList = new ArrayList<>(sortedMap.keySet()); ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors()); forkJoinPool.submit(() -> tempList.parallelStream().forEach(carrierId -> { @@ -152,7 +153,7 @@ static void runTourPlanningForCarriers(Carriers carriers, Scenario scenario, VRP log.info("setting maxIterations=1 as carrier has no services"); algorithm.setMaxIterations(1); } else { - algorithm.setMaxIterations(CarrierUtils.getJspritIterations(carrier)); + algorithm.setMaxIterations(CarriersUtils.getJspritIterations(carrier)); } // variationCoefficient = stdDeviation/mean. so i set the threshold rather soft @@ -167,7 +168,7 @@ static void runTourPlanningForCarriers(Carriers carriers, Scenario scenario, VRP CarrierPlan carrierPlan = MatsimJspritFactory.createPlan(carrier, bestSolution); log.info("routing plan for carrier " + carrier.getId()); - org.matsim.contrib.freight.jsprit.NetworkRouter.routePlan(carrierPlan, transportCosts); // we need to route + NetworkRouter.routePlan(carrierPlan, transportCosts); // we need to route // the plans in // order to create // reasonable diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExample.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExample.java index 5a3386fba32..62c6584a1de 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExample.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExample.java @@ -25,12 +25,12 @@ import org.matsim.contrib.commercialTrafficApplications.jointDemand.ChangeCommercialJobOperator; import org.matsim.contrib.commercialTrafficApplications.jointDemand.JointDemandConfigGroup; import org.matsim.contrib.commercialTrafficApplications.jointDemand.JointDemandModule; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; @@ -72,17 +72,17 @@ public void run(URL configUrl){ JointDemandConfigGroup jointDemandConfigGroup = ConfigUtils.addOrGetModule(config, JointDemandConfigGroup.class); jointDemandConfigGroup.setFirstLegTraveltimeBufferFactor(1.5); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setTravelTimeSliceWidth(3600); - freightConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); - freightConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setTravelTimeSliceWidth(3600); + freightCarriersConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); + freightCarriersConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); prepareConfig(config); Scenario scenario = loadScenario(config); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightConfigGroup + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightCarriersConfigGroup //alternatively, one can read in the input Carriers and CarrierVehicleTypes manually and use - //FreightUtils.getCarriers(scenario) and FreightUtils.getCarrierVehicleTypes(scenario) + //CarrierControlerUtils.getCarriers(scenario) and CarrierControlerUtils.getCarrierVehicleTypes(scenario) Controler controler = new Controler(scenario); controler.addOverridingModule(new JointDemandModule() ); @@ -90,28 +90,28 @@ public void run(URL configUrl){ } private static void prepareConfig(Config config) { - StrategyConfigGroup.StrategySettings changeExpBeta = new StrategyConfigGroup.StrategySettings(); + ReplanningConfigGroup.StrategySettings changeExpBeta = new ReplanningConfigGroup.StrategySettings(); changeExpBeta.setStrategyName(DefaultPlanStrategiesModule.DefaultSelector.ChangeExpBeta); changeExpBeta.setWeight(0.5); - config.strategy().addStrategySettings(changeExpBeta); + config.replanning().addStrategySettings(changeExpBeta); - StrategyConfigGroup.StrategySettings changeJobOperator = new StrategyConfigGroup.StrategySettings(); + ReplanningConfigGroup.StrategySettings changeJobOperator = new ReplanningConfigGroup.StrategySettings(); changeJobOperator.setStrategyName(ChangeCommercialJobOperator.SELECTOR_NAME); changeJobOperator.setWeight(0.5); - config.strategy().addStrategySettings(changeJobOperator); + config.replanning().addStrategySettings(changeJobOperator); - config.strategy().setFractionOfIterationsToDisableInnovation(.8); - PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + config.replanning().setFractionOfIterationsToDisableInnovation(.8); + ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(14 * 3600); - config.planCalcScore().addActivityParams(home); - PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + config.scoring().addActivityParams(home); + ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(14 * 3600); work.setOpeningTime(8 * 3600); work.setClosingTime(8 * 3600); - config.planCalcScore().addActivityParams(work); - config.controler().setWriteEventsInterval(5); - config.controler().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandCarExample"); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(5); + config.scoring().addActivityParams(work); + config.controller().setWriteEventsInterval(5); + config.controller().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandCarExample"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(5); } } diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java index ee0983bd2df..68addb0a68a 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExample.java @@ -36,13 +36,13 @@ import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; @@ -80,14 +80,14 @@ public static void main(String[] args) throws IOException { public void run(URL configURL){ Config config = loadConfig(configURL); prepareConfig(config); - DrtConfigs.adjustMultiModeDrtConfig(MultiModeDrtConfigGroup.get(config), config.planCalcScore(), - config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(MultiModeDrtConfigGroup.get(config), config.scoring(), + config.routing()); Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightConfigGroup + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); //assumes that input file paths are set in FreightCarriersConfigGroup //alternatively, one can read in the input Carriers and CarrierVehicleTypes manually and use - //FreightUtils.getCarriers(scenario) and FreightUtils.getCarrierVehicleTypes(scenario) + //CarrierControlerUtils.getCarriers(scenario) and CarrierControlerUtils.getCarrierVehicleTypes(scenario) Controler controler = new Controler(scenario); controler.addOverridingModule(new JointDemandModule()); @@ -102,33 +102,33 @@ private static void prepareConfig(Config config) { config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); - StrategyConfigGroup.StrategySettings changeExpBeta = new StrategyConfigGroup.StrategySettings(); + ReplanningConfigGroup.StrategySettings changeExpBeta = new ReplanningConfigGroup.StrategySettings(); changeExpBeta.setStrategyName(DefaultPlanStrategiesModule.DefaultSelector.ChangeExpBeta); changeExpBeta.setWeight(0.5); - config.strategy().addStrategySettings(changeExpBeta); - StrategyConfigGroup.StrategySettings changeServiceOperator = new StrategyConfigGroup.StrategySettings(); + config.replanning().addStrategySettings(changeExpBeta); + ReplanningConfigGroup.StrategySettings changeServiceOperator = new ReplanningConfigGroup.StrategySettings(); changeServiceOperator.setStrategyName(ChangeCommercialJobOperator.SELECTOR_NAME); changeServiceOperator.setWeight(0.5); - config.strategy().addStrategySettings(changeServiceOperator); + config.replanning().addStrategySettings(changeServiceOperator); - config.strategy().setFractionOfIterationsToDisableInnovation(.8); - PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + config.replanning().setFractionOfIterationsToDisableInnovation(.8); + ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(14 * 3600); - config.planCalcScore().addActivityParams(home); - PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + config.scoring().addActivityParams(home); + ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(14 * 3600); work.setOpeningTime(8 * 3600); work.setClosingTime(8 * 3600); - config.planCalcScore().addActivityParams(work); - config.controler().setWriteEventsInterval(1); - config.controler().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandUsingDRTExample"); - config.controler() + config.scoring().addActivityParams(work); + config.controller().setWriteEventsInterval(1); + config.controller().setOutputDirectory("output/commercialTrafficApplications/jointDemand/RunJointDemandUsingDRTExample"); + config.controller() .setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); config.qsim().setEndTime(26 * 3600); config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.onlyUseEndtime); - config.controler().setLastIteration(5); + config.controller().setLastIteration(5); } private static void loadConfigGroups(Config config) { @@ -147,8 +147,8 @@ private static void loadConfigGroups(Config config) { JointDemandConfigGroup jointDemandConfigGroup = ConfigUtils.addOrGetModule(config, JointDemandConfigGroup.class); jointDemandConfigGroup.setFirstLegTraveltimeBufferFactor(1.5); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setCarriersFile("jointDemand_carriers_drt.xml"); - freightConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersFile("jointDemand_carriers_drt.xml"); + freightCarriersConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); } } diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperatorTest.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperatorTest.java index a66096756ac..5dad7e11991 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperatorTest.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/ChangeCommercialJobOperatorTest.java @@ -1,17 +1,14 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Plan; -import org.matsim.contrib.commercialTrafficApplications.jointDemand.ChangeCommercialJobOperator; -import org.matsim.contrib.commercialTrafficApplications.jointDemand.JointDemandUtils; -import org.matsim.contrib.commercialTrafficApplications.jointDemand.TestScenarioGeneration; -import org.matsim.contrib.freight.carrier.Carrier; -import org.matsim.contrib.freight.carrier.Carriers; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Carriers; import org.matsim.core.router.util.TravelTime; import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; @@ -20,8 +17,8 @@ public class ChangeCommercialJobOperatorTest { - @Test - public void getPlanAlgoInstance() { + @Test + void getPlanAlgoInstance() { Carriers carriers = TestScenarioGeneration.generateCarriers(); @@ -34,19 +31,19 @@ public void getPlanAlgoInstance() { Activity work = (Activity) testPlan.getPlanElements().get(2); Id carrierId = JointDemandUtils.getCurrentlySelectedCarrierForJob(work, 1); - Assert.assertEquals("the person should expect a pizza", "pizza", JointDemandUtils.getCarrierMarket(carriers.getCarriers().get(carrierId))); - Assert.assertTrue("the person should expect a pizza from the italian place", carrierId.toString().contains("italian")); + Assertions.assertEquals("pizza", JointDemandUtils.getCarrierMarket(carriers.getCarriers().get(carrierId)), "the person should expect a pizza"); + Assertions.assertTrue(carrierId.toString().contains("italian"), "the person should expect a pizza from the italian place"); changeCommercialJobOperator.getPlanAlgoInstance().run(testPlan); carrierId = JointDemandUtils.getCurrentlySelectedCarrierForJob(work, 1); - Assert.assertTrue("the person should expect a pizza from the american place", carrierId.toString().contains("american")); + Assertions.assertTrue(carrierId.toString().contains("american"), "the person should expect a pizza from the american place"); changeCommercialJobOperator.getPlanAlgoInstance().run(testPlan); carrierId = JointDemandUtils.getCurrentlySelectedCarrierForJob(work, 1); - Assert.assertTrue("the person should expect a pizza from the italian place", carrierId.toString().contains("italian")); + Assertions.assertTrue(carrierId.toString().contains("italian"), "the person should expect a pizza from the italian place"); } -} \ No newline at end of file +} diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficIntegrationTest.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficIntegrationTest.java index 2ea7d0a9853..c0132d8903c 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficIntegrationTest.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/CommercialTrafficIntegrationTest.java @@ -1,9 +1,9 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; @@ -12,16 +12,16 @@ public class CommercialTrafficIntegrationTest { - @Test - public void runCommercialTrafficIT() { + @Test + void runCommercialTrafficIT() { Config config = ConfigUtils.loadConfig("./scenarios/grid/jointDemand_config.xml"); - config.controler().setLastIteration(5); + config.controller().setLastIteration(5); ConfigUtils.addOrGetModule(config, JointDemandConfigGroup.class); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); - freightConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); + freightCarriersConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); Scenario scenario = ScenarioUtils.loadScenario(config); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); Controler controler = new Controler(scenario); controler.addOverridingModule(new JointDemandModule()); controler.run(); diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialServiceScoreTest.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialServiceScoreTest.java index b96b3e5ca86..d2ce82e986d 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialServiceScoreTest.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/DefaultCommercialServiceScoreTest.java @@ -1,19 +1,19 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.contrib.commercialTrafficApplications.jointDemand.DefaultCommercialServiceScore; public class DefaultCommercialServiceScoreTest { - @Test - public void calcScore() { + @Test + void calcScore() { DefaultCommercialServiceScore serviceScore = new DefaultCommercialServiceScore(6, -6, 1800); - Assert.assertEquals(serviceScore.calcScore(0), 6., 0.001); - Assert.assertEquals(serviceScore.calcScore(1800), 0, 0.001); - Assert.assertEquals(serviceScore.calcScore(3600), -6., 0.001); - Assert.assertEquals(serviceScore.calcScore(7200), -6., 0.001); + Assertions.assertEquals(serviceScore.calcScore(0), 6., 0.001); + Assertions.assertEquals(serviceScore.calcScore(1800), 0, 0.001); + Assertions.assertEquals(serviceScore.calcScore(3600), -6., 0.001); + Assertions.assertEquals(serviceScore.calcScore(7200), -6., 0.001); } } \ No newline at end of file diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/IsTheRightCustomerScoredTest.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/IsTheRightCustomerScoredTest.java index 3b250c4f855..813601153ce 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/IsTheRightCustomerScoredTest.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/IsTheRightCustomerScoredTest.java @@ -18,18 +18,16 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.PopulationFactory; -import org.matsim.contrib.freight.FreightConfigGroup; -import org.matsim.contrib.freight.carrier.*; -import org.matsim.contrib.freight.controler.FreightUtils; +import org.matsim.freight.carriers.*; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; @@ -43,22 +41,22 @@ public class IsTheRightCustomerScoredTest { Scenario scenario; - @Before + @BeforeEach public void setUp() { Config config = ConfigUtils.loadConfig("./scenarios/grid/jointDemand_config.xml"); - config.controler().setLastIteration(0); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles); + config.controller().setLastIteration(0); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles); JointDemandConfigGroup jointDemandConfigGroup = ConfigUtils.addOrGetModule(config, JointDemandConfigGroup.class); jointDemandConfigGroup.setMaxJobScore(MAX_JOB_SCORE); - FreightConfigGroup freightConfigGroup = ConfigUtils.addOrGetModule(config, FreightConfigGroup.class); - freightConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); - freightConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersFile("jointDemand_carriers_car.xml"); + freightCarriersConfigGroup.setCarriersVehicleTypesFile("jointDemand_vehicleTypes.xml"); scenario = ScenarioUtils.loadScenario(config); - FreightUtils.loadCarriersAccordingToFreightConfig(scenario); + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); //limit the fleet size of carrier pizza_1 so that it can handly only one order/job - FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("salamiPizza", Carrier.class)).getCarrierCapabilities().setFleetSize(CarrierCapabilities.FleetSize.FINITE); + CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("salamiPizza", Carrier.class)).getCarrierCapabilities().setFleetSize(CarrierCapabilities.FleetSize.FINITE); preparePopulation(scenario); @@ -100,14 +98,14 @@ private void preparePopulation(Scenario scenario) { } - @Test - public void testIfTheRightPersonIsScoredForReceivingAJob() { + @Test + void testIfTheRightPersonIsScoredForReceivingAJob() { Plan partyPizzaPlan = scenario.getPopulation().getPersons().get(Id.createPersonId("customerOrderingForParty")).getSelectedPlan(); Plan lonelyPizzaPlan = scenario.getPopulation().getPersons().get(Id.createPersonId("customerOrderingJustForItself")).getSelectedPlan(); Plan nonCustomerPlan = scenario.getPopulation().getPersons().get(Id.createPersonId("nonCustomer")).getSelectedPlan(); //derive the service activity from the carrier plan and compare the service id (which should contain the customer id) with the person id of the expected customer - Carrier pizzaCarrier = FreightUtils.getCarriers(scenario).getCarriers().get(Id.create("salamiPizza", Carrier.class)); + Carrier pizzaCarrier = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create("salamiPizza", Carrier.class)); ScheduledTour tour = (ScheduledTour) pizzaCarrier.getSelectedPlan().getScheduledTours().toArray()[0]; Id serviceActivity = tour.getTour().getTourElements().stream() .filter(tourElement -> tourElement instanceof Tour.ServiceActivity) @@ -115,14 +113,14 @@ public void testIfTheRightPersonIsScoredForReceivingAJob() { .map(carrierService -> carrierService.getId()) .findFirst().orElseThrow(() -> new RuntimeException("no service activity found in scheduledTours")); - Assert.assertEquals("the person that is delivered pizza should be customerOrderingForParty", partyPizzaPlan.getPerson().getId().toString(), serviceActivity.toString().split("_")[0]); + Assertions.assertEquals(partyPizzaPlan.getPerson().getId().toString(), serviceActivity.toString().split("_")[0], "the person that is delivered pizza should be customerOrderingForParty"); //compare scores - Assert.assertTrue("the plan of the customer receiving a job should get a higher score than the plan of the non customer ", partyPizzaPlan.getScore() > nonCustomerPlan.getScore()); - Assert.assertTrue("the plan of the customer receiving a job should get a higher score than the plan of the customer not receiving one ", partyPizzaPlan.getScore() > lonelyPizzaPlan.getScore()); - Assert.assertTrue("the difference of receiving a job in time and not receiving it at all should be the maxJobScore=" + MAX_JOB_SCORE + " as job is performed in time", partyPizzaPlan.getScore() - lonelyPizzaPlan.getScore() == MAX_JOB_SCORE); - Assert.assertEquals("not receiving a job at all should be scored with zero", lonelyPizzaPlan.getScore(), 0.0, MatsimTestUtils.EPSILON); - Assert.assertTrue(lonelyPizzaPlan.getScore() - nonCustomerPlan.getScore() == 0); + Assertions.assertTrue(partyPizzaPlan.getScore() > nonCustomerPlan.getScore(), "the plan of the customer receiving a job should get a higher score than the plan of the non customer "); + Assertions.assertTrue(partyPizzaPlan.getScore() > lonelyPizzaPlan.getScore(), "the plan of the customer receiving a job should get a higher score than the plan of the customer not receiving one "); + Assertions.assertTrue(partyPizzaPlan.getScore() - lonelyPizzaPlan.getScore() == MAX_JOB_SCORE, "the difference of receiving a job in time and not receiving it at all should be the maxJobScore=" + MAX_JOB_SCORE + " as job is performed in time"); + Assertions.assertEquals(lonelyPizzaPlan.getScore(), 0.0, MatsimTestUtils.EPSILON, "not receiving a job at all should be scored with zero"); + Assertions.assertTrue(lonelyPizzaPlan.getScore() - nonCustomerPlan.getScore() == 0); } diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarExampleSkipIntervalIT.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarExampleSkipIntervalIT.java index 5ec00c316dc..884319ca6ef 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarExampleSkipIntervalIT.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/RunJointDemandCarExampleSkipIntervalIT.java @@ -1,13 +1,13 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; public class RunJointDemandCarExampleSkipIntervalIT { @Test - public void main() throws IOException { + void main() throws IOException { RunJointDemandCarToggleJspritExample.main(new String[0]); } } \ No newline at end of file diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java index 629c1bbd6c6..1d6b845a665 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java @@ -26,9 +26,9 @@ import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; -import org.matsim.contrib.freight.carrier.*; import org.matsim.core.config.Config; import org.matsim.core.population.PopulationUtils; +import org.matsim.freight.carriers.*; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; @@ -54,18 +54,18 @@ public static Carriers generateCarriers() { Carriers carriers = new Carriers(); Carrier italianPizzaPlace = CarrierImpl.newInstance(Id.create("pizza_italian", Carrier.class)); - CarrierUtils.setCarrierMode(italianPizzaPlace, TransportMode.car); - CarrierUtils.setJspritIterations(italianPizzaPlace, 20); + CarriersUtils.setCarrierMode(italianPizzaPlace, TransportMode.car); + CarriersUtils.setJspritIterations(italianPizzaPlace, 20); italianPizzaPlace.getAttributes().putAttribute(JointDemandUtils.CARRIER_MARKET_ATTRIBUTE_NAME, "pizza"); Carrier americanPizzaPlace = CarrierImpl.newInstance(Id.create("pizza_american", Carrier.class)); - CarrierUtils.setCarrierMode(americanPizzaPlace, TransportMode.car); - CarrierUtils.setJspritIterations(americanPizzaPlace, 20); + CarriersUtils.setCarrierMode(americanPizzaPlace, TransportMode.car); + CarriersUtils.setJspritIterations(americanPizzaPlace, 20); americanPizzaPlace.getAttributes().putAttribute(JointDemandUtils.CARRIER_MARKET_ATTRIBUTE_NAME, "pizza"); Carrier shopping_1 = CarrierImpl.newInstance(Id.create("shopping_1", Carrier.class)); - CarrierUtils.setCarrierMode(shopping_1, TransportMode.car); - CarrierUtils.setJspritIterations(shopping_1, 20); + CarriersUtils.setCarrierMode(shopping_1, TransportMode.car); + CarriersUtils.setJspritIterations(shopping_1, 20); shopping_1.getAttributes().putAttribute(JointDemandUtils.CARRIER_MARKET_ATTRIBUTE_NAME, "shopping"); VehicleType type = createLightType(); diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExampleIT.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExampleIT.java index 5d07acb7686..663f68d69e2 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExampleIT.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandCarExampleIT.java @@ -1,6 +1,6 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand.examples; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contrib.commercialTrafficApplications.jointDemand.examples.RunJointDemandCarExample; import java.io.IOException; @@ -8,7 +8,7 @@ public class RunJointDemandCarExampleIT { @Test - public void main() throws IOException { + void main() throws IOException { RunJointDemandCarExample.main(new String[0]); } } \ No newline at end of file diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExampleIT.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExampleIT.java index 30fbe9ef2c0..e62b15cc0ba 100644 --- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExampleIT.java +++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/examples/RunJointDemandDRTExampleIT.java @@ -1,6 +1,6 @@ package org.matsim.contrib.commercialTrafficApplications.jointDemand.examples; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contrib.commercialTrafficApplications.jointDemand.examples.RunJointDemandDRTExample; import java.io.IOException; @@ -8,7 +8,7 @@ public class RunJointDemandDRTExampleIT { @Test - public void main() throws IOException { + void main() throws IOException { RunJointDemandDRTExample.main(new String[0]); } } \ No newline at end of file diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/csv/CompactCSVWriter.java b/contribs/common/src/main/java/org/matsim/contrib/common/csv/CompactCSVWriter.java index c51911f531a..35d7ec5f660 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/csv/CompactCSVWriter.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/csv/CompactCSVWriter.java @@ -21,10 +21,9 @@ package org.matsim.contrib.common.csv; import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; -import org.matsim.core.utils.io.UncheckedIOException; - import com.opencsv.CSVWriter; public class CompactCSVWriter extends CSVWriter { diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java deleted file mode 100644 index 7fba53c4198..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* *********************************************************************** * - * project: org.matsim.* - * RandomizedTransitRouterFacotry - * * - * *********************************************************************** * - * * - * copyright : (C) 2013 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 * - * * - * *********************************************************************** */ - -import org.matsim.core.config.Config; -import org.matsim.pt.router.*; -import org.matsim.pt.transitSchedule.api.TransitSchedule; - -import jakarta.inject.Inject; -import jakarta.inject.Provider; - - -/** - * @author dgrether - * - */ -public class RandomizingTransitRouterFactory implements Provider { - - private TransitRouterConfig trConfig; - private TransitSchedule schedule; - private TransitRouterNetwork routerNetwork; - - @Inject - RandomizingTransitRouterFactory(Config config, TransitSchedule schedule) { - this.trConfig = new TransitRouterConfig(config); - this.schedule = schedule; - this.routerNetwork = TransitRouterNetwork.createFromSchedule(schedule, trConfig.getBeelineWalkConnectionDistance()); - } - - @Override - public TransitRouter get() { - RandomizingTransitRouterTravelTimeAndDisutility ttCalculator = new RandomizingTransitRouterTravelTimeAndDisutility(trConfig); - ttCalculator.setDataCollection(RandomizingTransitRouterTravelTimeAndDisutility.DataCollection.randomizedParameters, true) ; - ttCalculator.setDataCollection(RandomizingTransitRouterTravelTimeAndDisutility.DataCollection.additionalInformation, false) ; - return new TransitRouterImpl(trConfig, new PreparedTransitSchedule(schedule), routerNetwork, ttCalculator, ttCalculator); - } - -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java deleted file mode 100644 index 1dc0dec0300..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* - * *********************************************************************** * - * * project: org.matsim.* - * * RandomizedTransitRouterModule.java - * * * - * * *********************************************************************** * - * * * - * * copyright : (C) 2015 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 * - * * * - * * *********************************************************************** - */ - -import org.matsim.core.controler.AbstractModule; -import org.matsim.pt.router.TransitRouter; - -public class RandomizingTransitRouterModule extends AbstractModule { - @Override - public void install() { - bind(TransitRouter.class).toProvider(RandomizingTransitRouterFactory.class); - } -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java deleted file mode 100644 index d75e386838e..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* *********************************************************************** * - * project: org.matsim.* - * RandomizedTransitRouterNetworkTravelTimeAndDisutility2 - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 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 * - * * - * *********************************************************************** */ - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.population.Person; -import org.matsim.core.gbl.MatsimRandom; -import org.matsim.pt.router.CustomDataManager; -import org.matsim.pt.router.TransitRouterConfig; -import org.matsim.pt.router.TransitRouterNetwork.TransitRouterNetworkLink; -import org.matsim.pt.router.TransitRouterNetworkTravelTimeAndDisutility; -import org.matsim.vehicles.Vehicle; - -import java.util.HashMap; -import java.util.Map; - - -/** - * When plugged into the transit router, will switch to a different, randomly generated combination of - * marginal utilities every time it is called for a new agent. - *

- * Comments:
    - *
  • In the literature, they seem to use log-normal distributions for the tastes. (Makes sense - * since it addresse the symmetry problem which I am addressing ad-hoc.) [M. K. Anderson, hEART'13] - * kai, sep'13 - *
  • People seem to use "gamma distributions for the error term" ("double stochastic assignment"). - * Not sure what that does, if we need it, etc. [M. K. Anderson, hEART'13] kai, sep'13 - *
- * @author kai - * @author dgrether - * - */ -public class RandomizingTransitRouterTravelTimeAndDisutility extends TransitRouterNetworkTravelTimeAndDisutility { - - public enum DataCollection {randomizedParameters, additionalInformation} - private Id cachedPersonId = null ; - private final TransitRouterConfig originalTransitRouterConfig ; - - private double localMarginalUtilityOfTravelTimeWalk_utl_s = Double.NaN ; - private double localMarginalUtilityOfWaitingPt_utl_s = Double.NaN ; - private double localUtilityOfLineSwitch_utl = Double.NaN ; - private double localMarginalUtilityOfTravelTimePt_utl_s = Double.NaN ; - private double localMarginalUtilityOfTravelDistancePt_utl_m = Double.NaN ; - - private Map dataCollectionConfig = new HashMap() ; - private Map dataCollectionStrings = new HashMap() ; - - public RandomizingTransitRouterTravelTimeAndDisutility(TransitRouterConfig routerConfig) { - super(routerConfig); - - prepareDataCollection(); - - // make sure that some parameters are not zero since otherwise the randomization will not work: - - // marg utl time wlk should be around -3/h or -(3/3600)/sec. Give warning if not at least 1/3600: - if ( -routerConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() < 1./3600. ) { - LogManager.getLogger(this.getClass()).warn( "marg utl of walk rather close to zero; randomization may not work") ; - } - // utl of line switch should be around -300sec or -0.5u. Give warning if not at least 0.1u: - if ( -routerConfig.getUtilityOfLineSwitch_utl() < 0.1 ) { - LogManager.getLogger(this.getClass()).warn( "utl of line switch rather close to zero; randomization may not work") ; - } - - this.originalTransitRouterConfig = routerConfig ; - - this.localMarginalUtilityOfTravelDistancePt_utl_m = routerConfig.getMarginalUtilityOfTravelDistancePt_utl_m(); - this.localMarginalUtilityOfTravelTimePt_utl_s = routerConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - this.localMarginalUtilityOfTravelTimeWalk_utl_s = routerConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() ; -// this.localMarginalUtilityOfWaitingPt_utl_s = routerConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - this.localMarginalUtilityOfWaitingPt_utl_s = routerConfig.getMarginalUtilityOfWaitingPt_utl_s() ; - this.localUtilityOfLineSwitch_utl = routerConfig.getUtilityOfLineSwitch_utl() ; - } - public final String getDataCollectionString( DataCollection item ) { - return dataCollectionStrings.get(item).toString() ; - } - - @Override - public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, - final CustomDataManager dataManager) { - - regenerateUtilityParametersIfPersonHasChanged(person); - - double disutl; - if (((TransitRouterNetworkLink) link).getRoute() == null) { - // (this means that it is a transfer link (walk)) - - double transfertime = getLinkTravelTime(link, time, person, vehicle); - double waittime = this.originalTransitRouterConfig.getAdditionalTransferTime(); - - // say that the effective walk time is the transfer time minus some "buffer" - double walktime = transfertime - waittime; - - disutl = - walktime * localMarginalUtilityOfTravelTimeWalk_utl_s - - waittime * localMarginalUtilityOfWaitingPt_utl_s - - localUtilityOfLineSwitch_utl; - - } else { - - double offVehWaitTime = offVehicleWaitTime(link, time); - - double inVehTime = getLinkTravelTime(link,time, person, vehicle) - offVehWaitTime ; - - disutl = -inVehTime * this.localMarginalUtilityOfTravelTimePt_utl_s - - offVehWaitTime * this.localMarginalUtilityOfWaitingPt_utl_s - - link.getLength() * this.localMarginalUtilityOfTravelDistancePt_utl_m; - } - - if ( this.dataCollectionConfig.get(DataCollection.additionalInformation )) { - StringBuffer strb = this.dataCollectionStrings.get(DataCollection.additionalInformation ) ; - strb.append("also collecting additional information") ; - } - - return disutl; - } - - @Override - public double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord) { - regenerateUtilityParametersIfPersonHasChanged(person); - return - getWalkTravelTime(person, coord, toCoord) * localMarginalUtilityOfTravelTimeWalk_utl_s ; - } - - public final void setDataCollection( DataCollection item, Boolean bbb ) { - LogManager.getLogger(this.getClass()).info( " settin data collection of " + item.toString() + " to " + bbb.toString() ) ; - dataCollectionConfig.put( item, bbb ) ; - } - - private void prepareDataCollection() { - for ( DataCollection dataCollection : DataCollection.values() ) { - switch ( dataCollection ) { - case randomizedParameters: - dataCollectionConfig.put( dataCollection, false ) ; - dataCollectionStrings.put( dataCollection, new StringBuffer() ) ; - break; - case additionalInformation: - dataCollectionConfig.put( dataCollection, false ) ; - dataCollectionStrings.put( dataCollection, new StringBuffer() ) ; - break; - } - } - } - - private void regenerateUtilityParametersIfPersonHasChanged(final Person person) { - if ( !person.getId().equals(this.cachedPersonId)) { - // yyyyyy probably not thread safe (?!?!) - - // person has changed, so ... - - // ... memorize new person id: - this.cachedPersonId = person.getId() ; - - // ... generate new random parameters: - { - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble() ; - localMarginalUtilityOfTravelTimeWalk_utl_s = tmp ; - // yy if this becomes too small, they may walk the whole way (is it really clear why this can happen?) - } - { - double tmp = this.originalTransitRouterConfig.getUtilityOfLineSwitch_utl() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble() ; - localUtilityOfLineSwitch_utl = tmp ; - } - { - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfWaitingPt_utl_s(); - tmp *= 5. * MatsimRandom.getRandom().nextDouble(); - localMarginalUtilityOfWaitingPt_utl_s = tmp; - } - { - // (Conceptually, the following is not necessary, but empirically, it seems to help. kai, jan'13) - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble(); - localMarginalUtilityOfTravelTimePt_utl_s = tmp; - } - - if ( this.dataCollectionConfig.get(DataCollection.randomizedParameters) ) { -// StringBuffer strb = this.dataCollectionStrings.get(DataCollection.randomizedParameters) ; -// strb.append - System.out.println("personId: " + person.getId() + - "; margUtlOfTimeWlk_h: " + this.localMarginalUtilityOfTravelTimeWalk_utl_s*3600. + - "; utlOfLineSwitch: " + this.localUtilityOfLineSwitch_utl + - "; margUtlOfWait_h: " + this.localMarginalUtilityOfWaitingPt_utl_s*3600. + - "; margUtlOfTimePt_h: " + this.localMarginalUtilityOfTravelTimePt_utl_s*3600. ) ; - } - } - } - -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/timeprofile/ProfileWriter.java b/contribs/common/src/main/java/org/matsim/contrib/common/timeprofile/ProfileWriter.java index 5f5a9194b7b..e98f9cbb2b4 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/timeprofile/ProfileWriter.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/timeprofile/ProfileWriter.java @@ -87,7 +87,8 @@ public void notifyIterationEnds(IterationEndsEvent event) { } } - if (this.matsimServices.getConfig().controler().isCreateGraphs()) { + int createGraphsInterval = this.matsimServices.getConfig().controller().getCreateGraphsInterval(); + if (createGraphsInterval > 0 && event.getIteration() % createGraphsInterval == 0) { DefaultTableXYDataset xyDataset = createXYDataset(times, profiles); generateImage(xyDataset, TimeProfileCharts.ChartType.Line); generateImage(xyDataset, TimeProfileCharts.ChartType.StackedArea); @@ -103,7 +104,7 @@ private DefaultTableXYDataset createXYDataset(double[] times, Map { XYSeries series = new XYSeries(name, true, false); for (int i = 0; i < times.length; i++) { - series.add((double)times[i] / 3600, profile[i]); + series.add((double) times[i] / 3600, profile[i]); } seriesList.add(series); }); @@ -115,7 +116,7 @@ private DefaultTableXYDataset createXYDataset(double[] times, Map0 && matsimServices.getIterationNumber() % createGraphsInterval == 0; + + if(createGraphs){ + for (ChartType t : chartTypes) { + generateImage(header, t); + } } } diff --git a/contribs/common/src/test/java/org/matsim/contrib/common/collections/PartialSortTest.java b/contribs/common/src/test/java/org/matsim/contrib/common/collections/PartialSortTest.java index 84371963d61..2609969dd8c 100644 --- a/contribs/common/src/test/java/org/matsim/contrib/common/collections/PartialSortTest.java +++ b/contribs/common/src/test/java/org/matsim/contrib/common/collections/PartialSortTest.java @@ -24,9 +24,9 @@ import static org.matsim.contrib.common.collections.PartialSort.kSmallestElements; import java.util.Comparator; -import java.util.stream.Stream; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import java.util.stream.Stream; /** * @author Michal Maciejewski (michalm) @@ -35,36 +35,36 @@ public class PartialSortTest { private final Comparator comparator = Integer::compareTo; @Test - public void k0_noneSelected() { + void k0_noneSelected() { assertThat(kSmallestElements(0, Stream.of(), comparator)).isEmpty(); assertThat(kSmallestElements(0, Stream.of(7, 1, 4, 9, 8), comparator)).isEmpty(); } @Test - public void reversedComparator_largestElementsSelected() { + void reversedComparator_largestElementsSelected() { assertThat(kSmallestElements(1, Stream.of(7, 1, 4, 9, 8), comparator.reversed())).containsExactly(9); assertThat(kSmallestElements(3, Stream.of(7, 1, 4, 9, 8), comparator.reversed())).containsExactly(9, 8, 7); } @Test - public void allElementsPairwiseNonEqual_inputOrderNotImportant() { + void allElementsPairwiseNonEqual_inputOrderNotImportant() { assertThat(kSmallestElements(3, Stream.of(1, 7, 9, 8), comparator)).containsExactly(1, 7, 8); assertThat(kSmallestElements(3, Stream.of(9, 8, 7, 1), comparator)).containsExactly(1, 7, 8); } @Test - public void exactlyKElementsProvided() { + void exactlyKElementsProvided() { assertThat(kSmallestElements(3, Stream.of(7, 1, 4), comparator)).containsExactly(1, 4, 7); } @Test - public void moreThenKElementsProvided() { + void moreThenKElementsProvided() { assertThat(kSmallestElements(3, Stream.of(7, 1, 4, 9, 8), comparator)).containsExactly(1, 4, 7); assertThat(kSmallestElements(3, Stream.of(13, 7, 1, 55, 4, 9, 8, 11), comparator)).containsExactly(1, 4, 7); } @Test - public void lessThenKElementsProvided() { + void lessThenKElementsProvided() { assertThat(kSmallestElements(3, Stream.of(7, 1), comparator)).containsExactly(1, 7); assertThat(kSmallestElements(3, Stream.of(13), comparator)).containsExactly(13); assertThat(kSmallestElements(3, Stream.of(), comparator)).isEmpty(); diff --git a/contribs/common/src/test/java/org/matsim/contrib/common/diversitygeneration/planselectors/DiversityGeneratingPlansRemoverTest.java b/contribs/common/src/test/java/org/matsim/contrib/common/diversitygeneration/planselectors/DiversityGeneratingPlansRemoverTest.java index a0025ce5638..04a8efe7547 100644 --- a/contribs/common/src/test/java/org/matsim/contrib/common/diversitygeneration/planselectors/DiversityGeneratingPlansRemoverTest.java +++ b/contribs/common/src/test/java/org/matsim/contrib/common/diversitygeneration/planselectors/DiversityGeneratingPlansRemoverTest.java @@ -4,8 +4,7 @@ import gnu.trove.map.TMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -37,7 +36,7 @@ public class DiversityGeneratingPlansRemoverTest { private static final Logger log = LogManager.getLogger( DiversityGeneratingPlansRemoverTest.class ) ; - + private final Id node0 = Id.createNodeId( "node0" ) ; private final Id node1 = Id.createNodeId( "node1" ) ; private final Id node2 = Id.createNodeId( "node2" ) ; @@ -45,12 +44,12 @@ public class DiversityGeneratingPlansRemoverTest { private final Id link0_1 = Id.createLinkId( "dummy0-1" ); private final Id link1_2 = Id.createLinkId( "dummy1-2" ); private final Id link2_3 = Id.createLinkId( "dummyN" ); - + @Test - public void calcWeights() { + void calcWeights() { // yy This is not really a strong test. Rather something I wrote for debugging. Would be a good // starting point for a fuller test. kai, jul'18 - + Scenario scenario = ScenarioUtils.createScenario( ConfigUtils.createConfig() ) ; { Network net = scenario.getNetwork(); @@ -130,11 +129,11 @@ public void calcWeights() { plans.put("hwh_car_otherMode",plan) ; } pop.addPerson( person ); - + DiversityGeneratingPlansRemover.Builder builder = new DiversityGeneratingPlansRemover.Builder() ; builder.setNetwork( scenario.getNetwork() ) ; final DiversityGeneratingPlansRemover remover = builder.get(); - + for ( Map.Entry entry : plans.entrySet() ) { log.info( "similarity " + entry.getKey() + " to self is " + remover.similarity( entry.getValue(), entry.getValue() ) ); log.info("") ; @@ -145,7 +144,7 @@ public void calcWeights() { } log.info("") ; } - + // { // final double similarity = remover.similarity( person.getPlans().get( 0 ), person.getPlans().get( 1 ) ); // log.info( "similarity 0 to 1: " + similarity ); @@ -161,7 +160,7 @@ public void calcWeights() { // log.info( "similarity 0 to 2: " + similarity ); // Assert.assertEquals( 12.0, similarity, 10.*Double.MIN_VALUE ); // } - + final Map retVal = remover.calcWeights( person.getPlans() ); log.info("") ; for ( Map.Entry entry : retVal.entrySet() ) { @@ -173,13 +172,13 @@ public void calcWeights() { } double[] expecteds = new double[]{1.0,0.0} ; - + // Assert.assertArrayEquals( expecteds, Doubles.toArray( retVal.values() ) , 10.*Double.MIN_VALUE ); } - - + + } - + private Plan createHwhPlan( final PopulationFactory pf ) { Plan plan = pf.createPlan() ; { @@ -221,8 +220,8 @@ private Plan createHwhPlan( final PopulationFactory pf ) { plan.setScore(90.) ; return plan; } - + @Test - public void selectPlan() { + void selectPlan() { } } diff --git a/contribs/common/src/test/java/org/matsim/contrib/common/randomizingtransitrouter/RandomizingTransitRouterIT.java b/contribs/common/src/test/java/org/matsim/contrib/common/randomizingtransitrouter/RandomizingTransitRouterIT.java deleted file mode 100644 index e703c6c4af6..00000000000 --- a/contribs/common/src/test/java/org/matsim/contrib/common/randomizingtransitrouter/RandomizingTransitRouterIT.java +++ /dev/null @@ -1,163 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* * - * * - * *********************************************************************** * - * * - * copyright : (C) 2008 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.contrib.common.randomizingtransitrouter; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.events.PersonEntersVehicleEvent; -import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler; -import org.matsim.contrib.common.randomizedtransitrouter.RandomizingTransitRouterModule; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.FacilitiesConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.QSimConfigGroup.TrafficDynamics; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; -import org.matsim.core.config.groups.VspExperimentalConfigGroup.VspDefaultsCheckingLevel; -import org.matsim.core.controler.Controler; -import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule.DefaultSelector; -import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule.DefaultStrategy; -import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.pt.config.TransitConfigGroup.TransitRoutingAlgorithmType; -import org.matsim.testcases.MatsimTestUtils; -import org.matsim.vehicles.Vehicle; - - -/** - * @author nagel - * - */ -public class RandomizingTransitRouterIT { - private static final Logger log = LogManager.getLogger( RandomizingTransitRouterIT.class ) ; - - private static final class MyObserver implements PersonEntersVehicleEventHandler { -// private enum ObservedVehicle{ pt_1009_1 /*direct, fast, with wait*/, pt_2009_1 /*direct, slow*/, pt_3009_1 /*with interchange*/} ; - - Map,Double> cnts = new HashMap<>() ; - - @Override public void reset(int iteration) { - cnts.clear(); - } - - @Override public void handleEvent(PersonEntersVehicleEvent event) { - cnts.merge( event.getVehicleId() , 1. , Double::sum ); - } - - void printCounts() { - for ( Entry, Double> entry : cnts.entrySet() ) { - log.info( "Vehicle id: " + entry.getKey() + "; number of boards: " + entry.getValue() ) ; - } - } - - Map< Id, Double> getCounts() { - return this.cnts ; - } - } - - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; - - @Test -// @Ignore - public final void test() { - String outputDir = utils.getOutputDirectory() ; - - Config config = utils.createConfigWithPackageInputResourcePathAsContext(); - - config.network().setInputFile("network.xml"); - config.plans().setInputFile("population.xml"); - - config.transit().setRoutingAlgorithmType(TransitRoutingAlgorithmType.DijkstraBased); - config.transit().setTransitScheduleFile("transitschedule.xml"); - config.transit().setVehiclesFile("transitVehicles.xml"); - config.transit().setUseTransit(true); - - config.controler().setOutputDirectory( outputDir ); - config.controler().setLastIteration(20); - config.controler().setCreateGraphs(false); - config.controler().setDumpDataAtEnd(false); - - config.global().setNumberOfThreads(1); - - config.planCalcScore().addActivityParams( new ActivityParams("home").setTypicalDuration( 6*3600. ) ); - config.planCalcScore().addActivityParams( new ActivityParams("education_100").setTypicalDuration( 6*3600. ) ); - -// config.strategy().addStrategySettings( new StrategySettings( ConfigUtils.createAvailableStrategyId(config)).setStrategyName(DefaultStrategy.ReRoute ).setWeight(0.1 ) ); -// config.strategy().addStrategySettings( new StrategySettings( ConfigUtils.createAvailableStrategyId(config)).setStrategyName(DefaultSelector.ChangeExpBeta ).setWeight(0.9 ) ); - config.strategy().addStrategySettings( new StrategySettings().setStrategyName(DefaultStrategy.ReRoute ).setWeight(0.1 ) ); - config.strategy().addStrategySettings( new StrategySettings().setStrategyName(DefaultSelector.ChangeExpBeta ).setWeight(0.9 ) ); - // yy changing the above (= no longer using createAvailableStrategyId) changes the results. :-( :-( :-( - - config.qsim().setEndTime(18.*3600.); - - config.timeAllocationMutator().setMutationRange(7200); - config.timeAllocationMutator().setAffectingDuration(false); - config.plans().setRemovingUnneccessaryPlanAttributes(true); - config.qsim().setTrafficDynamics( TrafficDynamics.withHoles ); - config.qsim().setUsingFastCapacityUpdate(true); - -// config.facilities().setFacilitiesSource( FacilitiesConfigGroup.FacilitiesSource.none ); - // yyyy changing this setting changes result. Possible reasons: - // * The implicit activity coordinates may be elsewhere. - // * The "fudged" walk distances may be different. - // * It uses getNearestLinkEXACTLY, and thus activities may be attached to other links. - - config.vspExperimental().setWritingOutputEvents(true); - config.vspExperimental().setVspDefaultsCheckingLevel( VspDefaultsCheckingLevel.warn ); - - // --- - - Scenario scenario = ScenarioUtils.loadScenario( config ) ; - - // --- - - Controler controler = new Controler( scenario ) ; - - controler.addOverridingModule( new RandomizingTransitRouterModule() ); - - final MyObserver observer = new MyObserver(); - controler.getEvents().addHandler(observer); - - controler.run(); - - // --- - - observer.printCounts(); - - // yyyy the following is just a regression test, making sure that results remain stable. In general, the randomized transit router - // could be improved, for example along the lines of the randomized regular router, which uses a (hopefully unbiased) lognormal - // distribution rather than a biased uniform distribution as is used here. kai, jul'15 - - Assert.assertEquals(36., observer.getCounts().get( Id.create("1009", Vehicle.class) ), 0.1 ); - Assert.assertEquals( 8. /*6.*/ , observer.getCounts().get( Id.create("1012", Vehicle.class) ) , 0.1 ); - Assert.assertEquals(22. /*21.*/, observer.getCounts().get( Id.create("2009", Vehicle.class) ) , 0.1 ); - Assert.assertEquals(36., observer.getCounts().get( Id.create("3009", Vehicle.class) ) , 0.1 ); - - - } - -} diff --git a/contribs/common/src/test/java/org/matsim/contrib/common/util/WeightedRandomSelectionTest.java b/contribs/common/src/test/java/org/matsim/contrib/common/util/WeightedRandomSelectionTest.java index f96b4468202..2c33545ebe5 100644 --- a/contribs/common/src/test/java/org/matsim/contrib/common/util/WeightedRandomSelectionTest.java +++ b/contribs/common/src/test/java/org/matsim/contrib/common/util/WeightedRandomSelectionTest.java @@ -26,8 +26,8 @@ import java.util.Random; import org.apache.commons.lang3.mutable.MutableDouble; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * @author michalm @@ -37,7 +37,7 @@ public class WeightedRandomSelectionTest { private final MutableDouble randomDouble = new MutableDouble(); private WeightedRandomSelection weightedRandomSelection; - @Before + @BeforeEach public void init() { weightedRandomSelection = new WeightedRandomSelection<>(new Random() { @Override @@ -48,7 +48,7 @@ public double nextDouble(double from, double to) { } @Test - public void testIncorrectInput() { + void testIncorrectInput() { assertIncorrectWeight(-Double.MIN_VALUE); assertIncorrectWeight(-1); assertIncorrectWeight(-Double.MAX_VALUE); @@ -71,7 +71,7 @@ private void assertIncorrectWeight(double weight) { } @Test - public void testEmptyList() { + void testEmptyList() { assertThat(weightedRandomSelection.size()).isEqualTo(0); assertThatThrownBy(() -> weightedRandomSelection.select())// .isExactlyInstanceOf(IllegalStateException.class)// @@ -79,7 +79,7 @@ public void testEmptyList() { } @Test - public void testZeroTotalWeight() { + void testZeroTotalWeight() { weightedRandomSelection.add("A", 0.); weightedRandomSelection.add("B", 0.); assertThatThrownBy(() -> weightedRandomSelection.select())// @@ -88,7 +88,7 @@ public void testZeroTotalWeight() { } @Test - public void testSingleValueList() { + void testSingleValueList() { weightedRandomSelection.add("A", 1); assertThat(weightedRandomSelection.size()).isEqualTo(1); @@ -100,7 +100,7 @@ public void testSingleValueList() { } @Test - public void testThreeValuesList() { + void testThreeValuesList() { weightedRandomSelection.add("A", 1); weightedRandomSelection.add("B", 0.5); weightedRandomSelection.add("C", 1.5); diff --git a/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest66IT.java b/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest66IT.java index 7db3eb15ed1..e6a0711851a 100644 --- a/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest66IT.java +++ b/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest66IT.java @@ -20,20 +20,20 @@ package org.matsim.integration.always; -import static org.junit.Assert.assertEquals; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import jakarta.inject.Inject; + +import static org.junit.jupiter.api.Assertions.assertEquals; import jakarta.inject.Provider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -90,11 +90,11 @@ */ public class BetaTravelTest66IT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - /* This TestCase uses a custom Controler, named TestControler, to load + /*This TestCase uses a custom Controler, named TestControler, to load * specific strategies. The strategies make use of a test-specific * TimeAllocationMutator, the TimeAllocationMutatorBottleneck. * LinkAnalyzer, an event handler, collects some statistics on the @@ -130,10 +130,11 @@ public class BetaTravelTest66IT { * * @author mrieser */ - @Test public void testBetaTravel_66() { + @Test + void testBetaTravel_66() { Config config = utils.loadConfig("../../examples/scenarios/equil/config.xml"); ConfigUtils.loadConfig(config, utils.getInputDirectory() + "config.xml"); - config.controler().setWritePlansInterval(0); + config.controller().setWritePlansInterval(0); // --- Scenario scenario = ScenarioUtils.loadScenario(config); /* @@ -151,9 +152,9 @@ public void install() { } }); controler.addControlerListener(new TestControlerListener()); - controler.getConfig().controler().setCreateGraphs(false); - controler.getConfig().controler().setDumpDataAtEnd(false); - controler.getConfig().controler().setWriteEventsInterval(0); + controler.getConfig().controller().setCreateGraphs(false); + controler.getConfig().controller().setDumpDataAtEnd(false); + controler.getConfig().controller().setWriteEventsInterval(0); controler.run(); } @@ -275,7 +276,7 @@ public StrategyManager get() { StrategyManager manager = new StrategyManager(); manager.setMaxPlansPerAgent(5); - PlanStrategyImpl strategy1 = new PlanStrategyImpl(new ExpBetaPlanSelector<>(config.planCalcScore())); + PlanStrategyImpl strategy1 = new PlanStrategyImpl(new ExpBetaPlanSelector<>(config.scoring())); manager.addStrategy( strategy1, null, 0.80 ); PlanStrategyImpl strategy2 = new PlanStrategyImpl(new RandomPlanSelector<>()); @@ -317,12 +318,12 @@ private static class TestControlerListener implements StartupListener, Iteration @Override public void notifyStartup(final StartupEvent event) { // do some test to ensure the scenario is correct - double beta_travel = event.getServices().getConfig().planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); + double beta_travel = event.getServices().getConfig().scoring().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); if ((beta_travel != -6.0) && (beta_travel != -66.0)) { throw new IllegalArgumentException("Unexpected value for beta_travel. Expected -6.0 or -66.0, actual value is " + beta_travel); } - int lastIter = event.getServices().getConfig().controler().getLastIteration(); + int lastIter = event.getServices().getConfig().controller().getLastIteration(); if (lastIter < 100) { throw new IllegalArgumentException("Controler.lastIteration must be at least 100. Current value is " + lastIter); } @@ -360,7 +361,7 @@ public void notifyIterationEnds(final IterationEndsEvent event) { event.getServices().getEvents().removeHandler(this.ttAnalyzer); } if (iteration == 100) { - double beta_travel = event.getServices().getConfig().planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); + double beta_travel = event.getServices().getConfig().scoring().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); /* *************************************************************** * AUTOMATIC VERIFICATION OF THE TESTS: * diff --git a/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest6IT.java b/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest6IT.java index 6c9792fb458..49ec89733a1 100644 --- a/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest6IT.java +++ b/contribs/common/src/test/java/org/matsim/integration/always/BetaTravelTest6IT.java @@ -20,20 +20,20 @@ package org.matsim.integration.always; -import static org.junit.Assert.assertEquals; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import jakarta.inject.Inject; + +import static org.junit.jupiter.api.Assertions.assertEquals; import jakarta.inject.Provider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -91,11 +91,11 @@ */ public class BetaTravelTest6IT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - /* This TestCase uses a custom Controler, named TestControler, to load + /*This TestCase uses a custom Controler, named TestControler, to load * specific strategies. The strategies make use of a test-specific * TimeAllocationMutator, the TimeAllocationMutatorBottleneck. * LinkAnalyzer, an event handler, collects some statistics on the @@ -130,10 +130,11 @@ public class BetaTravelTest6IT { * * @author mrieser */ - @Test public void testBetaTravel_6() { + @Test + void testBetaTravel_6() { Config config = utils.loadConfig("../../examples/scenarios/equil/config.xml"); // default config ConfigUtils.loadConfig(config, utils.getInputDirectory() + "config.xml"); // specific setting for this test - config.controler().setWritePlansInterval(0); + config.controller().setWritePlansInterval(0); config.plans().setActivityDurationInterpretation( ActivityDurationInterpretation.tryEndTimeThenDuration ); /* * The input plans file is not sorted. After switching from TreeMap to LinkedHashMap @@ -150,9 +151,9 @@ public void install() { } }); controler.addControlerListener(new TestControlerListener()); - controler.getConfig().controler().setCreateGraphs(false); - controler.getConfig().controler().setDumpDataAtEnd(false); - controler.getConfig().controler().setWriteEventsInterval(0); + controler.getConfig().controller().setCreateGraphs(false); + controler.getConfig().controller().setDumpDataAtEnd(false); + controler.getConfig().controller().setWriteEventsInterval(0); controler.run(); } @@ -273,7 +274,7 @@ public StrategyManager get() { StrategyManager manager = new StrategyManager(); manager.setMaxPlansPerAgent(5); - PlanStrategyImpl strategy1 = new PlanStrategyImpl(new ExpBetaPlanSelector(config.planCalcScore())); + PlanStrategyImpl strategy1 = new PlanStrategyImpl(new ExpBetaPlanSelector(config.scoring())); manager.addStrategy( strategy1, null, 0.80 ); PlanStrategyImpl strategy2 = new PlanStrategyImpl(new RandomPlanSelector()); @@ -314,12 +315,12 @@ public TestControlerListener() { @Override public void notifyStartup(final StartupEvent event) { // do some test to ensure the scenario is correct - double beta_travel = event.getServices().getConfig().planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); + double beta_travel = event.getServices().getConfig().scoring().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); if ((beta_travel != -6.0) && (beta_travel != -66.0)) { throw new IllegalArgumentException("Unexpected value for beta_travel. Expected -6.0 or -66.0, actual value is " + beta_travel); } - int lastIter = event.getServices().getConfig().controler().getLastIteration(); + int lastIter = event.getServices().getConfig().controller().getLastIteration(); if (lastIter < 100) { throw new IllegalArgumentException("Controler.lastIteration must be at least 100. Current value is " + lastIter); } @@ -357,7 +358,7 @@ public void notifyIterationEnds(final IterationEndsEvent event) { event.getServices().getEvents().removeHandler(this.ttAnalyzer); } if (iteration == 100) { - double beta_travel = event.getServices().getConfig().planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); + double beta_travel = event.getServices().getConfig().scoring().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling(); /* *************************************************************** * AUTOMATIC VERIFICATION OF THE TESTS: * diff --git a/contribs/decongestion/pom.xml b/contribs/decongestion/pom.xml index f95fa91552d..42c6ad098c0 100644 --- a/contribs/decongestion/pom.xml +++ b/contribs/decongestion/pom.xml @@ -4,7 +4,15 @@ contrib 16.0-SNAPSHOT - 4.0.0 + + + org.matsim.contrib + otfvis + ${parent.version} + test + + + 4.0.0 org.matsim.contrib decongestion decongestion diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionControlerListener.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionControlerListener.java index 07b279f0be9..080d92d0c51 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionControlerListener.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionControlerListener.java @@ -40,7 +40,7 @@ import org.matsim.contrib.decongestion.handler.DelayAnalysis; import org.matsim.contrib.decongestion.handler.IntervalBasedTolling; import org.matsim.contrib.decongestion.tollSetting.DecongestionTollSetting; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.events.AfterMobsimEvent; import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.controler.events.IterationStartsEvent; @@ -103,7 +103,7 @@ public void notifyStartup(StartupEvent event) { log.info("decongestion settings: " + congestionInfo.getDecongestionConfigGroup().toString()); - this.outputDirectory = this.congestionInfo.getScenario().getConfig().controler().getOutputDirectory(); + this.outputDirectory = this.congestionInfo.getScenario().getConfig().controller().getOutputDirectory(); if (!outputDirectory.endsWith("/")) { log.info("Adjusting output directory."); outputDirectory = outputDirectory + "/"; @@ -117,13 +117,13 @@ public void notifyAfterMobsim(AfterMobsimEvent event) { computeDelays(event); } - if (event.getIteration() == this.congestionInfo.getScenario().getConfig().controler().getFirstIteration()) { + if (event.getIteration() == this.congestionInfo.getScenario().getConfig().controller().getFirstIteration()) { // skip first iteration } else if (event.getIteration() % this.congestionInfo.getDecongestionConfigGroup().getUpdatePriceInterval() == 0.) { - int totalNumberOfIterations = this.congestionInfo.getScenario().getConfig().controler().getLastIteration() - this.congestionInfo.getScenario().getConfig().controler().getFirstIteration(); - int iterationCounter = event.getIteration() - this.congestionInfo.getScenario().getConfig().controler().getFirstIteration(); + int totalNumberOfIterations = this.congestionInfo.getScenario().getConfig().controller().getLastIteration() - this.congestionInfo.getScenario().getConfig().controller().getFirstIteration(); + int iterationCounter = event.getIteration() - this.congestionInfo.getScenario().getConfig().controller().getFirstIteration(); if (iterationCounter < this.congestionInfo.getDecongestionConfigGroup().getFractionOfIterationsToEndPriceAdjustment() * totalNumberOfIterations && iterationCounter > this.congestionInfo.getDecongestionConfigGroup().getFractionOfIterationsToStartPriceAdjustment() * totalNumberOfIterations) { @@ -136,8 +136,8 @@ public void notifyAfterMobsim(AfterMobsimEvent event) { } if (event.getIteration() % this.congestionInfo.getDecongestionConfigGroup().getWriteOutputIteration() == 0.) { - CongestionInfoWriter.writeDelays(congestionInfo, event.getIteration(), this.outputDirectory + "ITERS/it." + event.getIteration() + "/", this.congestionInfo.getScenario().getConfig().controler().getRunId()); - CongestionInfoWriter.writeTolls(congestionInfo, event.getIteration(), this.outputDirectory + "ITERS/it." + event.getIteration() + "/", this.congestionInfo.getScenario().getConfig().controler().getRunId()); + CongestionInfoWriter.writeDelays(congestionInfo, event.getIteration(), this.outputDirectory + "ITERS/it." + event.getIteration() + "/", this.congestionInfo.getScenario().getConfig().controller().getRunId()); + CongestionInfoWriter.writeTolls(congestionInfo, event.getIteration(), this.outputDirectory + "ITERS/it." + event.getIteration() + "/", this.congestionInfo.getScenario().getConfig().controller().getRunId()); } } @@ -197,7 +197,7 @@ public void notifyIterationEnds(IterationEndsEvent event) { if ( person.getSelectedPlan().getScore()==null ) { throw new RuntimeException( "score is null; don't know how to continue.") ; } - monetizedUserBenefits += person.getSelectedPlan().getScore() / this.congestionInfo.getScenario().getConfig().planCalcScore().getMarginalUtilityOfMoney(); + monetizedUserBenefits += person.getSelectedPlan().getScore() / this.congestionInfo.getScenario().getConfig().scoring().getMarginalUtilityOfMoney(); } this.iteration2userBenefits.put(event.getIteration(), monetizedUserBenefits); @@ -207,35 +207,35 @@ public void notifyIterationEnds(IterationEndsEvent event) { this.iteration2totalTravelTime, this.iteration2userBenefits, outputDirectory, - this.congestionInfo.getScenario().getConfig().controler().getRunId() + this.congestionInfo.getScenario().getConfig().controller().getRunId() ); XYLineChart chart1 = new XYLineChart("Total travel time and total delay", "Iteration", "Hours"); double[] iterations1 = new double[event.getIteration() + 1]; double[] values1a = new double[event.getIteration() + 1]; double[] values1b = new double[event.getIteration() + 1]; - for (int i = this.congestionInfo.getScenario().getConfig().controler().getFirstIteration(); i <= event.getIteration(); i++) { + for (int i = this.congestionInfo.getScenario().getConfig().controller().getFirstIteration(); i <= event.getIteration(); i++) { iterations1[i] = i; values1a[i] = this.iteration2totalDelay.get(i) / 3600.; values1b[i] = this.iteration2totalTravelTime.get(i) / 3600.; } chart1.addSeries("Total delay", iterations1, values1a); chart1.addSeries("Total travel time", iterations1, values1b); - chart1.saveAsPng(outputDirectory + this.congestionInfo.getScenario().getConfig().controler().getRunId() + ".decongestion_travelTime_delay.png", 800, 600); + chart1.saveAsPng(outputDirectory + this.congestionInfo.getScenario().getConfig().controller().getRunId() + ".decongestion_travelTime_delay.png", 800, 600); XYLineChart chart2 = new XYLineChart("user benefits and toll revenues", "Iteration", "Monetary units"); double[] iterations2 = new double[event.getIteration() + 1]; double[] values2b = new double[event.getIteration() + 1]; double[] values2c = new double[event.getIteration() + 1]; - for (int i = this.congestionInfo.getScenario().getConfig().controler().getFirstIteration(); i <= event.getIteration(); i++) { + for (int i = this.congestionInfo.getScenario().getConfig().controller().getFirstIteration(); i <= event.getIteration(); i++) { iterations2[i] = i; values2b[i] = this.iteration2userBenefits.get(i); values2c[i] = this.iteration2totalTollPayments.get(i); } chart2.addSeries("User benefits", iterations2, values2b); chart2.addSeries("Toll payments (decongestion tolls only)", iterations2, values2c); - chart2.saveAsPng(outputDirectory + this.congestionInfo.getScenario().getConfig().controler().getRunId() + ".decongestion_userBenefits_tolls.png", 800, 600); + chart2.saveAsPng(outputDirectory + this.congestionInfo.getScenario().getConfig().controller().getRunId() + ".decongestion_userBenefits_tolls.png", 800, 600); } } @@ -243,9 +243,9 @@ public void notifyIterationEnds(IterationEndsEvent event) { public void notifyIterationStarts(IterationStartsEvent event) { if (congestionInfo.getDecongestionConfigGroup().getUpdatePriceInterval() > 1) { - if (event.getIteration() == this.congestionInfo.getScenario().getConfig().controler().getFirstIteration()) { + if (event.getIteration() == this.congestionInfo.getScenario().getConfig().controller().getFirstIteration()) { - this.nextDisableInnovativeStrategiesIteration = (int) (congestionInfo.getScenario().getConfig().strategy().getFractionOfIterationsToDisableInnovation() * congestionInfo.getDecongestionConfigGroup().getUpdatePriceInterval()); + this.nextDisableInnovativeStrategiesIteration = (int) (congestionInfo.getScenario().getConfig().replanning().getFractionOfIterationsToDisableInnovation() * congestionInfo.getDecongestionConfigGroup().getUpdatePriceInterval()); log.info("next disable innovative strategies iteration: " + this.nextDisableInnovativeStrategiesIteration); if (this.nextDisableInnovativeStrategiesIteration != 0) { @@ -274,7 +274,7 @@ public void notifyIterationStarts(IterationStartsEvent event) { } else if (event.getIteration() == this.nextEnableInnovativeStrategiesIteration) { // set weight back to original value - if (event.getIteration() >= congestionInfo.getScenario().getConfig().strategy().getFractionOfIterationsToDisableInnovation() * (congestionInfo.getScenario().getConfig().controler().getLastIteration() - congestionInfo.getScenario().getConfig().controler().getFirstIteration())) { + if (event.getIteration() >= congestionInfo.getScenario().getConfig().replanning().getFractionOfIterationsToDisableInnovation() * (congestionInfo.getScenario().getConfig().controller().getLastIteration() - congestionInfo.getScenario().getConfig().controller().getFirstIteration())) { log.info("Strategies are switched off by global settings. Do not set back the strategy parameters to original values..."); @@ -288,7 +288,7 @@ public void notifyIterationStarts(IterationStartsEvent event) { if (isInnovativeStrategy(strategy)) { double originalValue = -1.0; - for (StrategySettings setting : event.getServices().getConfig().strategy().getStrategySettings()) { + for (StrategySettings setting : event.getServices().getConfig().replanning().getStrategySettings()) { log.info("setting: " + setting.getStrategyName()); log.info("strategyName: " + strategyName); diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionModule.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionModule.java index a6afea61fd6..b8129dd901c 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionModule.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionModule.java @@ -19,12 +19,15 @@ package org.matsim.contrib.decongestion; -import org.matsim.api.core.v01.Scenario; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.decongestion.data.DecongestionInfo; import org.matsim.contrib.decongestion.handler.DelayAnalysis; import org.matsim.contrib.decongestion.handler.IntervalBasedTolling; import org.matsim.contrib.decongestion.handler.IntervalBasedTollingAll; import org.matsim.contrib.decongestion.handler.PersonVehicleTracker; +import org.matsim.contrib.decongestion.routing.TollTimeDistanceTravelDisutilityFactory; import org.matsim.contrib.decongestion.tollSetting.DecongestionTollSetting; import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingBangBang; import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingPID; @@ -37,51 +40,46 @@ public class DecongestionModule extends AbstractModule { - private final DecongestionConfigGroup decongestionConfigGroup; - - public DecongestionModule(Scenario scenario) { - this.decongestionConfigGroup = (DecongestionConfigGroup) scenario.getConfig().getModules().get(DecongestionConfigGroup.GROUP_NAME); - } + @Inject private DecongestionConfigGroup decongestionConfigGroup; @Override public void install() { if (decongestionConfigGroup.isEnableDecongestionPricing()) { - switch( decongestionConfigGroup.getDecongestionApproach() ) { - case BangBang: - this.bind(DecongestionTollingBangBang.class).asEagerSingleton(); - this.bind(DecongestionTollSetting.class).to(DecongestionTollingBangBang.class); - break; - case PID: - this.bind(DecongestionTollingPID.class).asEagerSingleton(); - this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); - this.addEventHandlerBinding().to(DecongestionTollingPID.class); - break; - case P_MC: - this.bind(DecongestionTollingP_MCP.class).asEagerSingleton(); - this.bind(DecongestionTollSetting.class).to(DecongestionTollingP_MCP.class); - this.addEventHandlerBinding().to(DecongestionTollingP_MCP.class); - break; - default: - throw new RuntimeException("not implemented") ; + switch( decongestionConfigGroup.getDecongestionApproach() ){ + case BangBang -> { + this.bind( DecongestionTollingBangBang.class ).in( Singleton.class ); + this.bind( DecongestionTollSetting.class ).to( DecongestionTollingBangBang.class ); + } + case PID -> { + this.bind( DecongestionTollingPID.class ).in( Singleton.class ); + this.bind( DecongestionTollSetting.class ).to( DecongestionTollingPID.class ); + this.addEventHandlerBinding().to( DecongestionTollingPID.class ); + } + case P_MC -> { + this.bind( DecongestionTollingP_MCP.class ).in( Singleton.class ); + this.bind( DecongestionTollSetting.class ).to( DecongestionTollingP_MCP.class ); + this.addEventHandlerBinding().to( DecongestionTollingP_MCP.class ); + } + default -> throw new RuntimeException( "not implemented" ); } } else { // no pricing } - this.bind(DecongestionInfo.class).asEagerSingleton(); + addTravelDisutilityFactoryBinding( TransportMode.car ).to( TollTimeDistanceTravelDisutilityFactory.class ); + + this.bind(DecongestionInfo.class).in( Singleton.class ); - this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); - this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); - this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); + this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class).in( Singleton.class ); + this.addEventHandlerBinding().to(IntervalBasedTolling.class); - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.addEventHandlerBinding().to(DelayAnalysis.class); + this.addEventHandlerBinding().to(DelayAnalysis.class).in( Singleton.class ); - this.addEventHandlerBinding().to(PersonVehicleTracker.class).asEagerSingleton(); + this.addEventHandlerBinding().to(PersonVehicleTracker.class).in( Singleton.class ); - this.addControlerListenerBinding().to(DecongestionControlerListener.class); + this.addControlerListenerBinding().to(DecongestionControlerListener.class).in( Singleton.class ); } } diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/routing/TollTimeDistanceTravelDisutility.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/routing/TollTimeDistanceTravelDisutility.java index 5635fdbae0a..1ad6ad0f479 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/routing/TollTimeDistanceTravelDisutility.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/routing/TollTimeDistanceTravelDisutility.java @@ -35,11 +35,11 @@ import org.matsim.contrib.decongestion.data.LinkInfo; /** - * A cost calculator which respects time, distance and decongestion tolls. + * A cost calculator which respects time, distance and decongestion tolls. * * @author ikaddoura */ -public final class TollTimeDistanceTravelDisutility implements TravelDisutility { +final class TollTimeDistanceTravelDisutility implements TravelDisutility { private static final Logger log = LogManager.getLogger(TollTimeDistanceTravelDisutility.class); private final TravelDisutility delegate; @@ -50,15 +50,15 @@ public final class TollTimeDistanceTravelDisutility implements TravelDisutility TollTimeDistanceTravelDisutility( final TravelTime timeCalculator, Config config, DecongestionInfo info ) { this.info = info; - this.marginalUtilityOfMoney = config.planCalcScore().getMarginalUtilityOfMoney(); + this.marginalUtilityOfMoney = config.scoring().getMarginalUtilityOfMoney(); final RandomizingTimeDistanceTravelDisutilityFactory builder = new RandomizingTimeDistanceTravelDisutilityFactory( TransportMode.car, config ); this.delegate = builder.createTravelDisutility(timeCalculator); this.timeBinSize = info.getScenario().getConfig().travelTimeCalculator().getTraveltimeBinSize(); - this.sigma = config.plansCalcRoute().getRoutingRandomness(); - + this.sigma = config.routing().getRoutingRandomness(); + log.info("Using the toll-adjusted travel disutility (improved version) in the decongestion package."); } @@ -67,7 +67,7 @@ public double getLinkTravelDisutility(final Link link, final double time, final int timeBin = (int) (time / timeBinSize); double timeDistanceTravelDisutilityFromDelegate = this.delegate.getLinkTravelDisutility(link, time, person, vehicle); - + double logNormalRnd = 1. ; if ( sigma != 0. ) { logNormalRnd = (double) person.getCustomAttributes().get("logNormalRnd") ; @@ -75,17 +75,17 @@ public double getLinkTravelDisutility(final Link link, final double time, final // adjust the travel disutility for the toll double toll = 0.; - + LinkInfo linkInfo = info.getlinkInfos().get(link.getId()); if (linkInfo != null) { - - Double linkInfoTimeBinToll = linkInfo.getTime2toll().get(timeBin); + + Double linkInfoTimeBinToll = linkInfo.getTime2toll().get(timeBin); if (linkInfoTimeBinToll != null) { toll = linkInfoTimeBinToll; } } - - double tollAdjustedLinkTravelDisutility = timeDistanceTravelDisutilityFromDelegate + logNormalRnd * marginalUtilityOfMoney * toll; + + double tollAdjustedLinkTravelDisutility = timeDistanceTravelDisutilityFromDelegate + logNormalRnd * marginalUtilityOfMoney * toll; return tollAdjustedLinkTravelDisutility; } diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExample.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExample.java similarity index 81% rename from contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExample.java rename to contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExample.java index a7ae5e473de..28ea4b3cfa5 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExample.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExample.java @@ -19,9 +19,9 @@ * *********************************************************************** */ /** - * + * */ -package org.matsim.contrib.decongestion; +package org.matsim.contrib.decongestion.run; import java.io.IOException; @@ -29,19 +29,21 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.contrib.decongestion.DecongestionConfigGroup; import org.matsim.contrib.decongestion.DecongestionConfigGroup.DecongestionApproach; import org.matsim.contrib.decongestion.DecongestionConfigGroup.IntegralApproach; +import org.matsim.contrib.decongestion.DecongestionModule; import org.matsim.contrib.decongestion.routing.TollTimeDistanceTravelDisutilityFactory; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; -import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.scenario.ScenarioUtils; /** * Starts an interval-based decongestion pricing simulation run. - * + * * @author ikaddoura * */ @@ -50,36 +52,39 @@ public class DecongestionRunExample { private static final Logger log = LogManager.getLogger(DecongestionRunExample.class); private static String configFile; - + public static void main(String[] args) throws IOException { - + if (args.length > 0) { log.info("Starting simulation run with the following arguments:"); - configFile = args[0]; + configFile = args[0]; log.info("config file: "+ configFile); } else { configFile = "path/to/config.xml"; } - + DecongestionRunExample main = new DecongestionRunExample(); main.run(); - + } private void run() { - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + Config config = ConfigUtils.loadConfig(configFile); + + final DecongestionConfigGroup decongestionSettings = ConfigUtils.addOrGetModule( config, DecongestionConfigGroup.class ); + decongestionSettings.setToleratedAverageDelaySec(30.); decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); decongestionSettings.setUpdatePriceInterval(1); decongestionSettings.setMsa(false); decongestionSettings.setTollBlendFactor(1.0); - + // decongestionSettings.setDecongestionApproach(DecongestionApproach.P_MC); - + decongestionSettings.setDecongestionApproach(DecongestionApproach.PID); decongestionSettings.setKd(0.005); decongestionSettings.setKi(0.005); @@ -87,38 +92,35 @@ private void run() { decongestionSettings.setIntegralApproach(IntegralApproach.UnusedHeadway); decongestionSettings.setIntegralApproachUnusedHeadwayFactor(10.0); decongestionSettings.setIntegralApproachAverageAlpha(0.0); - + // decongestionSettings.setDecongestionApproach(DecongestionApproach.BangBang); // decongestionSettings.setTOLL_ADJUSTMENT(1.0); // decongestionSettings.setINITIAL_TOLL(1.0); - - Config config = ConfigUtils.loadConfig(configFile); - config.addModule(decongestionSettings); - + + + // --- + final Scenario scenario = ScenarioUtils.loadScenario(config); + + // --- + Controler controler = new Controler(scenario); - - // ############################################################# - + // congestion toll computation - - controler.addOverridingModule(new DecongestionModule(scenario)); - + controler.addOverridingModule(new DecongestionModule() ); + // toll-adjusted routing - controler.addOverridingModule(new AbstractModule(){ @Override public void install() { - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( new TollTimeDistanceTravelDisutilityFactory() ); + // yyyy try if this could add the class instead of the instance. possibly as singleton. kai, jan'24 + } - }); - - // ############################################################# - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.failIfDirectoryExists); - controler.run(); - + }); + + controler.run(); + } } diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExampleFromConfig.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExampleFromConfig.java similarity index 74% rename from contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExampleFromConfig.java rename to contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExampleFromConfig.java index 3dd8a48c2a1..7bfe040d503 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/DecongestionRunExampleFromConfig.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/run/DecongestionRunExampleFromConfig.java @@ -19,9 +19,9 @@ * *********************************************************************** */ /** - * + * */ -package org.matsim.contrib.decongestion; +package org.matsim.contrib.decongestion.run; import java.io.IOException; @@ -29,17 +29,19 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.contrib.decongestion.DecongestionConfigGroup; +import org.matsim.contrib.decongestion.DecongestionModule; import org.matsim.contrib.decongestion.routing.TollTimeDistanceTravelDisutilityFactory; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; -import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.scenario.ScenarioUtils; /** * Starts an interval-based decongestion pricing simulation run. - * + * * @author ikaddoura * */ @@ -48,50 +50,43 @@ public class DecongestionRunExampleFromConfig { private static final Logger log = LogManager.getLogger(DecongestionRunExampleFromConfig.class); private static String configFile; - - public static void main(String[] args) throws IOException { + + public static void main(String[] args) throws IOException { if (args.length > 0) { log.info("Starting simulation run with the following arguments:"); - configFile = args[0]; + configFile = args[0]; log.info("config file: "+ configFile); } else { configFile = "path/to/config.xml"; } - + DecongestionRunExampleFromConfig main = new DecongestionRunExampleFromConfig(); main.run(); } - private void run() throws IOException { - - Config config = ConfigUtils.loadConfig(configFile, new DecongestionConfigGroup()); - + private void run() { + + Config config = ConfigUtils.loadConfig(configFile, new DecongestionConfigGroup() ); + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); - - // ############################################################# - + // congestion toll computation - - controler.addOverridingModule(new DecongestionModule(scenario)); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); + controler.addOverridingModule(new DecongestionModule() ); - controler.addOverridingModule(new AbstractModule(){ + // toll-adjusted routing + controler.addOverridingModule(new AbstractModule(){ @Override public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( new TollTimeDistanceTravelDisutilityFactory() ); + // yyyy try if this could add the class instead of the instance. possibly as singleton. kai, jan'24 } - }); - - // ############################################################# - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.failIfDirectoryExists); - controler.run(); + }); + + controler.run(); } } diff --git a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/tollSetting/DecongestionTollingP_MCP.java b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/tollSetting/DecongestionTollingP_MCP.java index 146bf63f012..00450067e9c 100644 --- a/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/tollSetting/DecongestionTollingP_MCP.java +++ b/contribs/decongestion/src/main/java/org/matsim/contrib/decongestion/tollSetting/DecongestionTollingP_MCP.java @@ -36,64 +36,64 @@ import org.matsim.contrib.decongestion.data.LinkInfo; /** - * + * * P-based toll adjustment, where e(t) = average delay and K_p = VTTS * number of delayed agents - * + * * @author ikaddoura */ public class DecongestionTollingP_MCP implements DecongestionTollSetting, LinkLeaveEventHandler { private static final Logger log = LogManager.getLogger(DecongestionTollingP_MCP.class); - + @Inject private DecongestionInfo congestionInfo; - - private Map, LinkInfo> linkId2infoPreviousTollComputation = new HashMap<>(); + + private Map, LinkInfo> linkId2infoPreviousTollComputation = new HashMap<>(); private int tollUpdateCounter = 0; private final Map, Map> linkId2time2leavingAgents = new HashMap<>(); @Override public void updateTolls() { - - final double vtts = ( this.congestionInfo.getScenario().getConfig().planCalcScore().getPerforming_utils_hr() - - this.congestionInfo.getScenario().getConfig().planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling() ) - / this.congestionInfo.getScenario().getConfig().planCalcScore().getMarginalUtilityOfMoney(); - + final double vtts = ( this.congestionInfo.getScenario().getConfig().scoring().getPerforming_utils_hr() + - this.congestionInfo.getScenario().getConfig().scoring().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling() ) + / this.congestionInfo.getScenario().getConfig().scoring().getMarginalUtilityOfMoney(); + + final double toleratedAvgDelay = this.congestionInfo.getDecongestionConfigGroup().getToleratedAverageDelaySec(); final boolean msa = this.congestionInfo.getDecongestionConfigGroup().isMsa(); final double blendFactorFromConfig = this.congestionInfo.getDecongestionConfigGroup().getTollBlendFactor(); - + for (Id linkId : this.congestionInfo.getlinkInfos().keySet()) { - + LinkInfo linkInfo = this.congestionInfo.getlinkInfos().get(linkId); for (Integer intervalNr : linkInfo.getTime2avgDelay().keySet()) { - + // average delay - - double averageDelay = linkInfo.getTime2avgDelay().get(intervalNr); + + double averageDelay = linkInfo.getTime2avgDelay().get(intervalNr); if (averageDelay <= toleratedAvgDelay) { averageDelay = 0.0; } - + // toll - + double demand = 1.0; if (this.linkId2time2leavingAgents.get(linkId) != null && this.linkId2time2leavingAgents.get(linkId).get(intervalNr) != null) { demand = this.linkId2time2leavingAgents.get(linkId).get(intervalNr); } - + double toll = vtts * demand * averageDelay / 3600.; // prevent negative tolls - + if (toll < 0) { log.warn("Negative tolls... Are you sure everything works fine?"); toll = 0; } - + // smoothen the tolls - + Double previousToll = linkInfo.getTime2toll().get(intervalNr); double blendFactor; @@ -106,35 +106,35 @@ public void updateTolls() { } else { blendFactor = blendFactorFromConfig; } - + double smoothedToll; if (previousToll != null && previousToll >= 0.) { smoothedToll = toll * blendFactor + previousToll * (1 - blendFactor); } else { smoothedToll = toll; } - + // store the updated toll - + linkInfo.getTime2toll().put(intervalNr, smoothedToll); - } + } } - + log.info("Updating tolls completed."); this.tollUpdateCounter++; - + // store the current link information for the next toll computation - + linkId2infoPreviousTollComputation = new HashMap<>(); for ( Map.Entry< Id,LinkInfo> entry : this.congestionInfo.getlinkInfos().entrySet() ) { LinkInfo linkInfo = entry.getValue() ; - + Map time2previousDelay = new HashMap<>(); for (Integer intervalNr : linkInfo.getTime2avgDelay().keySet()) { time2previousDelay.put(intervalNr, linkInfo.getTime2avgDelay().get(intervalNr)); } - + LinkInfo linkInfoPreviousTollComputation = new LinkInfo(linkInfo.getLink()); linkInfoPreviousTollComputation.setTime2avgDelay(time2previousDelay); linkId2infoPreviousTollComputation.put(linkInfo.getLink().getId(), linkInfoPreviousTollComputation); @@ -151,27 +151,27 @@ public void handleEvent(LinkLeaveEvent event) { int timeBinNr = getIntervalNr(event.getTime()); Id linkId = event.getLinkId(); - + if (linkId2time2leavingAgents.get(linkId) != null) { - + if (linkId2time2leavingAgents.get(linkId).get(timeBinNr) != null) { int leavingAgents = linkId2time2leavingAgents.get(linkId).get(timeBinNr) + 1; linkId2time2leavingAgents.get(linkId).put(timeBinNr, leavingAgents); - + } else { linkId2time2leavingAgents.get(linkId).put(timeBinNr, 1); } - + } else { Map time2leavingAgents = new HashMap<>(); time2leavingAgents.put(timeBinNr, 1); linkId2time2leavingAgents.put(linkId, time2leavingAgents); - + } } - + private int getIntervalNr(double time) { - double timeBinSize = congestionInfo.getScenario().getConfig().travelTimeCalculator().getTraveltimeBinSize(); + double timeBinSize = congestionInfo.getScenario().getConfig().travelTimeCalculator().getTraveltimeBinSize(); return (int) (time / timeBinSize); } diff --git a/contribs/decongestion/src/test/java/org/matsim/contrib/decongestion/DecongestionPricingTestIT.java b/contribs/decongestion/src/test/java/org/matsim/contrib/decongestion/DecongestionPricingTestIT.java index ac6697e3694..ee68e87271b 100644 --- a/contribs/decongestion/src/test/java/org/matsim/contrib/decongestion/DecongestionPricingTestIT.java +++ b/contribs/decongestion/src/test/java/org/matsim/contrib/decongestion/DecongestionPricingTestIT.java @@ -1,560 +1,678 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2013 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.contrib.decongestion; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.matsim.analysis.ScoreStatsControlerListener.ScoreItem; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.decongestion.DecongestionConfigGroup.DecongestionApproach; -import org.matsim.contrib.decongestion.data.DecongestionInfo; -import org.matsim.contrib.decongestion.handler.DelayAnalysis; -import org.matsim.contrib.decongestion.handler.IntervalBasedTolling; -import org.matsim.contrib.decongestion.handler.IntervalBasedTollingAll; -import org.matsim.contrib.decongestion.handler.PersonVehicleTracker; -import org.matsim.contrib.decongestion.routing.TollTimeDistanceTravelDisutilityFactory; -import org.matsim.contrib.decongestion.tollSetting.DecongestionTollSetting; -import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingBangBang; -import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingPID; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.controler.AbstractModule; -import org.matsim.core.controler.Controler; -import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.testcases.MatsimTestUtils; - -/** - * - * - * @author ikaddoura - * - */ -public class DecongestionPricingTestIT { - - @Rule - public MatsimTestUtils testUtils = new MatsimTestUtils(); - - /** - * Kp = 0.0123 - * - */ - @Test - public final void test0a() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; - - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setKp(0.0123); - decongestionSettings.setKd(0.0); - decongestionSettings.setKi(0.0); - decongestionSettings.setMsa(false); - decongestionSettings.setTollBlendFactor(1.0); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - DecongestionInfo info = new DecongestionInfo(); - - // congestion toll computation - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - - this.bind(DecongestionInfo.class).toInstance(info); - - this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); - this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); - - this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.bind(PersonVehicleTracker.class).asEagerSingleton(); - - this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); - this.addEventHandlerBinding().to(DelayAnalysis.class); - this.addEventHandlerBinding().to(PersonVehicleTracker.class); - - this.addControlerListenerBinding().to(DecongestionControlerListener.class); - - } - }); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - - controler.addOverridingModule(new AbstractModule(){ - @Override - public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); - double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); - double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); - - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt0, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 150.5, tt1, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt2, MatsimTestUtils.EPSILON); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); - Assert.assertEquals("Wrong average executed score. The tolls seem to have changed.", -33.940316666666666, avgScore, MatsimTestUtils.EPSILON); - - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); - - Assert.assertEquals("Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5", 50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong toll.", 50.5 * 0.0123, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84), MatsimTestUtils.EPSILON); - - } - - /** - * Kp = 0.0123, other syntax - * - */ - @Test - public final void test0amodified() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; - - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setKp(0.0123); - decongestionSettings.setKd(0.0); - decongestionSettings.setKi(0.0); - decongestionSettings.setMsa(false); - decongestionSettings.setTollBlendFactor(1.0); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - // congestion toll computation - controler.addOverridingModule(new DecongestionModule(scenario)); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - - controler.addOverridingModule(new AbstractModule(){ - @Override - public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); - double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); - double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); - - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt0, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 150.5, tt1, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt2, MatsimTestUtils.EPSILON); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); - Assert.assertEquals("Wrong average executed score. The tolls seem to have changed.", -33.940316666666666, avgScore, MatsimTestUtils.EPSILON); - } - - /** - * Kp = 2 - * - */ - @Test - public final void test0b() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; - - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setKp(2.0); - decongestionSettings.setKd(0.0); - decongestionSettings.setKi(0.0); - decongestionSettings.setMsa(false); - decongestionSettings.setTollBlendFactor(1.0); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - DecongestionInfo info = new DecongestionInfo(); - - // congestion toll computation - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - - this.bind(DecongestionInfo.class).toInstance(info); - - this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); - this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); - - this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.bind(PersonVehicleTracker.class).asEagerSingleton(); - - this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); - this.addEventHandlerBinding().to(DelayAnalysis.class); - this.addEventHandlerBinding().to(PersonVehicleTracker.class); - - this.addControlerListenerBinding().to(DecongestionControlerListener.class); - - } - }); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - - controler.addOverridingModule(new AbstractModule(){ - @Override - public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); - double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); - double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); - - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt0, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 150.5, tt1, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt2, MatsimTestUtils.EPSILON); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); - Assert.assertEquals("Wrong average executed score. The tolls seem to have changed.", -134.31916666666666, avgScore, MatsimTestUtils.EPSILON); - - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); - - Assert.assertEquals("Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5", 50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong toll.", 50.5 * 2, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84), MatsimTestUtils.EPSILON); - } - - /** - * Kp = 2 - * - */ - @Test - public final void test0bmodified() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; - - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setKp(2.0); - decongestionSettings.setKd(0.0); - decongestionSettings.setKi(0.0); - decongestionSettings.setMsa(false); - decongestionSettings.setTollBlendFactor(1.0); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - // congestion toll computation - controler.addOverridingModule(new DecongestionModule(scenario)); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - - controler.addOverridingModule(new AbstractModule(){ - @Override - public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); - double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); - double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); - - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt0, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 150.5, tt1, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt2, MatsimTestUtils.EPSILON); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); - Assert.assertEquals("Wrong average executed score. The tolls seem to have changed.", -134.31916666666666, avgScore, MatsimTestUtils.EPSILON); - } - - /** - * Kp = 0 / no tolling - * - */ - @Test - public final void test0c() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; - - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setKp(0.0); - decongestionSettings.setKd(0.0); - decongestionSettings.setKi(0.0); - decongestionSettings.setMsa(false); - decongestionSettings.setTollBlendFactor(1.0); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - DecongestionInfo info = new DecongestionInfo(); - - // congestion toll computation - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - - this.bind(DecongestionInfo.class).toInstance(info); - - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.addEventHandlerBinding().to(DelayAnalysis.class); - - this.addControlerListenerBinding().to(DecongestionControlerListener.class); - - } - }); - - // toll-adjusted routing - - final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); - - controler.addOverridingModule(new AbstractModule(){ - @Override - public void install() { - this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); - double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); - double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); - - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt0, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 150.5, tt1, MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong travel time. The run output seems to have changed.", 100.0, tt2, MatsimTestUtils.EPSILON); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); - Assert.assertEquals("Wrong average executed score. The tolls seem to have changed.", -33.31916666666666, avgScore, MatsimTestUtils.EPSILON); - - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); - - Assert.assertEquals("Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5", 50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong toll.", null, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84)); - - } - - /** - * Tests the PID controller - * - */ - @Test - public final void test1() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config.xml"; - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - decongestionSettings.setDecongestionApproach(DecongestionApproach.PID); - config.addModule(decongestionSettings); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - DecongestionInfo info = new DecongestionInfo(); - - // decongestion pricing - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - - this.bind(DecongestionInfo.class).toInstance(info); - - this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); - this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); - - this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.bind(PersonVehicleTracker.class).asEagerSingleton(); - - this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); - this.addEventHandlerBinding().to(DelayAnalysis.class); - this.addEventHandlerBinding().to(PersonVehicleTracker.class); - - this.addControlerListenerBinding().to(DecongestionControlerListener.class); - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index) ; - Assert.assertEquals("Wrong average executed score. The run output seems to have changed.", -11749.431349675931, avgScore, MatsimTestUtils.EPSILON); - - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); - Assert.assertEquals("Wrong toll in time bin 61.", 12.600000000000009, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(61), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong toll in time bin 73.", 16.665000000000006, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(73), MatsimTestUtils.EPSILON); - } - - /** - * Tests the BangBang controller - * - */ - @Test - public final void test2() { - - System.out.println(testUtils.getPackageInputDirectory()); - - final String configFile = testUtils.getPackageInputDirectory() + "/config.xml"; - Config config = ConfigUtils.loadConfig(configFile); - - String outputDirectory = testUtils.getOutputDirectory() + "/"; - config.controler().setOutputDirectory(outputDirectory); - - final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); - decongestionSettings.setWriteOutputIteration(1); - decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); - decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); - config.addModule(decongestionSettings); - - DecongestionInfo info = new DecongestionInfo(); - - final Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - // decongestion pricing - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - - this.bind(DecongestionInfo.class).toInstance(info); - - this.bind(DecongestionTollSetting.class).to(DecongestionTollingBangBang.class); - this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); - - this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); - this.bind(DelayAnalysis.class).asEagerSingleton(); - this.bind(PersonVehicleTracker.class).asEagerSingleton(); - - this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); - this.addEventHandlerBinding().to(DelayAnalysis.class); - this.addEventHandlerBinding().to(PersonVehicleTracker.class); - - this.addControlerListenerBinding().to(DecongestionControlerListener.class); - - } - }); - - controler.getConfig().controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - controler.run(); - - final int index = config.controler().getLastIteration() - config.controler().getFirstIteration(); - double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get( index ) ; - Assert.assertEquals("Wrong average executed score. The run output seems to have changed.", -54.97929444444, avgScore, MatsimTestUtils.EPSILON); - - System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); - Assert.assertEquals("Wrong toll in time bin 61.", 13., info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(61), MatsimTestUtils.EPSILON); - Assert.assertEquals("Wrong toll in time bin 73.", 13., info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(73), MatsimTestUtils.EPSILON); - } - -} +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2013 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.contrib.decongestion; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.analysis.ScoreStatsControlerListener.ScoreItem; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.decongestion.DecongestionConfigGroup.DecongestionApproach; +import org.matsim.contrib.decongestion.data.DecongestionInfo; +import org.matsim.contrib.decongestion.data.LinkInfo; +import org.matsim.contrib.decongestion.handler.DelayAnalysis; +import org.matsim.contrib.decongestion.handler.IntervalBasedTolling; +import org.matsim.contrib.decongestion.handler.IntervalBasedTollingAll; +import org.matsim.contrib.decongestion.handler.PersonVehicleTracker; +import org.matsim.contrib.decongestion.routing.TollTimeDistanceTravelDisutilityFactory; +import org.matsim.contrib.decongestion.tollSetting.DecongestionTollSetting; +import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingBangBang; +import org.matsim.contrib.decongestion.tollSetting.DecongestionTollingPID; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.router.util.TravelTime; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.examples.ExamplesUtils; +import org.matsim.testcases.MatsimTestUtils; + +import java.net.URL; + +/** + * + * + * @author ikaddoura + * + */ +public class DecongestionPricingTestIT { + + @RegisterExtension + private MatsimTestUtils testUtils = new MatsimTestUtils(); + + /** + * Kp = 0.0123 + * + */ + @Test + final void test0a() { + + System.out.println(testUtils.getPackageInputDirectory()); + + final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; + + Config config = ConfigUtils.loadConfig(configFile); + + String outputDirectory = testUtils.getOutputDirectory() + "/"; + config.controller().setOutputDirectory(outputDirectory); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setKp(0.0123); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + config.addModule(decongestionSettings); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + DecongestionInfo info = new DecongestionInfo(); + + // congestion toll computation + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + + this.bind(DecongestionInfo.class).toInstance(info); + + this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); + this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); + + this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); + this.bind(DelayAnalysis.class).asEagerSingleton(); + this.bind(PersonVehicleTracker.class).asEagerSingleton(); + + this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); + this.addEventHandlerBinding().to(DelayAnalysis.class); + this.addEventHandlerBinding().to(PersonVehicleTracker.class); + + this.addControlerListenerBinding().to(DecongestionControlerListener.class); + + } + }); + + // toll-adjusted routing + + controler.addOverridingModule(new AbstractModule(){ + @Override + public void install() { + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( new TollTimeDistanceTravelDisutilityFactory() ); + } + }); + + controler.run(); + + double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); + double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); + double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); + + Assertions.assertEquals(100.0, tt0, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(150.5, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(100.0, tt2, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); + Assertions.assertEquals(-33.940316666666666, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The tolls seem to have changed."); + + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); + + Assertions.assertEquals(50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON, "Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5"); + Assertions.assertEquals(50.5 * 0.0123, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84), MatsimTestUtils.EPSILON, "Wrong toll."); + + } + + /** + * Kp = 0.0123, other syntax + * + */ + @Test + final void test0amodified() { + + System.out.println(testUtils.getPackageInputDirectory()); + + // --- + + Config config = ConfigUtils.loadConfig( testUtils.getPackageInputDirectory() + "/config0.xml" ); + + config.controller().setOutputDirectory( testUtils.getOutputDirectory() ); + + final DecongestionConfigGroup decongestionSettings = ConfigUtils.addOrGetModule( config, DecongestionConfigGroup.class ); + + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setKp(0.0123); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + + // --- + + final Scenario scenario = ScenarioUtils.loadScenario(config); + + // --- + + Controler controler = new Controler(scenario); + + // congestion toll computation + controler.addOverridingModule(new DecongestionModule() ); + + // toll-adjusted routing + + controler.addOverridingModule(new AbstractModule(){ + @Override + public void install() { + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( new TollTimeDistanceTravelDisutilityFactory() ); + } + }); + + controler.run(); + + // --- + + double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); + double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); + double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); + + Assertions.assertEquals(100.0, tt0, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(150.5, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(100.0, tt2, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); + Assertions.assertEquals(-33.940316666666666, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The tolls seem to have changed."); + } + + /** + * Kp = 0.0123, other syntax, kn + * + */ + @Test + final void test0amodifiedKn() { + + URL configUrl = IOUtils.extendUrl( ExamplesUtils.getTestScenarioURL( "equil" ), "config.xml" ); + + Config config = ConfigUtils.loadConfig( configUrl ); + config.controller().setOutputDirectory( testUtils.getOutputDirectory() ); + + config.plans().setInputFile( "plans2000.xml.gz" ); + // (in my first attempts, the default plans file had too few agents. after my later changes, it may no longer be necessary to use this file here. kai, jan'23) + + config.controller().setLastIteration( 20 ); + // (need some iterations for the decongestion to unfold. 20 may be more than really needed. kai, jan'23) + + final DecongestionConfigGroup decongestionSettings = ConfigUtils.addOrGetModule( config, DecongestionConfigGroup.class ); + + decongestionSettings.setWriteOutputIteration(1); +// decongestionSettings.setKp(0.0123); + decongestionSettings.setKp(0.123); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + + // === + + final Scenario scenario = ScenarioUtils.loadScenario(config); + + Network network = scenario.getNetwork(); + + // make middle link faster + network.getLinks().get( Id.createLinkId( "6" )).setFreespeed( 100. ); + + // make alternative wider + network.getLinks().get( Id.createLinkId( "14" ) ).setCapacity( 100000. ); + + // increase some other capacities: + network.getLinks().get( Id.createLinkId( "5" ) ).setCapacity( 100000. ); + network.getLinks().get( Id.createLinkId( "6" ) ).setCapacity( 100000. ); + + // remove all other alternatives: + network.removeLink( Id.createLinkId( "11" ) ); + network.removeLink( Id.createLinkId( "12" ) ); + network.removeLink( Id.createLinkId( "13" ) ); + network.removeLink( Id.createLinkId( "16" ) ); + network.removeLink( Id.createLinkId( "17" ) ); + network.removeLink( Id.createLinkId( "18" ) ); + network.removeLink( Id.createLinkId( "19" ) ); + + network.removeLink( Id.createLinkId( "2" ) ); + network.removeLink( Id.createLinkId( "3" ) ); + network.removeLink( Id.createLinkId( "4" ) ); + network.removeLink( Id.createLinkId( "7" ) ); + network.removeLink( Id.createLinkId( "8" ) ); + network.removeLink( Id.createLinkId( "9" ) ); + network.removeLink( Id.createLinkId( "10" ) ); + + // --- + + Population population = scenario.getPopulation(); + + // remove 3/4 of the population to reduce computation time: + for ( int ii=500; ii<2000; ii++ ){ + population.removePerson( Id.createPersonId( ii ) ); + } + + + // --- + + Controler controler = new Controler(scenario); + + controler.addOverridingModule(new DecongestionModule() ); + +// controler.addOverridingModule( new OTFVisLiveModule() ); + + controler.run(); + + // === + + DecongestionInfo info = controler.getInjector().getInstance( DecongestionInfo.class ); + + final LinkInfo linkInfo = info.getlinkInfos().get( Id.createLinkId( "15" ) ); + if ( linkInfo!= null ){ + System.out.println( linkInfo.getTime2toll().toString() ); + } + + final TravelTime linkTravelTimes = controler.getLinkTravelTimes(); + double tt0a = linkTravelTimes.getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("15" ) ), 6 * 3600-1 , null, null ); + double tt0b = linkTravelTimes.getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("15" ) ), 6 * 3600 , null, null ); + double tt0c = linkTravelTimes.getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("15" ) ), 6 * 3600+15*60 , null, null ); + double tt1 = linkTravelTimes.getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("14" ) ), 6 * 3600, null, null ); + + System.err.println( tt0a + " " + tt0b + " " + tt0c ); + System.err.println( tt1 ); + + Assertions.assertEquals(179.985, tt0a, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(344.04, tt0b, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(179.985, tt0c, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(180.0, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + } + + /** + * Kp = 2 + * + */ + @Test + final void test0b() { + + System.out.println(testUtils.getPackageInputDirectory()); + + final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; + + Config config = ConfigUtils.loadConfig(configFile); + + String outputDirectory = testUtils.getOutputDirectory() + "/"; + config.controller().setOutputDirectory(outputDirectory); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setKp(2.0); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + config.addModule(decongestionSettings); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + DecongestionInfo info = new DecongestionInfo(); + + // congestion toll computation + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + + this.bind(DecongestionInfo.class).toInstance(info); + + this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); + this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); + + this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); + this.bind(DelayAnalysis.class).asEagerSingleton(); + this.bind(PersonVehicleTracker.class).asEagerSingleton(); + + this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); + this.addEventHandlerBinding().to(DelayAnalysis.class); + this.addEventHandlerBinding().to(PersonVehicleTracker.class); + + this.addControlerListenerBinding().to(DecongestionControlerListener.class); + + } + }); + + // toll-adjusted routing + + final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); + + controler.addOverridingModule(new AbstractModule(){ + @Override + public void install() { + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( travelDisutilityFactory ); + } + }); + + controler.getConfig().controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + controler.run(); + + // === + + double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); + double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); + double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); + + Assertions.assertEquals(100.0, tt0, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(150.5, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(100.0, tt2, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); + Assertions.assertEquals(-134.31916666666666, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The tolls seem to have changed."); + + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); + + Assertions.assertEquals(50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON, "Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5"); + Assertions.assertEquals(50.5 * 2, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84), MatsimTestUtils.EPSILON, "Wrong toll."); + } + + /** + * Kp = 2 + * + */ + @Test + final void test0bmodified() { + + System.out.println(testUtils.getPackageInputDirectory()); + + final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; + + Config config = ConfigUtils.loadConfig(configFile); + + String outputDirectory = testUtils.getOutputDirectory() + "/"; + config.controller().setOutputDirectory(outputDirectory); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setKp(2.0); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + config.addModule(decongestionSettings); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + // congestion toll computation + controler.addOverridingModule(new DecongestionModule() ); + + // toll-adjusted routing + + final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); + + controler.addOverridingModule(new AbstractModule(){ + @Override + public void install() { + addTravelDisutilityFactoryBinding( TransportMode.car ).toInstance( travelDisutilityFactory ); + } + }); + + controler.getConfig().controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + controler.run(); + + double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); + double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); + double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); + + Assertions.assertEquals(100.0, tt0, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(150.5, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(100.0, tt2, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); + Assertions.assertEquals(-134.31916666666666, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The tolls seem to have changed."); + } + + /** + * Kp = 0 / no tolling + * + */ + @Test + final void test0c() { + + System.out.println(testUtils.getPackageInputDirectory()); + + final String configFile = testUtils.getPackageInputDirectory() + "/config0.xml"; + + Config config = ConfigUtils.loadConfig(configFile); + + String outputDirectory = testUtils.getOutputDirectory() + "/"; + config.controller().setOutputDirectory(outputDirectory); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setKp(0.0); + decongestionSettings.setKd(0.0); + decongestionSettings.setKi(0.0); + decongestionSettings.setMsa(false); + decongestionSettings.setTollBlendFactor(1.0); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + config.addModule(decongestionSettings); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + DecongestionInfo info = new DecongestionInfo(); + + // congestion toll computation + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + + this.bind(DecongestionInfo.class).toInstance(info); + + this.bind(DelayAnalysis.class).asEagerSingleton(); + this.addEventHandlerBinding().to(DelayAnalysis.class); + + this.addControlerListenerBinding().to(DecongestionControlerListener.class); + + } + }); + + // toll-adjusted routing + + final TollTimeDistanceTravelDisutilityFactory travelDisutilityFactory = new TollTimeDistanceTravelDisutilityFactory(); + + controler.addOverridingModule(new AbstractModule(){ + @Override + public void install() { + this.bindCarTravelDisutilityFactory().toInstance( travelDisutilityFactory ); + } + }); + + controler.getConfig().controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + controler.run(); + + double tt0 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 6 * 3600 + 50. * 60, null, null); + double tt1 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 63, null, null); + double tt2 = controler.getLinkTravelTimes().getLinkTravelTime(scenario.getNetwork().getLinks().get(Id.createLinkId("link12")), 7 * 3600 + 15. * 60, null, null); + + Assertions.assertEquals(100.0, tt0, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(150.5, tt1, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + Assertions.assertEquals(100.0, tt2, MatsimTestUtils.EPSILON, "Wrong travel time. The run output seems to have changed."); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index); + Assertions.assertEquals(-33.31916666666666, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The tolls seem to have changed."); + + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().toString()); + + Assertions.assertEquals(50.5, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2avgDelay().get(84), MatsimTestUtils.EPSILON, "Wrong average delay (capacity is set in a way that one of the two agents has to wait 101 sec. Thus the average is 50.5"); + Assertions.assertNull(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(84), "Wrong toll."); + + } + + /** + * Tests the PID controller + * + */ + @Test + final void test1() { + + System.out.println(testUtils.getPackageInputDirectory()); + + final String configFile = testUtils.getPackageInputDirectory() + "/config.xml"; + Config config = ConfigUtils.loadConfig(configFile); + + String outputDirectory = testUtils.getOutputDirectory() + "/"; + config.controller().setOutputDirectory(outputDirectory); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + decongestionSettings.setDecongestionApproach(DecongestionApproach.PID); + config.addModule(decongestionSettings); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + DecongestionInfo info = new DecongestionInfo(); + + // decongestion pricing + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + + this.bind(DecongestionInfo.class).toInstance(info); + + this.bind(DecongestionTollSetting.class).to(DecongestionTollingPID.class); + this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); + + this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); + this.bind(DelayAnalysis.class).asEagerSingleton(); + this.bind(PersonVehicleTracker.class).asEagerSingleton(); + + this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); + this.addEventHandlerBinding().to(DelayAnalysis.class); + this.addEventHandlerBinding().to(PersonVehicleTracker.class); + + this.addControlerListenerBinding().to(DecongestionControlerListener.class); + } + }); + + controler.getConfig().controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + controler.run(); + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get(index) ; + Assertions.assertEquals(-12036.177448472225, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The run output seems to have changed."); + + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); + Assertions.assertEquals(9.197000000000003, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(61), MatsimTestUtils.EPSILON, "Wrong toll in time bin 61."); + Assertions.assertEquals(12.963999999999984, info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(73), MatsimTestUtils.EPSILON, "Wrong toll in time bin 73."); + } + + /** + * Tests the BangBang controller + * + */ + @Test + final void test2() { + + System.out.println(testUtils.getPackageInputDirectory()); + + Config config = ConfigUtils.loadConfig( testUtils.getPackageInputDirectory() + "/config.xml" ); + + config.controller().setOutputDirectory( testUtils.getOutputDirectory() ); + + final DecongestionConfigGroup decongestionSettings = new DecongestionConfigGroup(); + decongestionSettings.setWriteOutputIteration(1); + decongestionSettings.setFractionOfIterationsToEndPriceAdjustment(1.0); + decongestionSettings.setFractionOfIterationsToStartPriceAdjustment(0.0); + config.addModule(decongestionSettings); + + DecongestionInfo info = new DecongestionInfo(); + + final Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + // decongestion pricing + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + + this.bind(DecongestionInfo.class).toInstance(info); + + this.bind(DecongestionTollSetting.class).to(DecongestionTollingBangBang.class); + this.bind(IntervalBasedTolling.class).to(IntervalBasedTollingAll.class); + + this.bind(IntervalBasedTollingAll.class).asEagerSingleton(); + this.bind(DelayAnalysis.class).asEagerSingleton(); + this.bind(PersonVehicleTracker.class).asEagerSingleton(); + + this.addEventHandlerBinding().to(IntervalBasedTollingAll.class); + this.addEventHandlerBinding().to(DelayAnalysis.class); + this.addEventHandlerBinding().to(PersonVehicleTracker.class); + + this.addControlerListenerBinding().to(DecongestionControlerListener.class); + + } + }); + + controler.run(); + + // --- + + final int index = config.controller().getLastIteration() - config.controller().getFirstIteration(); + double avgScore = controler.getScoreStats().getScoreHistory().get( ScoreItem.executed ).get( index ) ; + Assertions.assertEquals(-55.215645833333184, avgScore, MatsimTestUtils.EPSILON, "Wrong average executed score. The run output seems to have changed."); + + System.out.println(info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().toString()); + Assertions.assertEquals(13., info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(61), MatsimTestUtils.EPSILON, "Wrong toll in time bin 61."); + Assertions.assertEquals(13., info.getlinkInfos().get(Id.createLinkId("link12")).getTime2toll().get(73), MatsimTestUtils.EPSILON, "Wrong toll in time bin 73."); + } + +} diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceConfigurator.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceConfigurator.java index 44838aa3186..4cf1f8704cb 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceConfigurator.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceConfigurator.java @@ -10,8 +10,8 @@ import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import org.matsim.contribs.discrete_mode_choice.replanning.NonSelectedPlanSelector; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.StrategyConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule.DefaultSelector; import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule.DefaultStrategy; @@ -19,7 +19,7 @@ /** * Utility class that makes it possible to set up various was of using the * Discrete Mode Choice extension with MATSim. - * + * * @author sebhoerl */ public final class DiscreteModeChoiceConfigurator { @@ -28,7 +28,7 @@ private DiscreteModeChoiceConfigurator() { } static public void configureAsSubtourModeChoiceReplacement(Config config) { - for (StrategySettings strategy : config.strategy().getStrategySettings()) { + for (StrategySettings strategy : config.replanning().getStrategySettings()) { if (strategy.getStrategyName().equals(DefaultStrategy.SubtourModeChoice)) { strategy.setStrategyName(DiscreteModeChoiceModule.STRATEGY_NAME); } @@ -89,24 +89,24 @@ static public void configureAsModeChoiceInTheLoop(Config config) { } static public void configureAsModeChoiceInTheLoop(Config config, double replanningRate) { - StrategyConfigGroup strategyConfigGroup = config.strategy(); - strategyConfigGroup.clearStrategySettings(); + ReplanningConfigGroup replanningConfigGroup = config.replanning(); + replanningConfigGroup.clearStrategySettings(); - strategyConfigGroup.setMaxAgentPlanMemorySize(1); - strategyConfigGroup.setFractionOfIterationsToDisableInnovation(Double.POSITIVE_INFINITY); - strategyConfigGroup.setPlanSelectorForRemoval(NonSelectedPlanSelector.NAME); + replanningConfigGroup.setMaxAgentPlanMemorySize(1); + replanningConfigGroup.setFractionOfIterationsToDisableInnovation(Double.POSITIVE_INFINITY); + replanningConfigGroup.setPlanSelectorForRemoval(NonSelectedPlanSelector.NAME); StrategySettings dmcStrategy = new StrategySettings(); dmcStrategy.setStrategyName(DiscreteModeChoiceModule.STRATEGY_NAME); dmcStrategy.setWeight(replanningRate); - strategyConfigGroup.addStrategySettings(dmcStrategy); + replanningConfigGroup.addStrategySettings(dmcStrategy); StrategySettings selectorStrategy = new StrategySettings(); selectorStrategy.setStrategyName(DefaultSelector.KeepLastSelected); selectorStrategy.setWeight(1.0 - replanningRate); - strategyConfigGroup.addStrategySettings(selectorStrategy); + replanningConfigGroup.addStrategySettings(selectorStrategy); - checkModeChoiceInTheLoop(strategyConfigGroup); + checkModeChoiceInTheLoop(replanningConfigGroup); DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules() .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); @@ -119,15 +119,15 @@ static public void configureAsModeChoiceInTheLoop(Config config, double replanni dmcConfig.setEnforceSinglePlan(true); } - public static void checkModeChoiceInTheLoop(StrategyConfigGroup strategyConfigGroup) { - if (strategyConfigGroup.getMaxAgentPlanMemorySize() != 1) { + public static void checkModeChoiceInTheLoop(ReplanningConfigGroup replanningConfigGroup) { + if (replanningConfigGroup.getMaxAgentPlanMemorySize() != 1) { throw new IllegalStateException( "Option strategy.maxAgentPlanMemorySize should be 1 if mode-choice-in-the-loop is enforced."); } Set activeStrategies = new HashSet<>(); - for (StrategySettings strategySettings : strategyConfigGroup.getStrategySettings()) { + for (StrategySettings strategySettings : replanningConfigGroup.getStrategySettings()) { if (strategySettings.getDisableAfter() != 0) { activeStrategies.add(strategySettings.getStrategyName()); } @@ -146,14 +146,14 @@ public static void checkModeChoiceInTheLoop(StrategyConfigGroup strategyConfigGr activeStrategies.remove(DefaultSelector.KeepLastSelected); activeStrategies.remove(DiscreteModeChoiceModule.STRATEGY_NAME); activeStrategies.remove(DefaultStrategy.ReRoute); - + if (activeStrategies.size() > 0) { throw new IllegalStateException( "All these strategies should be disabled (disableAfter == 0) if mode-choice-in-the-loop is enforced: " + activeStrategies); } - if (!strategyConfigGroup.getPlanSelectorForRemoval().equals(NonSelectedPlanSelector.NAME)) { + if (!replanningConfigGroup.getPlanSelectorForRemoval().equals(NonSelectedPlanSelector.NAME)) { throw new IllegalStateException( "Removal selector should be NonSelectedPlanSelector if mode-choice-in-the-loop is enforced."); } diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceModule.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceModule.java index 58db9c55b85..abf34cb42f6 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceModule.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/DiscreteModeChoiceModule.java @@ -11,7 +11,7 @@ /** * Main module of the Discrete Mode Choice extension. Should be added as an * overriding module before the MATSim controller is started. - * + * * @author sebhoerl */ public class DiscreteModeChoiceModule extends AbstractModule { @@ -24,7 +24,7 @@ public class DiscreteModeChoiceModule extends AbstractModule { public void install() { addPlanStrategyBinding(STRATEGY_NAME).toProvider(DiscreteModeChoiceStrategyProvider.class); - if (getConfig().strategy().getPlanSelectorForRemoval().equals(NonSelectedPlanSelector.NAME)) { + if (getConfig().replanning().getPlanSelectorForRemoval().equals(NonSelectedPlanSelector.NAME)) { bindPlanSelectorForRemoval().to(NonSelectedPlanSelector.class); } diff --git a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ModeChoiceInTheLoopChecker.java b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ModeChoiceInTheLoopChecker.java index 0d7df42a168..04617415d08 100644 --- a/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ModeChoiceInTheLoopChecker.java +++ b/contribs/discrete_mode_choice/src/main/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ModeChoiceInTheLoopChecker.java @@ -4,7 +4,7 @@ import org.matsim.api.core.v01.population.Plan; import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceConfigurator; import org.matsim.contribs.discrete_mode_choice.replanning.NonSelectedPlanSelector; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.events.StartupEvent; import org.matsim.core.controler.listener.StartupListener; import org.matsim.core.replanning.selectors.PlanSelector; @@ -14,16 +14,16 @@ /** * Internal listener that is used to do some runtime checks when * mode-choice-in-the-loop should be enforced. - * + * * @author sebhoerl * */ public class ModeChoiceInTheLoopChecker implements StartupListener { - private final StrategyConfigGroup strategyConfig; + private final ReplanningConfigGroup strategyConfig; private final PlanSelector removalSelector; @Inject - public ModeChoiceInTheLoopChecker(StrategyConfigGroup strategyConfig, PlanSelector removalSelector) { + public ModeChoiceInTheLoopChecker(ReplanningConfigGroup strategyConfig, PlanSelector removalSelector) { this.strategyConfig = strategyConfig; this.removalSelector = removalSelector; } diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/SubtourModeChoiceReplacementTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/SubtourModeChoiceReplacementTest.java index 2abbf28777c..416162e725e 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/SubtourModeChoiceReplacementTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/SubtourModeChoiceReplacementTest.java @@ -1,7 +1,5 @@ package org.matsim.contrib.discrete_mode_choice; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -9,7 +7,9 @@ import java.util.Random; import java.util.Set; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.population.Plan; import org.matsim.contrib.discrete_mode_choice.test_utils.PlanBuilder; import org.matsim.contrib.discrete_mode_choice.test_utils.PlanTester; @@ -51,7 +51,7 @@ public class SubtourModeChoiceReplacementTest { @Test - public void testChoiceSet() throws NoFeasibleChoiceException { + void testChoiceSet() throws NoFeasibleChoiceException { List modes = Arrays.asList("walk", "pt"); List constrainedModes = Arrays.asList(); boolean considerCarAvailability = true; @@ -140,7 +140,7 @@ public void testChoiceSet() throws NoFeasibleChoiceException { } @Test - public void testConstrainedChoiceSet() throws NoFeasibleChoiceException { + void testConstrainedChoiceSet() throws NoFeasibleChoiceException { List modes = Arrays.asList("walk", "car"); List constrainedModes = Arrays.asList("car"); boolean considerCarAvailability = true; @@ -229,7 +229,7 @@ public void testConstrainedChoiceSet() throws NoFeasibleChoiceException { } @Test - public void testLargerCase() throws NoFeasibleChoiceException { + void testLargerCase() throws NoFeasibleChoiceException { List modes = Arrays.asList("walk", "car", "pt", "bike"); List constrainedModes = Arrays.asList("car", "bike"); boolean considerCarAvailability = true; diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/constraints/VehicleTourConstraintTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/constraints/VehicleTourConstraintTest.java index 24bc7e6ceb5..f5c0fd7ce92 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/constraints/VehicleTourConstraintTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/constraints/VehicleTourConstraintTest.java @@ -1,13 +1,13 @@ package org.matsim.contrib.discrete_mode_choice.components.constraints; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.Collection; import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.discrete_mode_choice.test_utils.PlanBuilder; @@ -20,7 +20,7 @@ public class VehicleTourConstraintTest { @Test - public void testWithHome() { + void testWithHome() { // PREPARATION HomeFinder homeFinder = (List trips) -> Id.create("A", ActivityFacility.class); Collection availableModes = Arrays.asList("car", "walk"); @@ -69,7 +69,7 @@ public void testWithHome() { } @Test - public void testWithoutHome() { + void testWithoutHome() { // PREPARATION HomeFinder homeFinder = (List trips) -> null; Collection availableModes = Arrays.asList("car", "walk"); @@ -107,7 +107,7 @@ public void testWithoutHome() { } @Test - public void testTour() { + void testTour() { // PREPARATION HomeFinder homeFinder = (List trips) -> Id.create("A", ActivityFacility.class); Collection availableModes = Arrays.asList("car", "walk"); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/readers/ApolloTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/readers/ApolloTest.java index b58abaf6f80..c588e1864cf 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/readers/ApolloTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/readers/ApolloTest.java @@ -1,17 +1,17 @@ package org.matsim.contrib.discrete_mode_choice.components.readers; -import static org.junit.Assert.assertEquals; - import java.io.IOException; import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.contribs.discrete_mode_choice.components.readers.ApolloParameterReader; import org.matsim.contribs.discrete_mode_choice.components.readers.ApolloParameters; public class ApolloTest { @Test - public void testApolloReader() throws IOException { + void testApolloReader() throws IOException { URL fixtureUrl = getClass().getClassLoader().getResource("Model_13_12_Zurich_output.txt"); ApolloParameters parameters = new ApolloParameterReader().read(fixtureUrl); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/tour_finder/ActivityTourFinderTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/tour_finder/ActivityTourFinderTest.java index af9610761ca..483cfa96dfb 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/tour_finder/ActivityTourFinderTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/tour_finder/ActivityTourFinderTest.java @@ -1,12 +1,12 @@ package org.matsim.contrib.discrete_mode_choice.components.tour_finder; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.population.Plan; import org.matsim.contribs.discrete_mode_choice.components.tour_finder.ActivityTourFinder; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; @@ -42,7 +42,7 @@ private List createFixture(String... activityTypes) { } @Test - public void testActivityTourFinder() { + void testActivityTourFinder() { ActivityTourFinder finder = new ActivityTourFinder(Arrays.asList("home")); List trips; @@ -84,7 +84,7 @@ public void testActivityTourFinder() { } @Test - public void testActivityTourFinderMultiple() { + void testActivityTourFinderMultiple() { ActivityTourFinder finder = new ActivityTourFinder(Arrays.asList("home1", "home2", "home3", "home4")); List trips; diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/utils/ScheduleWaitingTimeEstimatorTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/utils/ScheduleWaitingTimeEstimatorTest.java index 4d19508ad24..f9c951bb195 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/utils/ScheduleWaitingTimeEstimatorTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/components/utils/ScheduleWaitingTimeEstimatorTest.java @@ -1,6 +1,8 @@ package org.matsim.contrib.discrete_mode_choice.components.utils; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; @@ -25,11 +27,9 @@ import java.util.LinkedList; import java.util.List; -import static org.junit.Assert.assertEquals; - public class ScheduleWaitingTimeEstimatorTest { @Test - public void testValidSingleCase() throws IOException { + void testValidSingleCase() throws IOException { TransitSchedule schedule = createSchedule(); ScheduleWaitingTimeEstimator estimator = new ScheduleWaitingTimeEstimator(schedule); @@ -53,9 +53,9 @@ public void testValidSingleCase() throws IOException { waitingTime = estimator.estimateWaitingTime(elements); assertEquals(995.0, waitingTime, 1e-6); } - + @Test - public void testValidMultiCase() throws IOException { + void testValidMultiCase() throws IOException { TransitSchedule schedule = createSchedule(); ScheduleWaitingTimeEstimator estimator = new ScheduleWaitingTimeEstimator(schedule); @@ -72,10 +72,10 @@ public void testValidMultiCase() throws IOException { waitingTime = estimator.estimateWaitingTime(elements); assertEquals(20.0 + 995.0, waitingTime, 1e-6); } - + @Test - public void testInvalidCase() throws IOException { + void testInvalidCase() throws IOException { TransitSchedule schedule = createSchedule(); ScheduleWaitingTimeEstimator estimator = new ScheduleWaitingTimeEstimator(schedule); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java index 9d931e70283..299d69644dd 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java @@ -1,12 +1,12 @@ package org.matsim.contrib.discrete_mode_choice.examples; -import static org.junit.Assert.assertEquals; - import java.net.URL; import java.util.HashMap; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.events.PersonArrivalEvent; import org.matsim.api.core.v01.events.handler.PersonArrivalEventHandler; @@ -24,20 +24,19 @@ public class TestSiouxFalls { @Test - public void testSiouxFallsWithSubtourModeChoiceReplacement() { + void testSiouxFallsWithSubtourModeChoiceReplacement() { URL scenarioURL = ExamplesUtils.getTestScenarioURL("siouxfalls-2014"); Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(scenarioURL, "config_default.xml")); - config.transit().setRoutingAlgorithmType(TransitRoutingAlgorithmType.DijkstraBased); DiscreteModeChoiceConfigurator.configureAsSubtourModeChoiceReplacement(config); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(1); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(1); // save some bandwidth/time: - config.controler().setCreateGraphs( false ); - config.controler().setWritePlansInterval( 0 ); - config.controler().setWriteEventsInterval( 0 ); - config.controler().setDumpDataAtEnd( false ); + config.controller().setCreateGraphs( false ); + config.controller().setWritePlansInterval( 0 ); + config.controller().setWriteEventsInterval( 0 ); + config.controller().setDumpDataAtEnd( false ); config.qsim().setFlowCapFactor(10000.0); config.qsim().setStorageCapFactor(10000.0); @@ -57,14 +56,13 @@ public void install() { controller.run(); - assertEquals(42395, (int) listener.counts.get("pt")); - assertEquals(132284, (int) listener.counts.get("car")); - assertEquals(78809, (int) listener.counts.get("walk")); -// assertEquals(42520, (int) listener.counts.get("pt")); -// assertEquals(132100, (int) listener.counts.get("car")); -// assertEquals(79106, (int) listener.counts.get("walk")); - // ...setConstrainedModes(...) (inside configureAsSubtourModeChoiceReplacement(...)) used to ignore its arguments because of a typo. - // This is now corrected, but results are no longer backwards compatible. kai, jan'23 + System.out.println((int) listener.counts.get("pt")); + System.out.println((int) listener.counts.get("car")); + System.out.println(listener.counts.get("walk")); + + assertEquals(44195, listener.counts.get("pt"), 2); + assertEquals(132316, listener.counts.get("car"), 2); + assertEquals(82139, listener.counts.get("walk"), 2); } diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MaximumUtilityTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MaximumUtilityTest.java index 347139ac155..b186857b40b 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MaximumUtilityTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MaximumUtilityTest.java @@ -1,13 +1,13 @@ package org.matsim.contrib.discrete_mode_choice.models; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.population.Activity; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.FallbackBehaviour; @@ -31,7 +31,7 @@ public class MaximumUtilityTest { @Test - public void testMaximumUtility() throws NoFeasibleChoiceException { + void testMaximumUtility() throws NoFeasibleChoiceException { TripFilter tripFilter = new CompositeTripFilter(Collections.emptySet()); ModeAvailability modeAvailability = new DefaultModeAvailability(Arrays.asList("car", "pt", "walk")); TripConstraintFactory constraintFactory = new CompositeTripConstraintFactory(); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MultinomialLogitTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MultinomialLogitTest.java index 71bcf10e76b..fcee4f218af 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MultinomialLogitTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/MultinomialLogitTest.java @@ -1,7 +1,5 @@ package org.matsim.contrib.discrete_mode_choice.models; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -9,7 +7,9 @@ import java.util.Map; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.population.Activity; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.FallbackBehaviour; @@ -33,7 +33,7 @@ public class MultinomialLogitTest { @Test - public void testMultinomialLogit() throws NoFeasibleChoiceException { + void testMultinomialLogit() throws NoFeasibleChoiceException { TripFilter tripFilter = new CompositeTripFilter(Collections.emptySet()); ModeAvailability modeAvailability = new DefaultModeAvailability(Arrays.asList("car", "pt", "walk")); TripConstraintFactory constraintFactory = new CompositeTripConstraintFactory(); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/NestedLogitTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/NestedLogitTest.java index 84489c34c7c..b25de2aeb32 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/NestedLogitTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/NestedLogitTest.java @@ -1,7 +1,5 @@ package org.matsim.contrib.discrete_mode_choice.models; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -9,7 +7,9 @@ import java.util.Map; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.population.Activity; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.FallbackBehaviour; @@ -35,7 +35,7 @@ public class NestedLogitTest { @Test - public void testRedBusBlueBus() throws NoFeasibleChoiceException { + void testRedBusBlueBus() throws NoFeasibleChoiceException { TripFilter tripFilter = new CompositeTripFilter(Collections.emptySet()); ModeAvailability modeAvailability = new DefaultModeAvailability(Arrays.asList("car", "redbus", "bluebus")); TripConstraintFactory constraintFactory = new CompositeTripConstraintFactory(); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/RandomUtilityTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/RandomUtilityTest.java index e0f3e7dd619..8df0f2cf4ae 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/RandomUtilityTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/RandomUtilityTest.java @@ -1,7 +1,5 @@ package org.matsim.contrib.discrete_mode_choice.models; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -9,7 +7,9 @@ import java.util.Map; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.population.Activity; import org.matsim.contribs.discrete_mode_choice.components.estimators.UniformTripEstimator; @@ -35,7 +35,7 @@ public class RandomUtilityTest { @Test - public void testRandomUtility() throws NoFeasibleChoiceException { + void testRandomUtility() throws NoFeasibleChoiceException { TripFilter tripFilter = new CompositeTripFilter(Collections.emptySet()); ModeAvailability modeAvailability = new DefaultModeAvailability(Arrays.asList("car", "pt", "walk")); TripConstraintFactory constraintFactory = new CompositeTripConstraintFactory(); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/nested/NestCalculatorTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/nested/NestCalculatorTest.java index 499a955392a..d65e211943b 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/nested/NestCalculatorTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/models/nested/NestCalculatorTest.java @@ -1,8 +1,8 @@ package org.matsim.contrib.discrete_mode_choice.models.nested; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.NoFeasibleChoiceException; import org.matsim.contribs.discrete_mode_choice.model.nested.DefaultNest; import org.matsim.contribs.discrete_mode_choice.model.nested.DefaultNestStructure; @@ -12,7 +12,7 @@ public class NestCalculatorTest { @Test - public void testNoNesting() throws NoFeasibleChoiceException { + void testNoNesting() throws NoFeasibleChoiceException { DefaultNestStructure structure = new DefaultNestStructure(); NestCalculator calculator = new NestCalculator(structure); @@ -28,7 +28,7 @@ public void testNoNesting() throws NoFeasibleChoiceException { } @Test - public void testNoNestingRedBlue() throws NoFeasibleChoiceException { + void testNoNestingRedBlue() throws NoFeasibleChoiceException { DefaultNestStructure structure = new DefaultNestStructure(); NestCalculator calculator = new NestCalculator(structure); @@ -49,7 +49,7 @@ public void testNoNestingRedBlue() throws NoFeasibleChoiceException { } @Test - public void testNestedBalancedRedBlue() throws NoFeasibleChoiceException { + void testNestedBalancedRedBlue() throws NoFeasibleChoiceException { DefaultNestStructure structure = new DefaultNestStructure(); DefaultNest busNest = new DefaultNest("bus", 1.0); structure.addNest(structure.getRoot(), busNest); @@ -96,7 +96,7 @@ public void testNestedBalancedRedBlue() throws NoFeasibleChoiceException { } @Test - public void testNestedUnbalancedRedBlue() throws NoFeasibleChoiceException { + void testNestedUnbalancedRedBlue() throws NoFeasibleChoiceException { DefaultNestStructure structure = new DefaultNestStructure(); DefaultNest busNest = new DefaultNest("bus", 1.0); structure.addNest(structure.getRoot(), busNest); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/modules/config/ConfigTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/modules/config/ConfigTest.java index b212182d3bc..a516cf31ec3 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/modules/config/ConfigTest.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/modules/config/ConfigTest.java @@ -1,7 +1,7 @@ package org.matsim.contrib.discrete_mode_choice.modules.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.BufferedReader; import java.io.File; @@ -11,8 +11,8 @@ import java.util.Arrays; import java.util.HashSet; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigReader; @@ -21,11 +21,11 @@ import org.matsim.testcases.MatsimTestUtils; public class ConfigTest { - @Rule + @RegisterExtension public final MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testReadWriteConfig() { + void testReadWriteConfig() { // Create config DiscreteModeChoiceConfigGroup dmcConfig = new DiscreteModeChoiceConfigGroup(); Config config = ConfigUtils.createConfig(dmcConfig); @@ -46,7 +46,7 @@ public void testReadWriteConfig() { } @Test - public void testReadWriteConfigMultipleTimes() throws IOException { + void testReadWriteConfigMultipleTimes() throws IOException { DiscreteModeChoiceConfigGroup dmcConfig = new DiscreteModeChoiceConfigGroup(); Config config1 = ConfigUtils.createConfig(dmcConfig); @@ -85,7 +85,7 @@ public void testReadWriteConfigMultipleTimes() throws IOException { } @Test - public void testSetTripConstraints() { + void testSetTripConstraints() { DiscreteModeChoiceConfigGroup dmcConfig1 = new DiscreteModeChoiceConfigGroup(); dmcConfig1.setTripConstraints(Arrays.asList("A", "B", "C")); diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/replanning/TestDepartureTimes.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/replanning/TestDepartureTimes.java index cfdef620689..69f766da8d4 100644 --- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/replanning/TestDepartureTimes.java +++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/replanning/TestDepartureTimes.java @@ -1,14 +1,14 @@ package org.matsim.contrib.discrete_mode_choice.replanning; -import static org.junit.Assert.assertEquals; - import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; @@ -49,7 +49,7 @@ public class TestDepartureTimes { @Test - public void testTripBasedModelDepartureTimes() throws NoFeasibleChoiceException { + void testTripBasedModelDepartureTimes() throws NoFeasibleChoiceException { TripBasedModel model = createTripBasedModel(); // Case 1: Only activity end times, and trips fall well between the end times @@ -130,7 +130,7 @@ public void testTripBasedModelDepartureTimes() throws NoFeasibleChoiceException } @Test - public void testPushDepartureTimeToNextTour() throws NoFeasibleChoiceException { + void testPushDepartureTimeToNextTour() throws NoFeasibleChoiceException { TourBasedModel model = createTourBasedModel(); Plan plan = new PlanBuilder() // @@ -150,7 +150,7 @@ public void testPushDepartureTimeToNextTour() throws NoFeasibleChoiceException { } @Test - public void testAccumulateAndPushDepartureTimeToNextTour() throws NoFeasibleChoiceException { + void testAccumulateAndPushDepartureTimeToNextTour() throws NoFeasibleChoiceException { TourBasedModel model = createTourBasedModel(); Plan plan = new PlanBuilder() // diff --git a/contribs/drt-extensions/pom.xml b/contribs/drt-extensions/pom.xml index b56ab569782..3e2cbf8dcf7 100644 --- a/contribs/drt-extensions/pom.xml +++ b/contribs/drt-extensions/pom.xml @@ -24,6 +24,12 @@ 16.0-SNAPSHOT
+ + org.matsim.contrib + informed-mode-choice + 16.0-SNAPSHOT + + org.matsim.contrib simwrapper @@ -33,6 +39,7 @@ org.assertj assertj-core + test @@ -41,6 +48,11 @@ 16.0-SNAPSHOT test + + + org.mockito + mockito-core + diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java index 7a38e5626ee..0db7bda1d6a 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java @@ -19,13 +19,14 @@ package org.matsim.contrib.drt.extension; +import java.util.Optional; + +import javax.annotation.Nullable; + import org.matsim.contrib.drt.extension.companions.DrtCompanionParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; import org.matsim.contrib.drt.run.DrtConfigGroup; -import javax.annotation.Nullable; -import java.util.Optional; - /** * @author Steffen Axer * @@ -56,5 +57,5 @@ public Optional getDrtCompanionParams() { public Optional getDrtOperationsParams() { return Optional.ofNullable(drtOperationsParams); } - + } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java index 9d14d6a5b37..4e8659df037 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionControlerCreator.java @@ -21,28 +21,25 @@ package org.matsim.contrib.drt.extension.companions; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.drt.extension.companions.MultiModeDrtCompanionModule; import org.matsim.contrib.drt.run.DrtConfigs; import org.matsim.contrib.drt.run.DrtControlerCreator; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtModule; import org.matsim.contrib.dvrp.run.DvrpModule; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; -import org.matsim.contrib.otfvis.OTFVisLiveModule; import org.matsim.core.config.Config; import org.matsim.core.controler.Controler; import org.matsim.core.scenario.ScenarioUtils; /** - * @author Steffen Axer - * + * @author steffenaxer */ public final class DrtCompanionControlerCreator { public static Controler createControler(Config config) { MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing()); Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); diff --git a/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeDataArrayFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java similarity index 58% rename from matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeDataArrayFactory.java rename to contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java index db9b07a578c..bd3f4445f92 100644 --- a/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeDataArrayFactory.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionGroupIdentifier.java @@ -1,10 +1,9 @@ /* *********************************************************************** * * project: org.matsim.* - * TravelTimeDataArrayFactory.java * * * *********************************************************************** * * * - * copyright : (C) 2009 by the members listed in the COPYING, * + * copyright : (C) 2024 by the members listed in the COPYING, * * LICENSE and WARRANTY file. * * email : info at matsim dot org * * * @@ -18,25 +17,35 @@ * * * *********************************************************************** */ -package org.matsim.core.trafficmonitoring; +package org.matsim.contrib.drt.extension.companions; import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; +import org.matsim.core.mobsim.framework.MobsimPassengerAgent; -class TravelTimeDataArrayFactory implements TravelTimeDataFactory { +import java.util.Optional; - private final Network network; - private final int numSlots; - - public TravelTimeDataArrayFactory(final Network network, final int numSlots) { - this.network = network; - this.numSlots = numSlots; +/** + * @author steffenaxer + */ +class DrtCompanionGroupIdentifier implements PassengerGroupIdentifier { + private final Population population; + DrtCompanionGroupIdentifier(final Population population) + { + this.population = population; } - + @Override - public TravelTimeData createTravelTimeData(Id linkId) { - return new TravelTimeDataArray(this.network.getLinks().get(linkId), this.numSlots); + public Optional> getGroupId(MobsimPassengerAgent agent) { + Person person = wrapMobsimPassengerAgentToPerson(agent); + return DrtCompanionUtils.getPassengerGroupIdentifier(person); + } + + private Person wrapMobsimPassengerAgentToPerson(MobsimPassengerAgent agent) + { + return this.population.getPersons().get(agent.getId()); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java index f93d49b19a6..9c5cd9bf3f2 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionModule.java @@ -20,37 +20,47 @@ package org.matsim.contrib.drt.extension.companions; import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Population; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.core.router.MainModeIdentifier; + /** * This module samples additional drt rides on booked drt trips in order to * replicate a more realistic vehicle occupancy. * * @author Steffen Axer - * */ public class DrtCompanionModule extends AbstractDvrpModeModule { - DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup; + final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup; - public DrtCompanionModule(String mode, DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { + public DrtCompanionModule(final String mode, final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { super(mode); this.drtWithExtensionsConfigGroup = drtWithExtensionsConfigGroup; - } @Override public void install() { bindModal(DrtCompanionRideGenerator.class).toProvider( modalProvider(getter -> new DrtCompanionRideGenerator( - getMode(), // - getter.get(MainModeIdentifier.class), // - getter.get(Scenario.class), // - getter.getModal(Network.class), // - this.drtWithExtensionsConfigGroup))) - .asEagerSingleton(); + getMode(), // + getter.get(MainModeIdentifier.class), // + getter.getModal(FleetSpecification.class), // + getter.get(Scenario.class), // + this.drtWithExtensionsConfigGroup))) + .asEagerSingleton(); addControlerListenerBinding().to(modalKey(DrtCompanionRideGenerator.class)); + installOverridingQSimModule(new AbstractDvrpModeQSimModule(getMode()) { + @Override + protected void configureQSim() { + bindModal(PassengerGroupIdentifier.class).toProvider( + modalProvider(getter -> new DrtCompanionGroupIdentifier( + getter.get(Population.class)))); + } + }); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java index 3789be3449c..f3947244027 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionParams.java @@ -28,9 +28,7 @@ import org.matsim.core.utils.misc.StringUtils; /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class DrtCompanionParams extends ReflectiveConfigGroupWithConfigurableParameterSets { private static final char DEFAULT_COLLECTION_DELIMITER = ','; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java index 5ed8926f465..e7bfc82fa0a 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionRideGenerator.java @@ -25,18 +25,19 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.UUID; 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.Network; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.common.util.WeightedRandomSelection; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleSpecification; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.core.controler.events.AfterMobsimEvent; import org.matsim.core.controler.events.BeforeMobsimEvent; import org.matsim.core.controler.listener.AfterMobsimListener; @@ -46,28 +47,38 @@ import org.matsim.core.router.TripStructureUtils; import org.matsim.utils.objectattributes.attributable.AttributesUtils; +import static org.matsim.contrib.drt.extension.companions.DrtCompanionUtils.DRT_COMPANION_AGENT_PREFIX; + /** * @author Steffen Axer */ -public final class DrtCompanionRideGenerator implements BeforeMobsimListener, AfterMobsimListener { +final class DrtCompanionRideGenerator implements BeforeMobsimListener, AfterMobsimListener { private static final Logger LOG = LogManager.getLogger(DrtCompanionRideGenerator.class); - public final static String DRT_COMPANION_AGENT_PREFIX = "COMPANION"; public static final String DRT_COMPANION_TYPE = "drtCompanion"; - private final Scenario scenario; - private final String drtModes; + private final String drtMode; private final MainModeIdentifier mainModeIdentifier; + private final int maxCapacity; - private Set> companionAgentIds = new HashSet<>(); + private final Set> companionAgentIds = new HashSet<>(); private WeightedRandomSelection sampler; + private int passengerGroupIdentifier = 0; // Should be unique over the entire simulation + DrtCompanionRideGenerator(final String drtMode, final MainModeIdentifier mainModeIdentifier, - final Scenario scenario, final Network network, + final FleetSpecification fleet, + final Scenario scenario, final DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { this.scenario = scenario; this.mainModeIdentifier = mainModeIdentifier; - this.drtModes = drtMode; + this.drtMode = drtMode; + this.maxCapacity = fleet.getVehicleSpecifications() + .values() + .stream() + .mapToInt(DvrpVehicleSpecification::getCapacity) + .max() + .orElse(0);; installSampler(drtWithExtensionsConfigGroup); } @@ -77,53 +88,73 @@ private String getCompanionPrefix(String drtMode) { private void installSampler(DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup) { if (!drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow().getDrtCompanionSamplingWeights() - .isEmpty()) { + .isEmpty()) { this.sampler = DrtCompanionUtils.createIntegerSampler( - drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow() - .getDrtCompanionSamplingWeights()); + drtWithExtensionsConfigGroup.getDrtCompanionParams().orElseThrow() + .getDrtCompanionSamplingWeights()); } else { throw new IllegalStateException( - "drtCompanionSamplingWeights are empty, please check your DrtCompanionParams"); + "drtCompanionSamplingWeights are empty, please check your DrtCompanionParams"); } } - void addCompanionAgents() { - HashMap drtCompanionAgents = new HashMap<>(); + private Id getGroupIdentifier() + { + return Id.create(this.passengerGroupIdentifier, PassengerGroupIdentifier.PassengerGroup.class); + } + + private void addCompanionAgents() { + int personIdentifierSuffix = 0; + int drtCompanionAgents = 0; Collection companions = new ArrayList<>(); for (Person person : this.scenario.getPopulation().getPersons().values()) { for (TripStructureUtils.Trip trip : TripStructureUtils.getTrips(person.getSelectedPlan())) { String mainMode = mainModeIdentifier.identifyMainMode(trip.getTripElements()); - if (this.drtModes.equals(mainMode)) { - + if (this.drtMode.equals(mainMode)) { int additionalCompanions = sampler.select(); + // Initial person travels now in a group + DrtCompanionUtils.setPassengerGroupIdentifier(person, getGroupIdentifier()); + + int groupSize = additionalCompanions + 1; + int currentGroupSize = 1; // Initial person + + // Add companions for (int i = 0; i < additionalCompanions; i++) { - int currentCounter = drtCompanionAgents.getOrDefault(mainMode, 0); - currentCounter++; - drtCompanionAgents.put(mainMode, currentCounter); - int groupSize = additionalCompanions + 1; int groupPart = i; + // currentGroupSize+1 exceeds maxCapacity, create a new passengerGroupIdentifier + if(currentGroupSize+1>this.maxCapacity) + { + passengerGroupIdentifier++; + currentGroupSize=0; + } + + // Bypass passengerGroupIdentifierId to each group member companions.add(createCompanionAgent(mainMode, person, trip, trip.getOriginActivity(), - trip.getDestinationActivity(), groupPart, groupSize)); + trip.getDestinationActivity(), groupPart, groupSize, personIdentifierSuffix, getGroupIdentifier())); + personIdentifierSuffix++; + drtCompanionAgents++; + currentGroupSize++; } } } + passengerGroupIdentifier++; } companions.forEach(p -> { this.scenario.getPopulation().addPerson(p); this.companionAgentIds.add(p.getId()); }); - for (Map.Entry drtModeEntry : drtCompanionAgents.entrySet()) { - LOG.info("Added # {} drt companion agents for mode {}", drtModeEntry.getValue(), drtModeEntry.getKey()); - } + + LOG.info("Added # {} drt companion agents for mode {}", drtCompanionAgents, this.drtMode); + } private Person createCompanionAgent(String drtMode, Person originalPerson, TripStructureUtils.Trip trip, - Activity fromActivity, Activity toActivity, int groupPart, int groupSize) { + Activity fromActivity, Activity toActivity, int groupPart, int groupSize, int personIdentifier, Id passengerGroupIdentifierId) { String prefix = getCompanionPrefix(drtMode); - String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + UUID.randomUUID(); + String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + personIdentifier; Person person = PopulationUtils.getFactory().createPerson(Id.createPersonId(companionId)); DrtCompanionUtils.setDRTCompanionType(person, DRT_COMPANION_TYPE); @@ -146,11 +177,12 @@ private Person createCompanionAgent(String drtMode, Person originalPerson, TripS // Add group information to trip DrtCompanionUtils.setAdditionalGroupPart(person, groupPart); DrtCompanionUtils.setAdditionalGroupSize(person, groupSize); + DrtCompanionUtils.setPassengerGroupIdentifier(person, passengerGroupIdentifierId); return person; } - void removeCompanionAgents() { + private void removeCompanionAgents() { int counter = 0; for (Id drtCompanion : companionAgentIds) { diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java index 4f9d6e33317..e7ed6132025 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/DrtCompanionUtils.java @@ -20,21 +20,24 @@ package org.matsim.contrib.drt.extension.companions; import java.util.List; +import java.util.Optional; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.common.util.WeightedRandomSelection; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; import org.matsim.core.gbl.MatsimRandom; /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class DrtCompanionUtils { public final static String ADDITIONAL_GROUP_SIZE_ATTRIBUTE = "additionalGroupSize"; public final static String ADDITIONAL_GROUP_PART_ATTRIBUTE = "additionalGroupPart"; public static final String COMPANION_TYPE_ATTRIBUTE = "companionType"; + public static final String GROUP_IDENTIFIER_ATTRIBUTE = "groupIdentifier"; + public static final String DRT_COMPANION_AGENT_PREFIX = "COMPANION"; private DrtCompanionUtils() { throw new IllegalStateException("Utility class"); @@ -44,6 +47,10 @@ public static boolean isDrtCompanion(Person person) { return getDRTCompanionType(person) != null; } + public static boolean isDrtCompanion(Id personId) { + return personId.toString().startsWith(DRT_COMPANION_AGENT_PREFIX); + } + public static void setDRTCompanionType(Person person, String drtCompanionType) { if (drtCompanionType == null) { person.getAttributes().removeAttribute(COMPANION_TYPE_ATTRIBUTE); @@ -72,6 +79,15 @@ public static Integer getAdditionalGroupSize(Person person) { } } + public static Optional> getPassengerGroupIdentifier(Person person) { + if (person.getAttributes().getAttribute(GROUP_IDENTIFIER_ATTRIBUTE) == null) { + return Optional.empty(); + } else { + return Optional.of(Id.create(person.getAttributes() + .getAttribute(GROUP_IDENTIFIER_ATTRIBUTE).toString(), PassengerGroupIdentifier.PassengerGroup.class)); + } + } + public static Integer getAdditionalGroupPart(Person person) { if (person.getAttributes().getAttribute(ADDITIONAL_GROUP_PART_ATTRIBUTE) == null) { return null; @@ -88,4 +104,8 @@ public static void setAdditionalGroupPart(Person person, int additionalgroupPart person.getAttributes().putAttribute(ADDITIONAL_GROUP_PART_ATTRIBUTE, additionalgroupPart); } + public static void setPassengerGroupIdentifier(Person person, Id passengerGroupIdentifierId ) { + person.getAttributes().putAttribute(GROUP_IDENTIFIER_ATTRIBUTE, passengerGroupIdentifierId); + } + } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java index 2ca26b70f32..599636b04d6 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/companions/MultiModeDrtCompanionModule.java @@ -19,27 +19,22 @@ package org.matsim.contrib.drt.extension.companions; +import com.google.inject.Inject; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.core.controler.AbstractModule; -import com.google.inject.Inject; - /** - * - * @author Steffen Axer - * + * @author steffenaxer */ public class MultiModeDrtCompanionModule extends AbstractModule { - @Inject - private MultiModeDrtConfigGroup multiModeDrtCfg; - @Override public void install() { + MultiModeDrtConfigGroup multiModeDrtCfg = MultiModeDrtConfigGroup.get(getConfig()); for (DrtConfigGroup drtCfg : multiModeDrtCfg.getModalElements()) { - if (drtCfg instanceof DrtWithExtensionsConfigGroup && ((DrtWithExtensionsConfigGroup) drtCfg).getDrtCompanionParams().isPresent()) { - DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) drtCfg; + if (drtCfg instanceof DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup && ((DrtWithExtensionsConfigGroup) drtCfg).getDrtCompanionParams().isPresent()) { + drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) drtCfg; install(new DrtCompanionModule(drtCfg.getMode(), drtWithExtensionsConfigGroup)); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboardProvider.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboardProvider.java index 9760f3ec617..93e186e2474 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboardProvider.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboardProvider.java @@ -25,7 +25,7 @@ public List getDashboards(Config config, SimWrapper simWrapper) { for (DrtConfigGroup drtConfig : multiModeDrtConfigGroup.getModalElements()) { - result.add(new DrtDashboard(drtConfig, config.getContext(), config.global().getCoordinateSystem(), config.controler().getLastIteration())); + result.add(new DrtDashboard(drtConfig, config.getContext(), config.global().getCoordinateSystem(), config.controller().getLastIteration())); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/EDrtActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/EDrtActionCreator.java index dcd376f1cef..2e90569768c 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/EDrtActionCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/EDrtActionCreator.java @@ -19,10 +19,8 @@ package org.matsim.contrib.drt.extension.edrt; -import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; -import org.matsim.contrib.dvrp.passenger.PassengerHandler; -import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.schedule.DriveTask; import org.matsim.contrib.dvrp.schedule.Task; import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; @@ -33,7 +31,6 @@ import org.matsim.contrib.dvrp.vrpagent.VrpLeg; import org.matsim.contrib.dynagent.DynAction; import org.matsim.contrib.dynagent.DynAgent; -import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; import org.matsim.contrib.evrp.ChargingActivity; import org.matsim.contrib.evrp.ChargingTask; import org.matsim.contrib.evrp.EvDvrpVehicle; @@ -45,12 +42,12 @@ * @author michalm */ public class EDrtActionCreator implements VrpAgentLogic.DynActionCreator { - private final DrtActionCreator drtActionCreator; + private final VrpAgentLogic.DynActionCreator delegate; private final MobsimTimer timer; - public EDrtActionCreator(PassengerHandler passengerHandler, MobsimTimer timer, DvrpConfigGroup dvrpCfg) { + public EDrtActionCreator(VrpAgentLogic.DynActionCreator delegate, MobsimTimer timer) { this.timer = timer; - drtActionCreator = new DrtActionCreator(passengerHandler, v -> createLeg(dvrpCfg.mobsimMode, v, timer)); + this.delegate = delegate; } @Override @@ -60,7 +57,7 @@ public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle)vehicle, timer)); return new ChargingActivity((ChargingTask)task); } else { - DynAction dynAction = drtActionCreator.createAction(dynAgent, vehicle, now); + DynAction dynAction = delegate.createAction(dynAgent, vehicle, now); if (task.getTaskTracker() == null) { task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle)vehicle, timer)); } @@ -68,7 +65,7 @@ public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now } } - private static VrpLeg createLeg(String mobsimMode, DvrpVehicle vehicle, MobsimTimer timer) { + public static VrpLeg createLeg(String mobsimMode, DvrpVehicle vehicle, MobsimTimer timer) { DriveTask driveTask = (DriveTask)vehicle.getSchedule().getCurrentTask(); VrpLeg leg = new VrpLeg(mobsimMode, driveTask.getPath()); OnlineDriveTaskTracker onlineTracker = new OnlineDriveTaskTrackerImpl(vehicle, leg, diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/optimizer/EDrtVehicleDataEntryFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/optimizer/EDrtVehicleDataEntryFactory.java index 7174f562e15..76d84a09e32 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/optimizer/EDrtVehicleDataEntryFactory.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/optimizer/EDrtVehicleDataEntryFactory.java @@ -20,19 +20,18 @@ import java.util.List; -import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; import org.matsim.contrib.drt.optimizer.VehicleDataEntryFactoryImpl; -import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.schedule.Schedule; import org.matsim.contrib.dvrp.schedule.Schedule.ScheduleStatus; import org.matsim.contrib.dvrp.schedule.Task; import org.matsim.contrib.dvrp.schedule.Task.TaskStatus; -import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; +import org.matsim.contrib.ev.fleet.Battery; import org.matsim.contrib.evrp.ETask; import org.matsim.contrib.evrp.EvDvrpVehicle; import org.matsim.contrib.evrp.tracker.ETaskTracker; -import org.matsim.contrib.ev.fleet.Battery; import com.google.inject.Provider; @@ -52,17 +51,13 @@ public EVehicleEntry(VehicleEntry entry, double socBeforeFinalStay) { private final double minimumRelativeSoc; private final VehicleDataEntryFactoryImpl entryFactory; - public EDrtVehicleDataEntryFactory(DrtConfigGroup drtCfg, double minimumRelativeSoc) { + public EDrtVehicleDataEntryFactory(double minimumRelativeSoc) { this.minimumRelativeSoc = minimumRelativeSoc; - entryFactory = new VehicleDataEntryFactoryImpl(drtCfg); + entryFactory = new VehicleDataEntryFactoryImpl(); } @Override public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { - if (entryFactory.isNotEligibleForRequestInsertion(vehicle, currentTime)) { - return null; - } - Schedule schedule = vehicle.getSchedule(); int taskCount = schedule.getTaskCount(); if (taskCount > 1) { @@ -76,16 +71,23 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { Battery battery = ((EvDvrpVehicle)vehicle).getElectricVehicle().getBattery(); int nextTaskIdx; double chargeBeforeNextTask; - if (schedule.getStatus() == ScheduleStatus.PLANNED) { - nextTaskIdx = 0; - chargeBeforeNextTask = battery.getCharge(); - } else { // STARTED - Task currentTask = schedule.getCurrentTask(); - ETaskTracker eTracker = (ETaskTracker)currentTask.getTaskTracker(); - chargeBeforeNextTask = eTracker.predictChargeAtEnd(); - nextTaskIdx = currentTask.getTaskIdx() + 1; + + switch (schedule.getStatus()) { + case PLANNED: + nextTaskIdx = 0; + chargeBeforeNextTask = battery.getCharge(); + break; + case STARTED: + Task currentTask = schedule.getCurrentTask(); + ETaskTracker eTracker = (ETaskTracker) currentTask.getTaskTracker(); + chargeBeforeNextTask = eTracker.predictChargeAtEnd(); + nextTaskIdx = currentTask.getTaskIdx() + 1; + break; + default: + return null; } + List tasks = schedule.getTasks(); for (int i = nextTaskIdx; i < tasks.size() - 1; i++) { chargeBeforeNextTask -= ((ETask)tasks.get(i)).getTotalEnergy(); @@ -100,17 +102,15 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { } public static class EDrtVehicleDataEntryFactoryProvider implements Provider { - private final DrtConfigGroup drtCfg; private final double minimumRelativeSoc; - public EDrtVehicleDataEntryFactoryProvider(DrtConfigGroup drtCfg, double minimumRelativeSoc) { - this.drtCfg = drtCfg; + public EDrtVehicleDataEntryFactoryProvider(double minimumRelativeSoc) { this.minimumRelativeSoc = minimumRelativeSoc; } @Override public EDrtVehicleDataEntryFactory get() { - return new EDrtVehicleDataEntryFactory(drtCfg, minimumRelativeSoc); + return new EDrtVehicleDataEntryFactory(minimumRelativeSoc); } } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java index 638180019a7..8471438ebe4 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java @@ -42,7 +42,7 @@ public class EDrtControlerCreator { public static Controler createControler(Config config, boolean otfvis) { MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing()); Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java index 6239ca5a240..71ee5abe1c1 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java @@ -44,23 +44,26 @@ import org.matsim.contrib.drt.optimizer.insertion.UnplannedRequestInserter; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; import org.matsim.contrib.drt.passenger.DrtOfferAcceptor; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtTaskFactory; import org.matsim.contrib.drt.scheduler.DefaultRequestInsertionScheduler; import org.matsim.contrib.drt.scheduler.DrtScheduleInquiry; import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; import org.matsim.contrib.drt.stops.StopTimeCalculator; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; -import org.matsim.contrib.dvrp.passenger.PassengerHandler; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModes; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure; -import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures; +import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.modal.ModalProviders; @@ -69,6 +72,7 @@ import org.matsim.core.router.util.TravelTime; import com.google.inject.Inject; +import com.google.inject.Singleton; /** * @author Michal Maciejewski (michalm) @@ -88,15 +92,17 @@ protected void configureQSim() { getter.getModal(EmptyVehicleChargingScheduler.class)))); bindModal(DefaultDrtOptimizer.class).toProvider(modalProvider( - getter -> new DefaultDrtOptimizer(drtCfg, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), + getter -> { + return new DefaultDrtOptimizer(drtCfg, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), getter.getModal(DepotFinder.class), getter.getModal(RebalancingStrategy.class), getter.getModal(DrtScheduleInquiry.class), getter.getModal(ScheduleTimingUpdater.class), getter.getModal(EmptyVehicleRelocator.class), getter.getModal(UnplannedRequestInserter.class), - getter.getModal(DrtRequestInsertionRetryQueue.class)))).asEagerSingleton(); + getter.getModal(DrtRequestInsertionRetryQueue.class)); + })).asEagerSingleton(); bindModal(ChargingInfrastructure.class).toProvider(modalProvider( - getter -> ChargingInfrastructures.createModalNetworkChargers(getter.get(ChargingInfrastructure.class), - getter.getModal(Network.class), getMode()))).asEagerSingleton(); + getter -> ChargingInfrastructureUtils.createModalNetworkChargers(getter.get(ChargingInfrastructure.class ), + getter.getModal(Network.class), getMode() ))).asEagerSingleton(); // XXX if overridden to something else, make sure that the depots are equipped with chargers // otherwise vehicles will not re-charge @@ -129,7 +135,8 @@ public EmptyVehicleChargingScheduler get() { getter.getModal(RequestInsertionScheduler.class), getter.getModal(VehicleEntry.EntryFactory.class), getter.getModal(DrtInsertionSearch.class), getter.getModal(DrtRequestInsertionRetryQueue.class), getter.getModal(DrtOfferAcceptor.class), - getter.getModal(QSimScopeForkJoinPoolHolder.class).getPool()))).asEagerSingleton(); + getter.getModal(QSimScopeForkJoinPoolHolder.class).getPool(), + getter.getModal(PassengerStopDurationProvider.class)))).asEagerSingleton(); bindModal(InsertionCostCalculator.class).toProvider(modalProvider( getter -> new DefaultInsertionCostCalculator(getter.getModal(CostCalculationStrategy.class)))); @@ -163,11 +170,12 @@ public EmptyVehicleRelocator get() { bindModal(DrtScheduleInquiry.class).to(DrtScheduleInquiry.class).asEagerSingleton(); + boolean scheduleWaitBeforeDrive = drtCfg.getPrebookingParams().map(p -> p.scheduleWaitBeforeDrive).orElse(false); bindModal(RequestInsertionScheduler.class).toProvider(modalProvider( getter -> new DefaultRequestInsertionScheduler(getter.getModal(Fleet.class), getter.get(MobsimTimer.class), getter.getModal(TravelTime.class), getter.getModal(ScheduleTimingUpdater.class), getter.getModal(DrtTaskFactory.class), - getter.getModal(StopTimeCalculator.class)))) + getter.getModal(StopTimeCalculator.class), scheduleWaitBeforeDrive))) .asEagerSingleton(); bindModal(DrtOfferAcceptor.class).toInstance(DrtOfferAcceptor.DEFAULT_ACCEPTOR); @@ -176,10 +184,26 @@ public EmptyVehicleRelocator get() { getter -> new ScheduleTimingUpdater(getter.get(MobsimTimer.class), new EDrtStayTaskEndTimeCalculator(getter.getModal(StopTimeCalculator.class))))).asEagerSingleton(); - bindModal(VrpAgentLogic.DynActionCreator.class).toProvider(modalProvider( - getter -> new EDrtActionCreator(getter.getModal(PassengerHandler.class), getter.get(MobsimTimer.class), - getter.get(DvrpConfigGroup.class)))).asEagerSingleton(); - + bindModal(VrpLegFactory.class).toProvider(modalProvider(getter -> { + DvrpConfigGroup dvrpCfg = getter.get(DvrpConfigGroup.class); + MobsimTimer timer = getter.get(MobsimTimer.class); + + // Makes basic DrtActionCreator create legs with consumption tracker + return v -> EDrtActionCreator.createLeg(dvrpCfg.mobsimMode, v, timer); + })).in(Singleton.class); + + bindModal(EDrtActionCreator.class).toProvider(modalProvider(getter -> { + VrpAgentLogic.DynActionCreator delegate = drtCfg.getPrebookingParams().isPresent() + ? getter.getModal(PrebookingActionCreator.class) + : getter.getModal(DrtActionCreator.class); + + // EDrtActionCreator wraps around delegate and initializes consumption trackers + // + adds ChargingActivity + return new EDrtActionCreator(delegate, getter.get(MobsimTimer.class)); + })).asEagerSingleton(); + + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(EDrtActionCreator.class)); + bindModal(VrpOptimizer.class).to(modalKey(DrtOptimizer.class)); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenario.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenario.java index 741a03e52b2..741c4047786 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenario.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenario.java @@ -54,14 +54,14 @@ public static void run(URL configUrl, boolean otfvis) { new OTFVisConfigGroup(), new EvConfigGroup()), otfvis); } - public static void run(Config config, boolean otfvis) { + public static Controler createControler(Config config, boolean otfvis) { Controler controler = EDrtControlerCreator.createControler(config, otfvis); for (DrtConfigGroup drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) { controler.addOverridingModule(new AbstractDvrpModeModule(drtCfg.getMode()) { @Override public void install() { bind(EDrtVehicleDataEntryFactoryProvider.class).toInstance( - new EDrtVehicleDataEntryFactoryProvider(drtCfg, MIN_RELATIVE_SOC)); + new EDrtVehicleDataEntryFactoryProvider(MIN_RELATIVE_SOC)); } }); } @@ -75,6 +75,11 @@ public void install() { bind(TemperatureService.class).toInstance(linkId -> TEMPERATURE); } }); - controler.run(); + + return controler; + } + + public static void run(Config config, boolean otfvis) { + createControler(config, otfvis).run(); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/schedule/EDrtTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/schedule/EDrtTaskFactoryImpl.java index 736355552db..4ec83dc7a15 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/schedule/EDrtTaskFactoryImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/schedule/EDrtTaskFactoryImpl.java @@ -23,6 +23,7 @@ import org.matsim.contrib.drt.schedule.DrtTaskType; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; import org.matsim.contrib.evrp.EvDvrpVehicle; import org.matsim.contrib.evrp.VrpPathEnergyConsumptions; import org.matsim.contrib.ev.fleet.ElectricVehicle; @@ -52,6 +53,11 @@ public EDrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double return new EDrtStayTask(beginTime, endTime, link, 0);// no energy consumption during STAY } + @Override + public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return createStayTask(vehicle, beginTime, endTime, link); + } + public EDrtChargingTask createChargingTask(DvrpVehicle vehicle, double beginTime, double endTime, Charger charger, double totalEnergy) { return new EDrtChargingTask(beginTime, endTime, charger, ((EvDvrpVehicle)vehicle).getElectricVehicle(), diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/scheduler/EmptyVehicleChargingScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/scheduler/EmptyVehicleChargingScheduler.java index f50d437a1a0..eea29745e80 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/scheduler/EmptyVehicleChargingScheduler.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/scheduler/EmptyVehicleChargingScheduler.java @@ -21,20 +21,23 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; import org.matsim.contrib.drt.schedule.DrtStayTask; import org.matsim.contrib.drt.schedule.DrtTaskFactory; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.schedule.Schedule; -import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; import org.matsim.contrib.ev.charging.ChargingStrategy; import org.matsim.contrib.ev.charging.ChargingWithAssignmentLogic; -import org.matsim.contrib.evrp.EvDvrpVehicle; import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.contrib.ev.infrastructure.Charger; import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure; +import org.matsim.contrib.evrp.EvDvrpVehicle; import org.matsim.core.mobsim.framework.MobsimTimer; +import java.util.Comparator; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -43,23 +46,27 @@ public class EmptyVehicleChargingScheduler { private final MobsimTimer timer; private final EDrtTaskFactoryImpl taskFactory; - private final Map, Charger> linkToChargerMap; + private final Map, List> linkToChargersMap; public EmptyVehicleChargingScheduler(MobsimTimer timer, DrtTaskFactory taskFactory, ChargingInfrastructure chargingInfrastructure) { this.timer = timer; this.taskFactory = (EDrtTaskFactoryImpl)taskFactory; - linkToChargerMap = chargingInfrastructure.getChargers() + linkToChargersMap = chargingInfrastructure.getChargers() .values() .stream() - .collect(Collectors.toMap(c -> c.getLink().getId(), c -> c)); + .collect(Collectors.groupingBy(c -> c.getLink().getId())); } public void chargeVehicle(DvrpVehicle vehicle) { DrtStayTask currentTask = (DrtStayTask)vehicle.getSchedule().getCurrentTask(); Link currentLink = currentTask.getLink(); - Charger charger = linkToChargerMap.get(currentLink.getId()); - if (charger != null) { + List chargers = linkToChargersMap.get(currentLink.getId()); + if (chargers != null) { + Optional freeCharger = chargers.stream().filter(c -> c.getLogic().getPluggedVehicles().isEmpty()).findFirst(); + + // Empty charger or at least smallest queue charger + Charger charger = freeCharger.orElseGet(() -> chargers.stream().min(Comparator.comparingInt(e -> e.getLogic().getQueuedVehicles().size())).orElseThrow()); ElectricVehicle ev = ((EvDvrpVehicle)vehicle).getElectricVehicle(); if (!charger.getLogic().getChargingStrategy().isChargingCompleted(ev)) { chargeVehicleImpl(vehicle, charger); @@ -67,6 +74,8 @@ public void chargeVehicle(DvrpVehicle vehicle) { } } + + private void chargeVehicleImpl(DvrpVehicle vehicle, Charger charger) { Schedule schedule = vehicle.getSchedule(); DrtStayTask stayTask = (DrtStayTask)schedule.getCurrentTask(); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java new file mode 100644 index 00000000000..d095a0037bd --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java @@ -0,0 +1,132 @@ +package org.matsim.contrib.drt.extension.estimator; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; +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.events.PersonMoneyEvent; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.core.controler.events.AfterMobsimEvent; +import org.matsim.core.controler.events.ShutdownEvent; +import org.matsim.core.controler.events.StartupEvent; +import org.matsim.core.controler.listener.AfterMobsimListener; +import org.matsim.core.controler.listener.ShutdownListener; +import org.matsim.core.controler.listener.StartupListener; +import org.matsim.core.utils.misc.OptionalTime; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + +/** + * Analyzes and outputs drt estimates errors metrics based on daily requests. + */ +public final class DrtEstimateAnalyzer implements StartupListener, ShutdownListener, AfterMobsimListener { + + private static final Logger log = LogManager.getLogger(DrtEstimateAnalyzer.class); + + // Might be useful but not needed currently + //private final DefaultMainLegRouter.RouteCreator creator; + private final DrtEstimator estimator; + private final DrtEventSequenceCollector collector; + private final DrtEstimatorConfigGroup config; + + private CSVPrinter csv; + + public DrtEstimateAnalyzer(DrtEstimator estimator, DrtEventSequenceCollector collector, DrtEstimatorConfigGroup config) { + this.estimator = estimator; + this.collector = collector; + this.config = config; + } + + @Override + public void notifyStartup(StartupEvent event) { + + String filename = event.getServices().getControlerIO().getOutputFilename("drt_estimates_" + config.getMode() + ".csv"); + + try { + csv = new CSVPrinter(Files.newBufferedWriter(Path.of(filename), StandardCharsets.UTF_8), CSVFormat.DEFAULT); + csv.printRecord("iteration", + "wait_time_mae", "wait_time_err_q5", "wait_time_err_q50", "wait_time_err_q95", + "travel_time_mae", "travel_time_err_q5", "travel_time_err_q50", "travel_time_err_q95", + "fare_mae", "fare_err_q5", "fare_err_q50", "fare_err_q95" + ); + + } catch (IOException e) { + throw new UncheckedIOException("Could not open output file for estimates.", e); + } + } + + @Override + public void notifyShutdown(ShutdownEvent event) { + try { + csv.close(); + } catch (IOException e) { + log.warn("Could not close drt estimate file", e); + } + } + + /** + * Needs to run before any estimators updates. + */ + @Override + public void notifyAfterMobsim(AfterMobsimEvent event) { + + try { + csv.printRecord(calcMetrics(event.getIteration())); + csv.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Return row of metrics for the csv file. + */ + private Iterable calcMetrics(int iteration) { + + DescriptiveStatistics waitTime = new DescriptiveStatistics(); + DescriptiveStatistics travelTime = new DescriptiveStatistics(); + DescriptiveStatistics fare = new DescriptiveStatistics(); + + for (DrtEventSequenceCollector.EventSequence seq : collector.getPerformedRequestSequences().values()) { + Map, DrtEventSequenceCollector.EventSequence.PersonEvents> personEvents = seq.getPersonEvents(); + for (Map.Entry, DrtEventSequenceCollector.EventSequence.PersonEvents> entry : personEvents.entrySet()) { + if (entry.getValue().getPickedUp().isPresent() && entry.getValue().getDroppedOff().isPresent()) { + + // many attributes are not filled, when using the constructor + DrtRoute route = new DrtRoute(seq.getSubmitted().getFromLinkId(), seq.getSubmitted().getToLinkId()); + route.setDirectRideTime(seq.getSubmitted().getUnsharedRideTime()); + route.setDistance(seq.getSubmitted().getUnsharedRideDistance()); + + double valWaitTime = entry.getValue().getPickedUp().get().getTime() - seq.getSubmitted().getTime(); + double valTravelTime = entry.getValue().getDroppedOff().get().getTime() - entry.getValue().getPickedUp().get().getTime(); + double valFare = seq.getDrtFares().stream().mapToDouble(PersonMoneyEvent::getAmount).sum(); + + DrtEstimator.Estimate estimate = estimator.estimate(route, OptionalTime.defined(seq.getSubmitted().getTime())); + + waitTime.addValue(Math.abs(estimate.waitingTime() - valWaitTime)); + travelTime.addValue(Math.abs(estimate.travelTime() - valTravelTime)); + fare.addValue(Math.abs(estimate.fare() - valFare)); + } + } + } + + return List.of( + iteration, + waitTime.getMean(), waitTime.getPercentile(5), waitTime.getPercentile(50), waitTime.getPercentile(95), + travelTime.getMean(), travelTime.getPercentile(5), travelTime.getPercentile(50), travelTime.getPercentile(95), + fare.getMean(), fare.getPercentile(5), fare.getPercentile(50), fare.getPercentile(95) + ); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java new file mode 100644 index 00000000000..fef209ed211 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java @@ -0,0 +1,35 @@ +package org.matsim.contrib.drt.extension.estimator; + +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.core.controler.listener.ControlerListener; +import org.matsim.core.utils.misc.OptionalTime; + +/** + * Interface to estimate a DRT service's detour, waiting time and costs. + */ +public interface DrtEstimator extends ControlerListener { + + /** + * Provide an estimate for a drt route with specific pickup and dropoff point. + * + * @param route drt route + * @param departureTime estimated departure time + * @return An {@link Estimate} instance + */ + Estimate estimate(DrtRoute route, OptionalTime departureTime); + + + /** + * Estimate for various attributes for a drt trip. + * + * @param distance travel distance in meter + * @param travelTime travel time in seconds + * @param waitingTime waiting time in seconds + * @param fare money, which is negative if the customer needs to pay it + * @param rejectionRate probability of a trip being rejected + */ + record Estimate(double distance, double travelTime, double waitingTime, double fare, double rejectionRate) { + + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtInitialEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtInitialEstimator.java new file mode 100644 index 00000000000..a826a936e46 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtInitialEstimator.java @@ -0,0 +1,9 @@ +package org.matsim.contrib.drt.extension.estimator; + +/** + * This interface is used to provide an initial estimate for the drt service. + * Supposed to be used when no data is available from the simulation yet. + * The interface is exactly the same as {@link DrtEstimator}, but this class won't be called with update events. + */ +public interface DrtInitialEstimator extends DrtEstimator { +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java new file mode 100644 index 00000000000..db6168ac2e1 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java @@ -0,0 +1,58 @@ +package org.matsim.contrib.drt.extension.estimator; + +import com.google.inject.Inject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.dvrp.run.DvrpMode; +import org.matsim.core.scoring.functions.ModeUtilityParameters; +import org.matsim.core.utils.misc.OptionalTime; +import org.matsim.modechoice.EstimatorContext; +import org.matsim.modechoice.ModeAvailability; +import org.matsim.modechoice.estimators.LegEstimator; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + + +/** + * Aggregate class for informed-mode-choice that makes sure to invoke the correct estimator for each drt mode. + */ +public class MultiModalDrtLegEstimator implements LegEstimator { + + private static final Logger log = LogManager.getLogger(MultiModalDrtLegEstimator.class); + + protected final Map estimators = new HashMap<>(); + + @Inject + public MultiModalDrtLegEstimator(Map estimators) { + for (Map.Entry e : estimators.entrySet()) { + this.estimators.put(e.getKey().value(), e.getValue()); + } + } + + @Override + public double estimate(EstimatorContext context, String mode, Leg leg, ModeAvailability option) { + + if (!(leg.getRoute() instanceof DrtRoute route)) + throw new IllegalStateException("Drt leg routes must be of type DrtRoute."); + + OptionalTime departureTime = leg.getDepartureTime(); + + DrtEstimator estimator = Objects.requireNonNull(estimators.get(mode), String.format("No drt estimator found for mode %s. Check log for errors.", mode)); + + DrtEstimator.Estimate est = estimator.estimate(route, departureTime); + ModeUtilityParameters params = context.scoring.modeParams.get(mode); + + // By default, waiting time is scored as travel time + return params.constant + + params.marginalUtilityOfDistance_m * est.distance() + + params.marginalUtilityOfTraveling_s * est.travelTime() + + params.marginalUtilityOfTraveling_s * est.waitingTime() + + context.scoring.marginalUtilityOfMoney * params.monetaryDistanceCostRate * est.distance() + + context.scoring.marginalUtilityOfMoney * est.fare(); + + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/BasicDrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/BasicDrtEstimator.java new file mode 100644 index 00000000000..f1fd6f04c8f --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/BasicDrtEstimator.java @@ -0,0 +1,165 @@ +package org.matsim.contrib.drt.extension.estimator.impl; + +import org.apache.commons.math3.stat.descriptive.SummaryStatistics; +import org.apache.commons.math3.stat.regression.RegressionResults; +import org.apache.commons.math3.stat.regression.SimpleRegression; +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.events.PersonMoneyEvent; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; +import org.matsim.contrib.drt.extension.estimator.DrtEstimator; +import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.speedup.DrtSpeedUp; +import org.matsim.core.controler.events.IterationEndsEvent; +import org.matsim.core.controler.listener.IterationEndsListener; +import org.matsim.core.utils.misc.OptionalTime; + +import java.util.Map; +import java.util.SplittableRandom; + +/** + * Estimates drt trips based only daily averages. No spatial or temporal differentiation is taken into account for the estimate. + * This estimator is suited for small scenarios with few vehicles and trips and consequently few data points. + */ +public class BasicDrtEstimator implements DrtEstimator, IterationEndsListener { + + private static final Logger log = LogManager.getLogger(BasicDrtEstimator.class); + + private final DrtEventSequenceCollector collector; + private final DrtEstimatorConfigGroup config; + private final DrtConfigGroup drtConfig; + private final DrtInitialEstimator initial; + + private final SplittableRandom rnd = new SplittableRandom(); + /** + * Currently valid estimates. + */ + private GlobalEstimate currentEst; + private RegressionResults fare; + + public BasicDrtEstimator(DrtEventSequenceCollector collector, DrtInitialEstimator initial, + DrtEstimatorConfigGroup config, DrtConfigGroup drtConfig) { + //zones = injector.getModal(DrtZonalSystem.class); + this.collector = collector; + this.initial = initial; + this.config = config; + this.drtConfig = drtConfig; + } + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + + // Speed-up iteration need to be ignored for the estimates + if (drtConfig.getDrtSpeedUpParams().isPresent() && + DrtSpeedUp.isTeleportDrtUsers(drtConfig.getDrtSpeedUpParams().get(), + event.getServices().getConfig().controller(), event.getIteration())) { + return; + } + + GlobalEstimate est = new GlobalEstimate(); + + int n = 0; + + int nRejections = collector.getRejectedRequestSequences().size(); + int nSubmitted = collector.getRequestSubmissions().size(); + + for (DrtEventSequenceCollector.EventSequence seq : collector.getPerformedRequestSequences().values()) { + + Map, DrtEventSequenceCollector.EventSequence.PersonEvents> personEvents = seq.getPersonEvents(); + for (Map.Entry, DrtEventSequenceCollector.EventSequence.PersonEvents> entry : personEvents.entrySet()) { + if (entry.getValue().getPickedUp().isPresent() && entry.getValue().getDroppedOff().isPresent()) { + double waitTime = entry.getValue().getPickedUp().get().getTime() - seq.getSubmitted().getTime(); + est.waitTime.addValue(waitTime); + + double unsharedTime = seq.getSubmitted().getUnsharedRideTime(); + double travelTime = entry.getValue().getDroppedOff().get().getTime() - entry.getValue().getPickedUp().get().getTime(); + + est.detour.addValue(travelTime / unsharedTime); + + double fare = seq.getDrtFares().stream().mapToDouble(PersonMoneyEvent::getAmount).sum(); + est.fare.addData(seq.getSubmitted().getUnsharedRideDistance(), fare); + n++; + } + } + } + + // At least some data points are required + if (n <= 3) + return; + + fare = est.fare.regress(); + + double rejectionRate = (double) nRejections / nSubmitted; + + if (currentEst == null) { + est.meanWait = est.waitTime.getMean(); + est.stdWait = est.waitTime.getStandardDeviation(); + est.meanDetour = est.detour.getMean(); + est.stdDetour = est.detour.getStandardDeviation(); + est.rejectionRate = rejectionRate; + } else { + est.meanWait = config.decayFactor * est.waitTime.getMean() + (1 - config.decayFactor) * currentEst.waitTime.getMean(); + est.stdWait = config.decayFactor * est.waitTime.getStandardDeviation() + (1 - config.decayFactor) * currentEst.waitTime.getStandardDeviation(); + est.meanDetour = config.decayFactor * est.detour.getMean() + (1 - config.decayFactor) * currentEst.detour.getMean(); + est.stdDetour = config.decayFactor * est.detour.getStandardDeviation() + (1 - config.decayFactor) * currentEst.detour.getStandardDeviation(); + est.rejectionRate = config.decayFactor * rejectionRate + (1 - config.decayFactor) * currentEst.rejectionRate; + } + + log.info("Calculated {}", est); + currentEst = est; + } + + @Override + public Estimate estimate(DrtRoute route, OptionalTime departureTime) { + + if (currentEst == null) { + // Same interface, just different binding + return initial.estimate(route, departureTime); + } + + double fare = 0; + if (this.fare != null) + fare = this.fare.getParameterEstimate(0) + this.fare.getParameterEstimate(1) * route.getDistance(); + + if (drtConfig.getDrtFareParams().isPresent()) { + fare = Math.max(fare, drtConfig.getDrtFareParams().get().minFarePerTrip); + } + + double detour = Math.max(1, rnd.nextGaussian(currentEst.meanDetour, config.randomization * currentEst.stdDetour)); + double waitTime = Math.max(0, rnd.nextGaussian(currentEst.meanWait, config.randomization * currentEst.stdWait)); + + return new Estimate(route.getDistance() * detour, route.getDirectRideTime() * detour, waitTime, fare, currentEst.rejectionRate); + } + + /** + * Helper class to hold statistics. + */ + private static final class GlobalEstimate { + + private final SummaryStatistics waitTime = new SummaryStatistics(); + private final SummaryStatistics detour = new SummaryStatistics(); + private final SimpleRegression fare = new SimpleRegression(true); + + private double meanWait; + private double stdWait; + private double meanDetour; + private double stdDetour; + private double rejectionRate; + + @Override + public String toString() { + return "GlobalEstimate{" + + "meanWait=" + meanWait + + ", stdWait=" + stdWait + + ", meanDetour=" + meanDetour + + ", stdDetour=" + stdDetour + + ", rejectionRate=" + rejectionRate + + '}'; + } + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/ConstantDrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/ConstantDrtEstimator.java new file mode 100644 index 00000000000..d9a4d4be46f --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/ConstantDrtEstimator.java @@ -0,0 +1,50 @@ +package org.matsim.contrib.drt.extension.estimator.impl; + +import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator; +import org.matsim.contrib.drt.fare.DrtFareParams; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.core.utils.misc.OptionalTime; + +/** + * Estimates using a constant detour factor and waiting time. + */ +public class ConstantDrtEstimator implements DrtInitialEstimator { + + private final DrtConfigGroup drtConfig; + + /** + * Detour factor for the estimate. 1.0 means no detour, 2.0 means twice the distance. + */ + private final double detourFactor; + + /** + * Constant waiting time estimate in seconds. + */ + private final double waitingTime; + + public ConstantDrtEstimator(DrtConfigGroup drtConfig, double detourFactor, double waitingTime) { + this.drtConfig = drtConfig; + this.detourFactor = detourFactor; + this.waitingTime = waitingTime; + } + + @Override + public Estimate estimate(DrtRoute route, OptionalTime departureTime) { + + double distance = route.getDistance() * detourFactor; + double travelTime = route.getDirectRideTime() * detourFactor; + + double fare = 0; + if (drtConfig.getDrtFareParams().isPresent()) { + DrtFareParams fareParams = drtConfig.getDrtFareParams().get(); + fare = fareParams.distanceFare_m * distance + + fareParams.timeFare_h * travelTime / 3600.0 + + fareParams.baseFare; + + fare = Math.max(fare, fareParams.minFarePerTrip); + } + + return new Estimate(distance, travelTime, waitingTime, fare, 0); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/PessimisticDrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/PessimisticDrtEstimator.java new file mode 100644 index 00000000000..d26a318c635 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/impl/PessimisticDrtEstimator.java @@ -0,0 +1,40 @@ +package org.matsim.contrib.drt.extension.estimator.impl; + +import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator; +import org.matsim.contrib.drt.fare.DrtFareParams; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.core.utils.misc.OptionalTime; + +/** + * Uses the upper bounds from config for the initial estimate. + */ +public class PessimisticDrtEstimator implements DrtInitialEstimator { + private final DrtConfigGroup drtConfig; + + public PessimisticDrtEstimator(DrtConfigGroup drtConfig) { + this.drtConfig = drtConfig; + } + + @Override + public Estimate estimate(DrtRoute route, OptionalTime departureTime) { + // If not estimates are present, use travel time alpha as detour + // beta is not used, because estimates are supposed to be minimums and not worst cases + double travelTime = Math.min(route.getDirectRideTime() + drtConfig.maxAbsoluteDetour, + route.getDirectRideTime() * drtConfig.maxTravelTimeAlpha); + + double fare = 0; + if (drtConfig.getDrtFareParams().isPresent()) { + DrtFareParams fareParams = drtConfig.getDrtFareParams().get(); + fare = fareParams.distanceFare_m * route.getDistance() + + fareParams.timeFare_h * route.getDirectRideTime() / 3600.0 + + fareParams.baseFare; + + fare = Math.max(fare, fareParams.minFarePerTrip); + } + + // for distance, also use the max travel time alpha + return new Estimate(route.getDistance() * drtConfig.maxTravelTimeAlpha, travelTime, drtConfig.maxWaitTime, fare, 0); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java new file mode 100644 index 00000000000..985435bcfc3 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java @@ -0,0 +1,74 @@ +package org.matsim.contrib.drt.extension.estimator.run; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.PositiveOrZero; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.contrib.dvrp.run.Modal; +import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; + +public class DrtEstimatorConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets implements Modal { + + /** + * Type of estimator, which will be installed in {@link DrtEstimatorModule}. + */ + public enum EstimatorType { + BASIC, + + /** + * Will use the bound initial estimator, without any updates. + */ + INITIAL, + + /** + * Custom estimator, that needs to provided via binding. + */ + CUSTOM + } + + public static final String GROUP_NAME = "drtEstimator"; + + public DrtEstimatorConfigGroup() { + super(GROUP_NAME); + } + + public DrtEstimatorConfigGroup(String mode) { + super(GROUP_NAME); + this.mode = mode; + } + + @Parameter + @Comment("Mode of the drt service to estimate.") + @NotBlank + public String mode = TransportMode.drt; + + @Parameter + @Comment("Estimator typed to be used. In case of 'CUSTOM', guice bindings needs to be provided.") + @NotNull + public EstimatorType estimator = EstimatorType.BASIC; + + @Parameter + @Comment("Decay of the exponential moving average.") + @Positive + public double decayFactor = 0.7; + + @Parameter + @Comment("Factor multiplied with standard deviation to randomize estimates.") + @PositiveOrZero + public double randomization = 0.1; + + @Override + public String getMode() { + return mode; + } + + /** + * Set estimator type and return same instance. + */ + public DrtEstimatorConfigGroup withEstimator(EstimatorType estimator) { + this.estimator = estimator; + return this; + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java new file mode 100644 index 00000000000..c5a8ed00e7c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java @@ -0,0 +1,119 @@ +package org.matsim.contrib.drt.extension.estimator.run; + +import com.google.inject.Singleton; +import com.google.inject.multibindings.MapBinder; +import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; +import org.matsim.contrib.drt.extension.estimator.DrtEstimateAnalyzer; +import org.matsim.contrib.drt.extension.estimator.DrtEstimator; +import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator; +import org.matsim.contrib.drt.extension.estimator.impl.BasicDrtEstimator; +import org.matsim.contrib.drt.extension.estimator.impl.PessimisticDrtEstimator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.dvrp.run.DvrpMode; +import org.matsim.contrib.dvrp.run.DvrpModes; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +/** + * Main module that needs to be installed if any estimator is to be used. + */ +public class DrtEstimatorModule extends AbstractModule { + + + /** + * Map of initial providers. + */ + private final Map> initial = new HashMap<>(); + + @Override + public void install() { + + MultiModeDrtConfigGroup drtConfigs = MultiModeDrtConfigGroup.get(getConfig()); + MultiModeDrtEstimatorConfigGroup configs = ConfigUtils.addOrGetModule(getConfig(), MultiModeDrtEstimatorConfigGroup.class); + + for (DrtConfigGroup cfg : drtConfigs.getModalElements()) { + + Optional estCfg = configs.getModalElement(cfg.mode); + + estCfg.ifPresent(drtEstimatorConfigGroup -> install(new ModeModule(cfg, drtEstimatorConfigGroup))); + } + } + + /** + * Configure initial estimators for the given modes. + * + * @param getter modal getter, which can be used to use other modal components via guice + */ + public DrtEstimatorModule withInitialEstimator(Function getter, String... modes) { + + if (modes.length == 0) + throw new IllegalArgumentException("At least one mode needs to be provided."); + + for (String mode : modes) { + initial.put(mode, getter); + } + + return this; + } + + final class ModeModule extends AbstractDvrpModeModule { + + private final DrtConfigGroup cfg; + private final DrtEstimatorConfigGroup group; + + public ModeModule(DrtConfigGroup cfg, DrtEstimatorConfigGroup group) { + super(group.mode); + this.cfg = cfg; + this.group = group; + } + + @Override + public void install() { + + // try with default injections and overwrite + if (group.estimator == DrtEstimatorConfigGroup.EstimatorType.BASIC) { + bindModal(DrtEstimator.class).toProvider(modalProvider( + getter -> new BasicDrtEstimator( + getter.getModal(DrtEventSequenceCollector.class), + getter.getModal(DrtInitialEstimator.class), + group, cfg + ) + )).in(Singleton.class); + } else if (group.estimator == DrtEstimatorConfigGroup.EstimatorType.INITIAL) { + bindModal(DrtEstimator.class).to(modalKey(DrtInitialEstimator.class)); + } + + if (initial.containsKey(group.mode)) { + bindModal(DrtInitialEstimator.class).toProvider(() -> initial.get(group.mode).apply(cfg)).in(Singleton.class); + } else + bindModal(DrtInitialEstimator.class).toInstance(new PessimisticDrtEstimator(cfg)); + + // DRT Estimators will be available as Map + MapBinder.newMapBinder(this.binder(), DvrpMode.class, DrtEstimator.class) + .addBinding(DvrpModes.mode(getMode())) + .to(modalKey(DrtEstimator.class)); + + addControlerListenerBinding().to(modalKey(DrtEstimator.class)); + + bindModal(DrtEstimatorConfigGroup.class).toInstance(group); + + // Needs to run before estimators + bindModal(DrtEstimateAnalyzer.class) + .toProvider( + modalProvider(getter -> new DrtEstimateAnalyzer(getter.getModal(DrtEstimator.class), getter.getModal(DrtEventSequenceCollector.class), group)) + ) + .in(Singleton.class); + + addControlerListenerBinding().to(modalKey(DrtEstimateAnalyzer.class)); + + } + + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java new file mode 100644 index 00000000000..b998bf78648 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java @@ -0,0 +1,103 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2018 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.contrib.drt.extension.estimator.run; + +import java.util.Collection; +import java.util.Optional; +import java.util.function.Supplier; + +import org.matsim.contrib.dvrp.run.MultiModal; +import org.matsim.contrib.dvrp.run.MultiModals; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ReflectiveConfigGroup; + +import com.google.common.base.Verify; + +/** + * @author Michal Maciejewski (michalm) + */ +public final class MultiModeDrtEstimatorConfigGroup extends ReflectiveConfigGroup implements MultiModal { + public static final String GROUP_NAME = "drtEstimators"; + + /** + * @param config + * @return MultiModeDrtConfigGroup if exists. Otherwise fails + */ + public static MultiModeDrtEstimatorConfigGroup get(Config config) { + return (MultiModeDrtEstimatorConfigGroup)config.getModule(GROUP_NAME); + } + + private final Supplier drtConfigSupplier; + + public MultiModeDrtEstimatorConfigGroup() { + this(DrtEstimatorConfigGroup::new); + } + + public MultiModeDrtEstimatorConfigGroup(Supplier drtConfigSupplier) { + super(GROUP_NAME); + this.drtConfigSupplier = drtConfigSupplier; + } + + @Override + protected void checkConsistency(Config config) { + super.checkConsistency(config); + Verify.verify(config.getModule(DrtEstimatorConfigGroup.GROUP_NAME) == null, + "In the multi-mode DRT setup, DrtEstimatorConfigGroup must not be defined at the config top level"); + MultiModals.requireAllModesUnique(this); + } + + @Override + public ConfigGroup createParameterSet(String type) { + if (type.equals(DrtEstimatorConfigGroup.GROUP_NAME)) { + return drtConfigSupplier.get(); + } else { + throw new IllegalArgumentException("Unsupported parameter set type: " + type); + } + } + + @Override + public void addParameterSet(ConfigGroup set) { + if (set instanceof DrtEstimatorConfigGroup) { + super.addParameterSet(set); + } else { + throw new IllegalArgumentException("Unsupported parameter set class: " + set); + } + } + + public void addParameterSet(DrtEstimatorConfigGroup set) { + addParameterSet((ConfigGroup) set); + } + + @Override + @SuppressWarnings("unchecked") + public Collection getModalElements() { + return (Collection)getParameterSets(DrtEstimatorConfigGroup.GROUP_NAME); + } + + /** + * Find estimator config for specific mode. + */ + public Optional getModalElement(String mode) { + return getModalElements().stream().filter(m -> m.getMode().equals(mode)).findFirst(); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/fiss/FISS.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/fiss/FISS.java index ac265cf4a2c..58705f89cb3 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/fiss/FISS.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/fiss/FISS.java @@ -164,7 +164,7 @@ public void afterSim() { } private boolean switchOffFISS() { - return (this.fissConfigGroup.switchOffFISSLastIteration && this.matsimServices.getConfig().controler().getLastIteration() == this.matsimServices.getIterationNumber()); + return (this.fissConfigGroup.switchOffFISSLastIteration && this.matsimServices.getConfig().controller().getLastIteration() == this.matsimServices.getIterationNumber()); } @Override diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/ConfigurableCostCalculatorStrategy.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/ConfigurableCostCalculatorStrategy.java new file mode 100644 index 00000000000..68fa48371e1 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/ConfigurableCostCalculatorStrategy.java @@ -0,0 +1,63 @@ +package org.matsim.contrib.drt.extension.insertion; + +import java.util.List; + +import javax.annotation.Nullable; + +import org.matsim.contrib.drt.optimizer.insertion.CostCalculationStrategy; +import org.matsim.contrib.drt.optimizer.insertion.InsertionCostCalculator; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public class ConfigurableCostCalculatorStrategy implements CostCalculationStrategy { + private final List constraints; + private final DrtInsertionObjective objective; + + private final SoftInsertionParams softInsertionParams; + + public ConfigurableCostCalculatorStrategy(DrtInsertionObjective objective, List constraints, + @Nullable SoftInsertionParams softInsertionParams) { + this.objective = objective; + this.constraints = constraints; + this.softInsertionParams = softInsertionParams; + } + + private boolean checkHardInsertion(DrtRequest request, DetourTimeInfo detourTimeInfo) { + return detourTimeInfo.pickupDetourInfo.departureTime <= request.getLatestStartTime() + && detourTimeInfo.dropoffDetourInfo.arrivalTime <= request.getLatestArrivalTime(); + } + + private double calculateSoftInsertionPenalty(DrtRequest request, DetourTimeInfo detourTimeInfo) { + if (softInsertionParams == null) { + return 0.0; + } else { + double pickupDelay = Math.max(0, + detourTimeInfo.pickupDetourInfo.departureTime - request.getLatestStartTime()); + + double dropoffDelay = Math.max(0, + detourTimeInfo.dropoffDetourInfo.arrivalTime - request.getLatestArrivalTime()); + + return softInsertionParams.pickupWeight * pickupDelay + softInsertionParams.dropoffWeight * dropoffDelay; + } + } + + @Override + public double calcCost(DrtRequest request, Insertion insertion, DetourTimeInfo detourTimeInfo) { + if (softInsertionParams == null && !checkHardInsertion(request, detourTimeInfo)) { + return InsertionCostCalculator.INFEASIBLE_SOLUTION_COST; + } + + for (DrtInsertionConstraint constraint : constraints) { + if (!constraint.checkInsertion(request, insertion, detourTimeInfo)) { + return InsertionCostCalculator.INFEASIBLE_SOLUTION_COST; + } + } + + return objective.calculateObjective(request, insertion, detourTimeInfo) + + calculateSoftInsertionPenalty(request, detourTimeInfo); + } + + static record SoftInsertionParams(double pickupWeight, double dropoffWeight) { + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionConstraint.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionConstraint.java new file mode 100644 index 00000000000..7a9fc3204b9 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionConstraint.java @@ -0,0 +1,9 @@ +package org.matsim.contrib.drt.extension.insertion; + +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public interface DrtInsertionConstraint { + boolean checkInsertion(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionModule.java new file mode 100644 index 00000000000..23ad52f4e80 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionModule.java @@ -0,0 +1,518 @@ +package org.matsim.contrib.drt.extension.insertion; + +import java.util.LinkedList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.drt.extension.insertion.ConfigurableCostCalculatorStrategy.SoftInsertionParams; +import org.matsim.contrib.drt.extension.insertion.constraints.ExclusivityConstraint; +import org.matsim.contrib.drt.extension.insertion.constraints.ExclusivityConstraint.ExclusivityVoter; +import org.matsim.contrib.drt.extension.insertion.constraints.SingleRequestConstraint; +import org.matsim.contrib.drt.extension.insertion.constraints.SkillsConstraint; +import org.matsim.contrib.drt.extension.insertion.constraints.SkillsConstraint.RequestRequirementsSupplier; +import org.matsim.contrib.drt.extension.insertion.constraints.SkillsConstraint.VehicleSkillsSupplier; +import org.matsim.contrib.drt.extension.insertion.constraints.VehicleRangeConstraint; +import org.matsim.contrib.drt.extension.insertion.constraints.VehicleRangeConstraint.VehicleRangeSupplier; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceApproximator; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.distances.EuclideanDistanceApproximator; +import org.matsim.contrib.drt.extension.insertion.distances.RoutingDistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.objectives.PassengerDelayObjective; +import org.matsim.contrib.drt.extension.insertion.objectives.VehicleActiveTimeObjective; +import org.matsim.contrib.drt.extension.insertion.objectives.VehicleDistanceObjective; +import org.matsim.contrib.drt.extension.insertion.objectives.VehicleDistanceObjective.VehcileDistanceWeights; +import org.matsim.contrib.drt.optimizer.insertion.CostCalculationStrategy; +import org.matsim.contrib.drt.passenger.DrtOfferAcceptor; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility; +import org.matsim.core.router.speedy.SpeedyALTFactory; +import org.matsim.core.router.util.LeastCostPathCalculatorFactory; +import org.matsim.core.router.util.TravelDisutility; +import org.matsim.core.router.util.TravelTime; + +import com.google.common.base.Preconditions; +import com.google.inject.Key; +import com.google.inject.Singleton; + +public class DrtInsertionModule extends AbstractDvrpModeQSimModule { + public DrtInsertionModule(DrtConfigGroup drtConfig) { + super(drtConfig.getMode()); + } + + // EXCLUSIVITY CONSTRAINT + + private boolean useExclusivityContraint = false; + private Class exclusivityVoterClass; + private ExclusivityVoter exclusivityVoter; + + public DrtInsertionModule withExclusivity(Class exclusivityVoterClass) { + Preconditions.checkState(!this.useExclusivityContraint); + this.useExclusivityContraint = true; + this.exclusivityVoterClass = exclusivityVoterClass; + return this; + } + + public DrtInsertionModule withExclusivity(ExclusivityVoter exclusivityVoter) { + Preconditions.checkState(!this.useExclusivityContraint); + this.useExclusivityContraint = true; + this.exclusivityVoter = exclusivityVoter; + return this; + } + + private void configureExclusivityConstraint(List> constraintBindings) { + if (useExclusivityContraint) { + if (exclusivityVoter != null) { + bindModal(ExclusivityVoter.class).toInstance(exclusivityVoter); + } + + if (exclusivityVoterClass != null) { + bindModal(ExclusivityVoter.class).to(modalKey(exclusivityVoterClass)); + } + + bindModal(ExclusivityConstraint.class).toProvider(modalProvider(getter -> { + ExclusivityVoter exclusivityVoter = getter.getModal(ExclusivityVoter.class); + return new ExclusivityConstraint(exclusivityVoter); + })).in(Singleton.class); + + constraintBindings.add(modalKey(ExclusivityConstraint.class)); + } + } + + // SINGLE REQUEST CONSTRAINT + + private boolean useSingleRequestContraint = false; + + public DrtInsertionModule withSingleRequestPerPerson() { + Preconditions.checkState(!this.useSingleRequestContraint); + this.useSingleRequestContraint = true; + return this; + } + + private void configureSingleRequestConstraint(List> constraintBindings) { + if (useSingleRequestContraint) { + bindModal(SingleRequestConstraint.class).toProvider(modalProvider(getter -> { + return new SingleRequestConstraint(); + })).in(Singleton.class); + + addMobsimScopeEventHandlerBinding().to(SingleRequestConstraint.class); + constraintBindings.add(modalKey(SingleRequestConstraint.class)); + } + } + + // SKILLS CONSTRAINT + + private boolean useSkillsConstraint = false; + + private Class vehicleSkillsSupplierClass; + private VehicleSkillsSupplier vehicleSkillsSupplier; + + private Class requestRequirementsSupplierClass; + private RequestRequirementsSupplier requestRequirementsSupplier; + + public DrtInsertionModule withSkills(VehicleSkillsSupplier vehicleSkillsSupplier, + RequestRequirementsSupplier requestRequirementsSupplier) { + Preconditions.checkState(!this.useSkillsConstraint); + this.vehicleSkillsSupplier = vehicleSkillsSupplier; + this.requestRequirementsSupplier = requestRequirementsSupplier; + this.useSkillsConstraint = true; + return this; + } + + public DrtInsertionModule withSkills(Class vehicleSkillsSupplierClass, + Class requestRequirementsSupplierClass) { + Preconditions.checkState(!this.useSkillsConstraint); + this.vehicleSkillsSupplierClass = vehicleSkillsSupplierClass; + this.requestRequirementsSupplierClass = requestRequirementsSupplierClass; + this.useSkillsConstraint = true; + return this; + } + + private void configureSkillsContraint(List> constraintBindings) { + if (useSkillsConstraint) { + if (vehicleSkillsSupplier != null) { + bindModal(VehicleSkillsSupplier.class).toInstance(vehicleSkillsSupplier); + } + + if (vehicleSkillsSupplierClass != null) { + bindModal(VehicleSkillsSupplier.class).to(modalKey(vehicleSkillsSupplierClass)); + } + + if (requestRequirementsSupplier != null) { + bindModal(RequestRequirementsSupplier.class).toInstance(requestRequirementsSupplier); + } + + if (requestRequirementsSupplierClass != null) { + bindModal(RequestRequirementsSupplier.class).to(modalKey(requestRequirementsSupplierClass)); + } + + bindModal(SkillsConstraint.class).toProvider(modalProvider(getter -> { + VehicleSkillsSupplier vehicleSkillsSupplier = getter.getModal(VehicleSkillsSupplier.class); + RequestRequirementsSupplier requestRequirementsSupplier = getter + .getModal(RequestRequirementsSupplier.class); + return new SkillsConstraint(vehicleSkillsSupplier, requestRequirementsSupplier); + })).in(Singleton.class); + + constraintBindings.add(modalKey(SkillsConstraint.class)); + } + } + + // CUSTOM CONSTRAINTS + + private final List> customConstraintClasses = new LinkedList<>(); + private final List customConstraints = new LinkedList<>(); + + public DrtInsertionModule withConstraint(Class constraintClass) { + customConstraintClasses.add(constraintClass); + return this; + } + + public DrtInsertionModule withConstraint(DrtInsertionConstraint constraint) { + customConstraints.add(constraint); + return this; + } + + // DISTANCES + + private DistanceCalculator distanceCalculator; + private DistanceApproximator distanceApproximator; + + private Class distanceCalculatorClass; + private Class distanceApproximatorClass; + + public DrtInsertionModule withDistanceCalculator(DistanceCalculator distanceCalculator) { + Preconditions.checkState(this.distanceCalculator == null && this.distanceCalculatorClass == null); + this.distanceCalculator = distanceCalculator; + return this; + } + + public DrtInsertionModule withDistanceCalculator(Class distanceCalculatorClass) { + Preconditions.checkState(this.distanceCalculator == null && this.distanceCalculatorClass == null); + this.distanceCalculatorClass = distanceCalculatorClass; + return this; + } + + public DrtInsertionModule withDistanceApproximator(DistanceApproximator distanceApproximator) { + Preconditions.checkState(this.distanceApproximator == null && this.distanceApproximatorClass == null); + this.distanceApproximator = distanceApproximator; + return this; + } + + public DrtInsertionModule withDistanceApproximator( + Class distanceApproximatorClass) { + Preconditions.checkState(this.distanceApproximator == null && this.distanceApproximatorClass == null); + this.distanceApproximatorClass = distanceApproximatorClass; + return this; + } + + public DrtInsertionModule withEuclideanDistanceApproximator(double euclideanDistanceFactor) { + Preconditions.checkState(this.distanceApproximator == null && this.distanceApproximatorClass == null); + this.distanceApproximator = new EuclideanDistanceApproximator(euclideanDistanceFactor); + return this; + } + + public DrtInsertionModule withEuclideanDistanceCalculator(double euclideanDistanceFactor) { + Preconditions.checkState(this.distanceCalculator == null && this.distanceCalculatorClass == null); + this.distanceCalculator = new EuclideanDistanceApproximator(euclideanDistanceFactor); + return this; + } + + private void configureDistances() { + bindModal(RoutingDistanceCalculator.class).toProvider(modalProvider(getter -> { + LeastCostPathCalculatorFactory factory = new SpeedyALTFactory(); + + TravelTime travelTime = getter.getModal(TravelTime.class); + TravelDisutility travelDisutility = new OnlyTimeDependentTravelDisutility(travelTime); + Network network = getter.getModal(Network.class); + + printDistanceWarning(); + + return new RoutingDistanceCalculator(factory.createPathCalculator(network, travelDisutility, travelTime), + travelTime); + })); + + if (distanceCalculator == null && distanceCalculatorClass == null) { + distanceCalculatorClass = RoutingDistanceCalculator.class; + } + + if (distanceApproximator == null && distanceApproximatorClass == null) { + distanceApproximator = DistanceApproximator.NULL; + } + + if (distanceCalculator != null) { + bindModal(DistanceCalculator.class).toInstance(distanceCalculator); + } + + if (distanceCalculatorClass != null) { + bindModal(DistanceCalculator.class).to(modalKey(distanceCalculatorClass)); + } + + if (distanceApproximator != null) { + bindModal(DistanceApproximator.class).toInstance(distanceApproximator); + } + + if (distanceApproximatorClass != null) { + bindModal(DistanceApproximator.class).to(modalKey(distanceApproximatorClass)); + } + } + + // RANGE CONSTRAINT + + private boolean useRangeConstraint = false; + + private VehicleRangeSupplier vehicleRangeSupplier; + private Class vehicleRangeSupplierClass; + + public DrtInsertionModule withVehicleRange(VehicleRangeSupplier rangeSupplier) { + Preconditions.checkState(!useRangeConstraint); + useRangeConstraint = true; + this.vehicleRangeSupplier = rangeSupplier; + return this; + } + + public DrtInsertionModule withVehicleRange(double vehicleRange) { + withVehicleRange(v -> vehicleRange); + return this; + } + + public DrtInsertionModule withVehicleRange(Class rangeSupplierClass) { + Preconditions.checkState(!useRangeConstraint); + useRangeConstraint = true; + this.vehicleRangeSupplierClass = rangeSupplierClass; + return this; + } + + private void configureRangeContraint(List> constraintBindings) { + if (useRangeConstraint) { + if (vehicleRangeSupplier != null) { + bindModal(VehicleRangeSupplier.class).toInstance(vehicleRangeSupplier); + } + + if (vehicleRangeSupplierClass != null) { + bindModal(VehicleRangeSupplier.class).to(modalKey(vehicleRangeSupplierClass)); + } + + bindModal(VehicleRangeConstraint.class).toProvider(modalProvider(getter -> { + DistanceCalculator distanceCalculator = getter.getModal(DistanceCalculator.class); + DistanceApproximator distanceApproximator = getter.getModal(DistanceApproximator.class); + + if (distanceApproximator == DistanceApproximator.NULL) { + distanceApproximator = null; + } + + return new VehicleRangeConstraint(vehicleRangeSupplier, distanceCalculator, distanceApproximator); + })); + + constraintBindings.add(modalKey(VehicleRangeConstraint.class)); + } + } + + // SOFT INSERTION + + private boolean useSoftInsertionPenalties = false; + private ConfigurableCostCalculatorStrategy.SoftInsertionParams softInsertionParams; + + public DrtInsertionModule withSoftInsertionPenalty(double pickupWeight, double dropoffWeight) { + Preconditions.checkState(!this.useSoftInsertionPenalties); + this.useSoftInsertionPenalties = true; + this.softInsertionParams = new SoftInsertionParams(pickupWeight, dropoffWeight); + return this; + } + + // PICKUP AND DROPOFF TIME WINDOW + + private double promisedPickupTimeWindow = Double.POSITIVE_INFINITY; + private double promisedDropoffTimeWindow = Double.POSITIVE_INFINITY; + + public DrtInsertionModule withPromisedPickupTimeWindow(double promisedPickupTimeWindow) { + this.promisedPickupTimeWindow = promisedPickupTimeWindow; + return this; + } + + public DrtInsertionModule withPromisedDropoffTimeWindow(double promisedDropoffTimeWindow) { + this.promisedDropoffTimeWindow = promisedDropoffTimeWindow; + return this; + } + + // OBJECTIVES + + private enum Objective { + Custom, VehicleActiveTime, PassengerDelay, VehicleDistance + } + + private Objective selectedObjective = null; + + // Vehicle active time + + public DrtInsertionModule minimizeVehicleActiveTime() { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.VehicleActiveTime; + return this; + } + + private void configureVehicleActiveTimeObjective() { + bindModal(DrtInsertionObjective.class).toInstance(new VehicleActiveTimeObjective()); + } + + // Passenger delay + + private double passengerDelayPickupWeight = 1.0; + private double passengerDelayDropoffWeight = 1.0; + + public DrtInsertionModule minimizePassengerDelay() { + return minimizePassengerDelay(1.0, 1.0); + } + + public DrtInsertionModule minimizePassengerDelay(double pickupWeight, double dropoffWeight) { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.PassengerDelay; + passengerDelayPickupWeight = pickupWeight; + passengerDelayDropoffWeight = dropoffWeight; + return this; + } + + private void configurePassengerDelayObjective() { + bindModal(DrtInsertionObjective.class) + .toInstance(new PassengerDelayObjective(passengerDelayPickupWeight, passengerDelayDropoffWeight)); + } + + // Custom objective + + private DrtInsertionObjective configuredObjective; + private Class configuredObjectiveClass; + + public DrtInsertionModule minimize(DrtInsertionObjective objective) { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.Custom; + configuredObjective = objective; + return this; + } + + public DrtInsertionModule minimize(Class objective) { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.Custom; + configuredObjectiveClass = objective; + return this; + } + + private void configureCustomObjective() { + if (configuredObjective != null) { + bindModal(DrtInsertionObjective.class).toInstance(configuredObjective); + } + + if (configuredObjectiveClass != null) { + bindModal(DrtInsertionObjective.class).to(modalKey(configuredObjectiveClass)); + } + } + + // Vehicle distance + + private VehcileDistanceWeights vehicleDistanceWeights = null; + private double distanceObjectiveEstimationFactor = Double.NaN; + + public DrtInsertionModule minimizeDistances(double occupiedWeight, double emptyWeight, double passengerWeight) { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.VehicleDistance; + vehicleDistanceWeights = new VehcileDistanceWeights(occupiedWeight, emptyWeight, passengerWeight); + return this; + } + + public DrtInsertionModule minimizeVehicleDistance() { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.VehicleDistance; + vehicleDistanceWeights = new VehcileDistanceWeights(1.0, 1.0, 0.0); + return this; + } + + public DrtInsertionModule minimizeEmptyDistance() { + Preconditions.checkState(selectedObjective == null); + selectedObjective = Objective.VehicleDistance; + vehicleDistanceWeights = new VehcileDistanceWeights(0.0, 1.0, 0.0); + return this; + } + + public DrtInsertionModule withDistanceObjectiveFactor(double estimationFactor) { + this.distanceObjectiveEstimationFactor = estimationFactor; + return this; + } + + private void configureVehicleDistanceObjective() { + bindModal(DrtInsertionObjective.class).toProvider(modalProvider(getter -> { + final DistanceCalculator distanceCalculator; + + if (Double.isFinite(distanceObjectiveEstimationFactor)) { + distanceCalculator = new EuclideanDistanceApproximator(distanceObjectiveEstimationFactor); + } else { + distanceCalculator = getter.getModal(RoutingDistanceCalculator.class); + } + + return new VehicleDistanceObjective(vehicleDistanceWeights, distanceCalculator); + })); + } + + @Override + protected void configureQSim() { + configureDistances(); + + List> constraintBindings = new LinkedList<>(); + configureExclusivityConstraint(constraintBindings); + configureSingleRequestConstraint(constraintBindings); + configureSkillsContraint(constraintBindings); + configureRangeContraint(constraintBindings); + + if (selectedObjective == null) { + selectedObjective = Objective.VehicleActiveTime; + } + + switch (selectedObjective) { + case Custom: + configureCustomObjective(); + break; + case PassengerDelay: + configurePassengerDelayObjective(); + break; + case VehicleDistance: + configureVehicleDistanceObjective(); + break; + case VehicleActiveTime: + default: + configureVehicleActiveTimeObjective(); + break; + } + + bindModal(ConfigurableCostCalculatorStrategy.class).toProvider(modalProvider(getter -> { + List constraints = new LinkedList<>(); + + for (Key constraintBinding : constraintBindings) { + constraints.add(getter.get(constraintBinding)); + } + + for (Class constraintClass : customConstraintClasses) { + constraints.add(getter.getModal(constraintClass)); + } + + for (DrtInsertionConstraint constraint : customConstraints) { + constraints.add(constraint); + } + + return new ConfigurableCostCalculatorStrategy(getter.getModal(DrtInsertionObjective.class), constraints, + softInsertionParams); + })).in(Singleton.class); + + bindModal(PromisedTimeWindowOfferAcceptor.class).toProvider(modalProvider(getter -> { + return new PromisedTimeWindowOfferAcceptor(promisedPickupTimeWindow, promisedDropoffTimeWindow); + })).in(Singleton.class); + + bindModal(CostCalculationStrategy.class).to(modalKey(ConfigurableCostCalculatorStrategy.class)); + bindModal(DrtOfferAcceptor.class).to(modalKey(PromisedTimeWindowOfferAcceptor.class)); + } + + private final static Logger logger = LogManager.getLogger(DrtInsertionModule.class); + + private static void printDistanceWarning() { + logger.warn( + "Depending on your configruation, distance-based objectives and constraints may be very impacting on performance. The features should be considered experimental. See discussion of #2947 on Github."); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionObjective.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionObjective.java new file mode 100644 index 00000000000..b6fd9946152 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionObjective.java @@ -0,0 +1,9 @@ +package org.matsim.contrib.drt.extension.insertion; + +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public interface DrtInsertionObjective { + double calculateObjective(DrtRequest request, Insertion insertion, DetourTimeInfo detourTimeInfo); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/PromisedTimeWindowOfferAcceptor.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/PromisedTimeWindowOfferAcceptor.java new file mode 100644 index 00000000000..2bb52a952ac --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/PromisedTimeWindowOfferAcceptor.java @@ -0,0 +1,33 @@ +package org.matsim.contrib.drt.extension.insertion; + +import java.util.Optional; + +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.passenger.DrtOfferAcceptor; +import org.matsim.contrib.drt.passenger.DrtRequest; + +/** + * This class is based on MOIA's PromisedPickupTimeWindowDrtOfferAcceptor. + */ +public class PromisedTimeWindowOfferAcceptor implements DrtOfferAcceptor { + private final double promisedPickupTimeWindow; + private final double promisedDropoffTimeWindow; + + public PromisedTimeWindowOfferAcceptor(double promisedPickTimeWindow, double promisedDropoffTimeWindow) { + this.promisedPickupTimeWindow = promisedPickTimeWindow; + this.promisedDropoffTimeWindow = promisedDropoffTimeWindow; + } + + @Override + public Optional acceptDrtOffer(DrtRequest request, double departureTime, double arrivalTime) { + double updatedPickupTimeWindow = Math.min(departureTime + promisedPickupTimeWindow, + request.getLatestStartTime()); + + double updatedDropoffTimeWindow = Math.min(arrivalTime + promisedDropoffTimeWindow, + request.getLatestArrivalTime()); + + return Optional + .of(AcceptedDrtRequest.newBuilder().request(request).earliestStartTime(request.getEarliestStartTime()) + .latestArrivalTime(updatedDropoffTimeWindow).latestStartTime(updatedPickupTimeWindow).build()); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/ExclusivityConstraint.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/ExclusivityConstraint.java new file mode 100644 index 00000000000..fbac3a88209 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/ExclusivityConstraint.java @@ -0,0 +1,70 @@ +package org.matsim.contrib.drt.extension.insertion.constraints; + +import org.matsim.contrib.drt.extension.insertion.DrtInsertionConstraint; +import org.matsim.contrib.drt.optimizer.Waypoint; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public class ExclusivityConstraint implements DrtInsertionConstraint { + private final ExclusivityVoter voter; + + public ExclusivityConstraint(ExclusivityVoter voter) { + this.voter = voter; + } + + @Override + public boolean checkInsertion(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) { + if (voter.isExclusive(drtRequest)) { + return isValidInsertionForExclusiveRequest(drtRequest, insertion, detourTimeInfo); + } else { + return isValidInsertionForStandardRequest(drtRequest, insertion, detourTimeInfo); + } + } + + private boolean isValidInsertionForExclusiveRequest(DrtRequest drtRequest, Insertion insertion, + DetourTimeInfo detourTimeInfo) { + if (insertion.pickup.previousWaypoint.getOutgoingOccupancy() > 0) { + // attempt to attach pickup to existing trip + return false; + } + + // dropoff must follow directly after pickup + return insertion.pickup.index == insertion.dropoff.index; + } + + private boolean isValidInsertionForStandardRequest(DrtRequest drtRequest, Insertion insertion, + DetourTimeInfo detourTimeInfo) { + if (insertion.pickup.index == 0) { + if (insertion.vehicleEntry.stops.size() > 0) { + Waypoint.Stop nextStop = insertion.vehicleEntry.stops.get(0); + + for (AcceptedDrtRequest dropoffRequest : nextStop.task.getDropoffRequests().values()) { + if (voter.isExclusive(dropoffRequest.getRequest())) { + // ongoing prebooking trip, we cannot insert at beginning of schedule + return false; + } + } + } + } + + int minimumIndex = Math.max(0, insertion.pickup.index - 1); + for (int index = minimumIndex; index < insertion.dropoff.index; index++) { + Waypoint.Stop stop = insertion.vehicleEntry.stops.get(index); + + for (AcceptedDrtRequest pickupRequest : stop.task.getPickupRequests().values()) { + if (voter.isExclusive(pickupRequest.getRequest())) { + // covering a prebooked pickup + return false; + } + } + } + + return true; + } + + static public interface ExclusivityVoter { + boolean isExclusive(DrtRequest request); + } +} \ No newline at end of file diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SingleRequestConstraint.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SingleRequestConstraint.java new file mode 100644 index 00000000000..532bbd204b1 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SingleRequestConstraint.java @@ -0,0 +1,33 @@ +package org.matsim.contrib.drt.extension.insertion.constraints; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdSet; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.extension.insertion.DrtInsertionConstraint; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEventHandler; +import org.matsim.core.events.MobsimScopeEventHandler; + +public class SingleRequestConstraint + implements DrtInsertionConstraint, PassengerRequestSubmittedEventHandler, MobsimScopeEventHandler { + private final IdSet observedPersons = new IdSet<>(Person.class); + + @Override + public boolean checkInsertion(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) { + for (Id passengerId : drtRequest.getPassengerIds()) { + if (observedPersons.contains(passengerId)) { + return false; + } + } + + return true; + } + + @Override + public void handleEvent(PassengerRequestSubmittedEvent event) { + observedPersons.addAll(event.getPersonIds()); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SkillsConstraint.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SkillsConstraint.java new file mode 100644 index 00000000000..1b48ea822c9 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/SkillsConstraint.java @@ -0,0 +1,90 @@ +package org.matsim.contrib.drt.extension.insertion.constraints; + +import java.util.Set; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.extension.insertion.DrtInsertionConstraint; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +public class SkillsConstraint implements DrtInsertionConstraint { + private final VehicleSkillsSupplier vehicleSkillsSupplier; + private final RequestRequirementsSupplier requestRequirementsSupplier; + + public SkillsConstraint(VehicleSkillsSupplier vehicleSkillsSupplier, + RequestRequirementsSupplier requestRequirementsSupplier) { + this.vehicleSkillsSupplier = vehicleSkillsSupplier; + this.requestRequirementsSupplier = requestRequirementsSupplier; + } + + @Override + public boolean checkInsertion(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) { + Set requestRequirements = requestRequirementsSupplier.getRequiredSkills(drtRequest); + Set vehicleSkills = vehicleSkillsSupplier.getAvailableSkills(insertion.vehicleEntry.vehicle); + + if (requestRequirements == null) { + return true; + } + + if (vehicleSkills == null) { + return false; + } + + return vehicleSkills.containsAll(requestRequirements); + } + + static public interface VehicleSkillsSupplier { + Set getAvailableSkills(DvrpVehicle vehicle); + } + + static public interface RequestRequirementsSupplier { + Set getRequiredSkills(DrtRequest request); + } + + static public class VehicleSkillsBuilder { + private final ImmutableMap.Builder, ImmutableSet> builder = ImmutableMap.builder(); + + public VehicleSkillsBuilder addVehicle(Id vehicleId, Set skills) { + builder.put(vehicleId, ImmutableSet.copyOf(skills)); + return this; + } + + public VehicleSkillsSupplier build() { + var data = builder.build(); + return v -> data.get(v.getId()); + } + } + + static public class PersonRequirementsBuilder { + private final ImmutableMap.Builder, ImmutableSet> builder = ImmutableMap.builder(); + + public PersonRequirementsBuilder addVehicle(Id personId, Set skills) { + builder.put(personId, ImmutableSet.copyOf(skills)); + return this; + } + + public RequestRequirementsSupplier build() { + var data = builder.build(); + + return request -> { + ImmutableSet.Builder builder = ImmutableSet.builder(); + + for (Id passengerId : request.getPassengerIds()) { + var passengerRequirements = data.get(passengerId); + + if (passengerRequirements != null) { + builder.addAll(passengerRequirements); + } + } + + return builder.build(); + }; + } + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/VehicleRangeConstraint.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/VehicleRangeConstraint.java new file mode 100644 index 00000000000..649a68fd189 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/constraints/VehicleRangeConstraint.java @@ -0,0 +1,59 @@ +package org.matsim.contrib.drt.extension.insertion.constraints; + +import javax.annotation.Nullable; + +import org.matsim.contrib.drt.extension.insertion.DrtInsertionConstraint; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceApproximator; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.distances.InsertionDistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.distances.InsertionDistanceCalculator.VehicleDistance; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +public class VehicleRangeConstraint implements DrtInsertionConstraint { + private final InsertionDistanceCalculator insertionCalculator = new InsertionDistanceCalculator(); + + private final VehicleRangeSupplier rangeSupplier; + private final DistanceCalculator distanceCalculator; + private final DistanceApproximator distanceApproximator; + + public VehicleRangeConstraint(VehicleRangeSupplier rangeSupplier, DistanceCalculator distanceEstimator, + @Nullable DistanceApproximator distanceApproximator) { + this.rangeSupplier = rangeSupplier; + this.distanceCalculator = distanceEstimator; + this.distanceApproximator = distanceApproximator; + } + + @Override + public boolean checkInsertion(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) { + VehicleDistance scheduledDistance = insertionCalculator.calculateScheduledDistance(insertion.vehicleEntry); + double currentDistance = scheduledDistance.totalDriveDistance(); + double distanceSlack = rangeSupplier.getVehicleRange(insertion.vehicleEntry.vehicle) - currentDistance; + + if (distanceSlack <= 0) { + return false; // already violated + } + + if (distanceApproximator != null) { + VehicleDistance approximatedInsertionDistance = insertionCalculator.calculateInsertionDistance(insertion, + detourTimeInfo, distanceApproximator); + double approximatedDistanceDelta = approximatedInsertionDistance.totalDriveDistance(); + + if (approximatedDistanceDelta <= distanceSlack) { + return true; // passes with pessimistic approximation + } + } + + VehicleDistance insertionDistance = insertionCalculator.calculateInsertionDistance(insertion, detourTimeInfo, + distanceCalculator); + double distanceDelta = insertionDistance.totalDriveDistance(); + + return distanceDelta <= distanceSlack; + } + + static public interface VehicleRangeSupplier { + double getVehicleRange(DvrpVehicle vehicle); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceApproximator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceApproximator.java new file mode 100644 index 00000000000..bae08f00040 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceApproximator.java @@ -0,0 +1,8 @@ +package org.matsim.contrib.drt.extension.insertion.distances; + +public interface DistanceApproximator extends DistanceCalculator { + static public DistanceApproximator NULL = (departureTime, fromLink, toLink) -> { + throw new IllegalStateException( + "The NULL DistanceApproximator is only used as a tag for not using any approximation."); + }; +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceCalculator.java new file mode 100644 index 00000000000..cc74978ac34 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/DistanceCalculator.java @@ -0,0 +1,7 @@ +package org.matsim.contrib.drt.extension.insertion.distances; + +import org.matsim.api.core.v01.network.Link; + +public interface DistanceCalculator { + double calculateDistance(double departureTime, Link fromLink, Link toLink); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/EuclideanDistanceApproximator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/EuclideanDistanceApproximator.java new file mode 100644 index 00000000000..9f8c5c4556e --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/EuclideanDistanceApproximator.java @@ -0,0 +1,18 @@ +package org.matsim.contrib.drt.extension.insertion.distances; + +import org.matsim.api.core.v01.network.Link; +import org.matsim.core.utils.geometry.CoordUtils; + +public class EuclideanDistanceApproximator implements DistanceApproximator { + private final double distanceEstimationFactor; + + public EuclideanDistanceApproximator(double distanceEstimationFactor) { + this.distanceEstimationFactor = distanceEstimationFactor; + } + + @Override + public double calculateDistance(double departureTime, Link fromLink, Link toLink) { + return distanceEstimationFactor + * CoordUtils.calcEuclideanDistance(fromLink.getFromNode().getCoord(), toLink.getFromNode().getCoord()); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/InsertionDistanceCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/InsertionDistanceCalculator.java new file mode 100644 index 00000000000..01a6c91bf20 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/InsertionDistanceCalculator.java @@ -0,0 +1,213 @@ +package org.matsim.contrib.drt.extension.insertion.distances; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.optimizer.Waypoint; +import org.matsim.contrib.drt.optimizer.Waypoint.End; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.dvrp.schedule.DriveTask; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Schedule.ScheduleStatus; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; + +public class InsertionDistanceCalculator { + public VehicleDistance calculateScheduledDistance(VehicleEntry vehicleEntry) { + Schedule schedule = vehicleEntry.vehicle.getSchedule(); + + double occupiedDistance = 0.0; + double emptyDistance = 0.0; + double passengerDistance = 0.0; + + if (!schedule.getStatus().equals(ScheduleStatus.UNPLANNED)) { + int occupancy = 0; + + for (Task task : schedule.getTasks()) { + if (task instanceof DrtStopTask) { + occupancy += getPassengers(((DrtStopTask) task).getPickupRequests().values()); + occupancy -= getPassengers(((DrtStopTask) task).getDropoffRequests().values()); + } + + if (task instanceof DriveTask) { + double taskDistance = calculateTaskDistance((DriveTask) task); + + if (occupancy == 0) { + emptyDistance += taskDistance; + } else { + occupiedDistance += taskDistance; + passengerDistance += taskDistance * occupancy; + } + } + } + } + + return new VehicleDistance(occupiedDistance, emptyDistance, passengerDistance); + } + + private int getPassengers(Collection requests) { + return requests.stream().mapToInt(r -> r.getPassengerIds().size()).sum(); + } + + public VehicleDistance calculateInsertionDistance(Insertion insertion, DetourTimeInfo detourTimeInfo, + DistanceCalculator distanceEstimator) { + // pairs containing driven distance and occupany + List addedDistances = new LinkedList<>(); + List removedDistances = new LinkedList<>(); + + final Link pickupFromLink = insertion.pickup.previousWaypoint.getLink(); + final Link pickupNewLink = insertion.pickup.newWaypoint.getLink(); + final Link pickupToLink = insertion.pickup.nextWaypoint.getLink(); + + int beforePickupOccupancy = insertion.pickup.previousWaypoint.getOutgoingOccupancy(); + + double beforePickupDistance = distanceEstimator + .calculateDistance(insertion.pickup.previousWaypoint.getDepartureTime(), pickupFromLink, pickupNewLink); + + double afterPickupDistance = distanceEstimator.calculateDistance(detourTimeInfo.pickupDetourInfo.departureTime, + pickupNewLink, pickupToLink); + + addedDistances.add(new DistanceEntry(beforePickupDistance, beforePickupOccupancy)); + addedDistances.add(new DistanceEntry(afterPickupDistance, beforePickupOccupancy + 1)); + + if (insertion.pickup.previousWaypoint instanceof Waypoint.Start) { + Task currentTask = insertion.vehicleEntry.vehicle.getSchedule().getCurrentTask(); + + if (currentTask instanceof DriveTask) { + OnlineDriveTaskTracker tracker = (OnlineDriveTaskTracker) ((DriveTask) currentTask).getTaskTracker(); + + double removedStartDistance = 0.0; + + for (int k = tracker.getCurrentLinkIdx(); k < tracker.getPath().getLinkCount(); k++) { + removedStartDistance += tracker.getPath().getLink(k).getLength(); + } + + int startOccupancy = insertion.pickup.previousWaypoint.getOutgoingOccupancy(); + removedDistances.add(new DistanceEntry(removedStartDistance, startOccupancy)); + } + } else { + int startIndex = ((Waypoint.Stop) insertion.pickup.previousWaypoint).task.getTaskIdx(); + int occupancy = insertion.pickup.previousWaypoint.getOutgoingOccupancy(); + + final int endIndex; + if (insertion.pickup.nextWaypoint instanceof Waypoint.End) { + endIndex = insertion.vehicleEntry.vehicle.getSchedule().getTaskCount() - 1; + } else if (!(insertion.pickup.nextWaypoint instanceof Waypoint.Dropoff)) { + endIndex = ((Waypoint.Stop) insertion.pickup.nextWaypoint).task.getTaskIdx(); + } else { + endIndex = startIndex; + } + + for (int index = startIndex; index < endIndex; index++) { + Task task = insertion.vehicleEntry.vehicle.getSchedule().getTasks().get(index); + + if (task instanceof DrtStopTask) { + occupancy += getPassengers(((DrtStopTask) task).getPickupRequests().values()); + occupancy -= getPassengers(((DrtStopTask) task).getDropoffRequests().values()); + } + + if (task instanceof DriveTask) { + double taskDistance = calculateTaskDistance((DriveTask) task); + removedDistances.add(new DistanceEntry(taskDistance, occupancy)); + } + } + } + + final Link dropoffFromLink = insertion.dropoff.previousWaypoint.getLink(); + final Link dropoffNewLink = insertion.dropoff.newWaypoint.getLink(); + final Link dropoffToLink = (insertion.dropoff.nextWaypoint instanceof End) + ? insertion.dropoff.newWaypoint.getLink() + : insertion.dropoff.nextWaypoint.getLink(); + + final int beforeDropoffOccupancy; + if (insertion.dropoff.index > insertion.pickup.index) { + beforeDropoffOccupancy = insertion.dropoff.previousWaypoint.getOutgoingOccupancy() + 1; + double beforeDropoffDistance = distanceEstimator.calculateDistance( + insertion.dropoff.previousWaypoint.getDepartureTime(), dropoffFromLink, dropoffNewLink); + + addedDistances.add(new DistanceEntry(beforeDropoffDistance, beforeDropoffOccupancy)); + } else { + beforeDropoffOccupancy = beforePickupOccupancy + 1; + } + + double afterDropoffDistance = distanceEstimator.calculateDistance(detourTimeInfo.dropoffDetourInfo.arrivalTime, + dropoffNewLink, dropoffToLink); + addedDistances.add(new DistanceEntry(afterDropoffDistance, beforeDropoffOccupancy - 1)); + + if (insertion.dropoff.index > insertion.pickup.index) { + int startIndex = ((Waypoint.Stop) insertion.dropoff.previousWaypoint).task.getTaskIdx(); + int occupancy = insertion.dropoff.previousWaypoint.getOutgoingOccupancy(); + + final int endIndex; + if (insertion.dropoff.nextWaypoint instanceof Waypoint.End) { + endIndex = insertion.vehicleEntry.vehicle.getSchedule().getTaskCount() - 1; + } else { + endIndex = ((Waypoint.Stop) insertion.dropoff.nextWaypoint).task.getTaskIdx(); + } + + for (int index = startIndex; index < endIndex; index++) { + Task task = insertion.vehicleEntry.vehicle.getSchedule().getTasks().get(index); + + if (task instanceof DrtStopTask) { + occupancy += getPassengers(((DrtStopTask) task).getPickupRequests().values()); + occupancy -= getPassengers(((DrtStopTask) task).getDropoffRequests().values()); + } + + if (task instanceof DriveTask) { + double taskDistance = calculateTaskDistance((DriveTask) task); + removedDistances.add(new DistanceEntry(taskDistance, occupancy)); + } + } + } + + double occupiedDriveDistance = 0.0; + double emptyDriveDistance = 0.0; + double passengerDistance = 0.0; + + for (var entry : addedDistances) { + if (entry.occupancy == 0) { + emptyDriveDistance += entry.distance; + } else { + occupiedDriveDistance += entry.distance; + passengerDistance += entry.distance * entry.occupancy; + } + } + + for (var entry : removedDistances) { + if (entry.occupancy == 0) { + emptyDriveDistance -= entry.distance; + } else { + occupiedDriveDistance -= entry.distance; + passengerDistance -= entry.hashCode() * entry.occupancy; + } + } + + return new VehicleDistance(occupiedDriveDistance, emptyDriveDistance, passengerDistance); + } + + private double calculateTaskDistance(DriveTask task) { + double distance = 0.0; + + for (int k = 0; k < task.getPath().getLinkCount(); k++) { + distance += task.getPath().getLink(k).getLength(); + } + + return distance; + } + + static public record VehicleDistance(double occupiedDriveDistance, double emptyDriveDistance, + double passengerDistance) { + public double totalDriveDistance() { + return occupiedDriveDistance + emptyDriveDistance; + } + } + + private record DistanceEntry(double distance, int occupancy) { + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/RoutingDistanceCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/RoutingDistanceCalculator.java new file mode 100644 index 00000000000..cf74ff360a1 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/distances/RoutingDistanceCalculator.java @@ -0,0 +1,26 @@ +package org.matsim.contrib.drt.extension.insertion.distances; + +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.path.VrpPaths; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.TravelTime; + +public class RoutingDistanceCalculator implements DistanceCalculator { + private final TravelTime travelTime; + private final LeastCostPathCalculator router; + + public RoutingDistanceCalculator(LeastCostPathCalculator router, TravelTime travelTime) { + this.router = router; + this.travelTime = travelTime; + } + + // Currently, simply protected through synchonized. Later on would be better to + // set this up in a more intelligent way, I'm not sure, but I guess that the + // constraints are accesses in parallel by DRT. /sh nov'23 + @Override + public synchronized double calculateDistance(double departureTime, Link fromLink, Link toLink) { + VrpPathWithTravelData path = VrpPaths.calcAndCreatePath(fromLink, toLink, departureTime, router, travelTime); + return VrpPaths.calcDistance(path); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/PassengerDelayObjective.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/PassengerDelayObjective.java new file mode 100644 index 00000000000..55cda444f99 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/PassengerDelayObjective.java @@ -0,0 +1,58 @@ +package org.matsim.contrib.drt.extension.insertion.objectives; + +import java.util.Collection; + +import org.matsim.contrib.drt.extension.insertion.DrtInsertionObjective; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public class PassengerDelayObjective implements DrtInsertionObjective { + private final double pickupWeight; + private final double dropoffWeight; + + public PassengerDelayObjective(double pickupWeight, double dropoffWeight) { + this.pickupWeight = pickupWeight; + this.dropoffWeight = dropoffWeight; + } + + @Override + public double calculateObjective(DrtRequest request, Insertion insertion, DetourTimeInfo detourTimeInfo) { + VehicleEntry vehicleEntry = insertion.vehicleEntry; + + double totalPickupValue = detourTimeInfo.pickupDetourInfo.departureTime - request.getEarliestStartTime(); + double totalDropoffValue = detourTimeInfo.dropoffDetourInfo.arrivalTime - request.getEarliestStartTime(); + + double remainingTimeLoss = detourTimeInfo.pickupDetourInfo.pickupTimeLoss; + + for (int i = insertion.pickup.index; i < insertion.dropoff.index; i++) { + remainingTimeLoss -= insertion.vehicleEntry.getPrecedingStayTime(i); + remainingTimeLoss = Math.max(0.0, remainingTimeLoss); + + totalPickupValue += getPassengers(vehicleEntry.stops.get(i).task.getPickupRequests().values()) + * remainingTimeLoss; + totalDropoffValue += getPassengers(vehicleEntry.stops.get(i).task.getDropoffRequests().values()) + * remainingTimeLoss; + } + + remainingTimeLoss += detourTimeInfo.dropoffDetourInfo.dropoffTimeLoss; + + for (int i = insertion.dropoff.index; i < vehicleEntry.stops.size(); i++) { + remainingTimeLoss -= insertion.vehicleEntry.getPrecedingStayTime(i); + remainingTimeLoss = Math.max(0.0, remainingTimeLoss); + + totalPickupValue += getPassengers(vehicleEntry.stops.get(i).task.getPickupRequests().values()) + * remainingTimeLoss; + totalDropoffValue += getPassengers(vehicleEntry.stops.get(i).task.getDropoffRequests().values()) + * remainingTimeLoss; + } + + return totalPickupValue * pickupWeight + totalDropoffValue * dropoffWeight; + } + + private int getPassengers(Collection requests) { + return requests.stream().mapToInt(r -> r.getPassengerIds().size()).sum(); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleActiveTimeObjective.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleActiveTimeObjective.java new file mode 100644 index 00000000000..bf09f86b2d9 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleActiveTimeObjective.java @@ -0,0 +1,13 @@ +package org.matsim.contrib.drt.extension.insertion.objectives; + +import org.matsim.contrib.drt.extension.insertion.DrtInsertionObjective; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public class VehicleActiveTimeObjective implements DrtInsertionObjective { + @Override + public double calculateObjective(DrtRequest request, Insertion insertion, DetourTimeInfo detourTimeInfo) { + return detourTimeInfo.getTotalTimeLoss(); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleDistanceObjective.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleDistanceObjective.java new file mode 100644 index 00000000000..27a7333e575 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/insertion/objectives/VehicleDistanceObjective.java @@ -0,0 +1,32 @@ +package org.matsim.contrib.drt.extension.insertion.objectives; + +import org.matsim.contrib.drt.extension.insertion.DrtInsertionObjective; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.distances.InsertionDistanceCalculator; +import org.matsim.contrib.drt.extension.insertion.distances.InsertionDistanceCalculator.VehicleDistance; +import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; +import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.DrtRequest; + +public class VehicleDistanceObjective implements DrtInsertionObjective { + private final InsertionDistanceCalculator insertionCalculator = new InsertionDistanceCalculator(); + private final DistanceCalculator distanceCalculator; + private final VehcileDistanceWeights weights; + + public VehicleDistanceObjective(VehcileDistanceWeights weights, DistanceCalculator distanceCalculator) { + this.weights = weights; + this.distanceCalculator = distanceCalculator; + } + + @Override + public double calculateObjective(DrtRequest request, Insertion insertion, DetourTimeInfo detourTimeInfo) { + VehicleDistance distance = insertionCalculator.calculateInsertionDistance(insertion, detourTimeInfo, + distanceCalculator); + + return distance.occupiedDriveDistance() * weights.occupied + distance.emptyDriveDistance() * weights.empty + + distance.passengerDistance() * weights.passenger; + } + + static public record VehcileDistanceWeights(double occupied, double empty, double passenger) { + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/charging/ChargingBreakActivity.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/charging/ChargingBreakActivity.java index f535c15d5ca..1a008c63cdd 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/charging/ChargingBreakActivity.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/charging/ChargingBreakActivity.java @@ -1,6 +1,7 @@ package org.matsim.contrib.drt.extension.operations.eshifts.charging; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; import org.matsim.contrib.dvrp.optimizer.Request; @@ -15,7 +16,10 @@ import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask; import org.matsim.core.mobsim.framework.MobsimPassengerAgent; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * based on {@link DrtStopActivity} and {@link ChargingActivity} @@ -50,7 +54,7 @@ public ChargingBreakActivity(ChargingTask chargingTask, PassengerHandler passeng protected boolean isLastStep(double now) { if(chargingDelegate.getEndTime() < now && now >= endTime) { for (var request : pickupRequests.values()) { - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { passengersPickedUp++; } } @@ -64,13 +68,13 @@ public void finalizeAction(double now) { } @Override - public void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, double now) { + public void notifyPassengersAreReadyForDeparture(List passengers, double now) { if (!isLastStep(now)) { return;// pick up only at the end of stop activity } - var request = getRequestForPassenger(passenger.getId()); - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { + var request = getRequestForPassengers(passengers.stream().map(Identifiable::getId).toList()); + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { passengersPickedUp++; } else { throw new IllegalStateException("The passenger is not on the link or not available for departure!"); @@ -81,7 +85,7 @@ public void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, d protected void beforeFirstStep(double now) { // TODO probably we should simulate it more accurately (passenger by passenger, not all at once...) for (var request : dropoffRequests.values()) { - passengerHandler.dropOffPassenger(driver, request.getId(), now); + passengerHandler.dropOffPassengers(driver, request.getId(), now); } } @@ -95,9 +99,9 @@ protected void simStep(double now) { chargingDelegate.doSimStep(now); } - private AcceptedDrtRequest getRequestForPassenger(Id passengerId) { + private AcceptedDrtRequest getRequestForPassengers(List> passengerIds) { return pickupRequests.values().stream() - .filter(r -> passengerId.equals(r.getPassengerId())) + .filter(r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) .findAny() .orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java index a6619dbff3c..e18008e4ce5 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java @@ -53,6 +53,11 @@ public EDrtShiftDispatcherImpl(EShiftTaskScheduler shiftTaskScheduler, ChargingI this.fleet = fleet; } + @Override + public void initialize() { + delegate.initialize(); + } + @Override public void dispatch(double timeStep) { delegate.dispatch(timeStep); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java index 8f625fdb18e..ad3c83ca0f7 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java @@ -27,7 +27,7 @@ public EDrtShiftStartLogic(ShiftStartLogic delegate) { @Override public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry shiftEntry) { - Schedule schedule = shiftEntry.vehicle.getSchedule(); + Schedule schedule = shiftEntry.vehicle().getSchedule(); Task currentTask = schedule.getCurrentTask(); if (currentTask instanceof EDrtWaitForShiftStayTask) { //check whether vehicle still needs to complete charging task diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java index 4fc1aafaad1..fdc06e3cb8b 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java @@ -1,6 +1,8 @@ package org.matsim.contrib.drt.extension.operations.eshifts.run; +import com.google.inject.Singleton; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.drt.extension.edrt.EDrtActionCreator; import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory; import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; import org.matsim.contrib.drt.extension.edrt.scheduler.EmptyVehicleChargingScheduler; @@ -20,17 +22,21 @@ import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.DrtShiftDispatcher; import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.DrtShiftDispatcherImpl; import org.matsim.contrib.drt.extension.operations.shifts.optimizer.ShiftVehicleDataEntryFactory; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtActionCreator; import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtTaskFactory; import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftTaskScheduler; import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShifts; import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.passenger.PassengerHandler; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; @@ -69,22 +75,37 @@ drtShiftParams, new EDrtShiftStartLogic(new DefaultShiftStartLogic()), new EDrtAssignShiftToVehicleLogic(new DefaultAssignShiftToVehicleLogic(drtShiftParams), drtShiftParams)), getter.getModal(Fleet.class)))).asEagerSingleton(); - bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter -> new ShiftVehicleDataEntryFactory(new EDrtVehicleDataEntryFactory(drtCfg, 0)))).asEagerSingleton(); + bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter -> new ShiftVehicleDataEntryFactory(new EDrtVehicleDataEntryFactory(0)))).asEagerSingleton(); - final ShiftEDrtTaskFactoryImpl taskFactory = new ShiftEDrtTaskFactoryImpl(new EDrtTaskFactoryImpl()); - bindModal(DrtTaskFactory.class).toInstance(taskFactory); - bindModal(ShiftDrtTaskFactory.class).toInstance(taskFactory); + bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> new ShiftEDrtTaskFactoryImpl(new EDrtTaskFactoryImpl(), getter.getModal(OperationFacilities.class)))).in(Singleton.class); + bindModal(ShiftDrtTaskFactory.class).toProvider(modalProvider(getter -> ((ShiftDrtTaskFactory) getter.getModal(DrtTaskFactory.class)))); bindModal(ShiftTaskScheduler.class).toProvider(modalProvider( getter -> new EShiftTaskScheduler(getter.getModal(Network.class), getter.getModal(TravelTime.class), getter.getModal(TravelDisutilityFactory.class).createTravelDisutility(getter.getModal(TravelTime.class)), - getter.get(MobsimTimer.class), taskFactory, drtShiftParams, getter.getModal(ChargingInfrastructure.class), + getter.get(MobsimTimer.class), getter.getModal(ShiftDrtTaskFactory.class), drtShiftParams, getter.getModal(ChargingInfrastructure.class), getter.getModal(OperationFacilities.class), getter.getModal(Fleet.class)) )).asEagerSingleton(); - bindModal(VrpAgentLogic.DynActionCreator.class).toProvider(modalProvider( - getter -> new ShiftEDrtActionCreator(getter.getModal(PassengerHandler.class), - getter.get(MobsimTimer.class), getter.get(DvrpConfigGroup.class))) - ).asEagerSingleton(); + // See EDrtModeOptimizerQSimModule + bindModal(VrpLegFactory.class).toProvider(modalProvider(getter -> { + DvrpConfigGroup dvrpCfg = getter.get(DvrpConfigGroup.class); + MobsimTimer timer = getter.get(MobsimTimer.class); + + // Makes basic DrtActionCreator create legs with consumption tracker + return v -> EDrtActionCreator.createLeg(dvrpCfg.mobsimMode, v, timer); + })).in(Singleton.class); + + bindModal(ShiftEDrtActionCreator.class).toProvider(modalProvider(getter -> { + VrpAgentLogic.DynActionCreator delegate = drtCfg.getPrebookingParams().isPresent() + ? getter.getModal(PrebookingActionCreator.class) + : getter.getModal(DrtActionCreator.class); + + return new ShiftEDrtActionCreator( + new ShiftDrtActionCreator(getter.getModal(PassengerHandler.class), delegate), + getter.get(MobsimTimer.class), getter.getModal(PassengerHandler.class)); + })).asEagerSingleton(); + + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(ShiftEDrtActionCreator.class)); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtShiftChangeoverTaskImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtShiftChangeoverTaskImpl.java index 9cc818dace7..007a9f2fe3f 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtShiftChangeoverTaskImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtShiftChangeoverTaskImpl.java @@ -82,4 +82,14 @@ public void addDropoffRequest(AcceptedDrtRequest request) { public void addPickupRequest(AcceptedDrtRequest request) { delegate.addPickupRequest(request); } + + @Override + public void removePickupRequest(Id requestId) { + delegate.removePickupRequest(requestId); + } + + @Override + public void removeDropoffRequest(Id requestId) { + delegate.removeDropoffRequest(requestId); + } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java index ba473f314ba..4604771bed9 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java @@ -2,26 +2,17 @@ import org.matsim.contrib.drt.extension.operations.eshifts.charging.ChargingBreakActivity; import org.matsim.contrib.drt.extension.operations.eshifts.charging.ChargingChangeoverActivity; +import org.matsim.contrib.drt.extension.operations.eshifts.charging.ChargingWaitForShiftActivity; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtActionCreator; import org.matsim.contrib.drt.schedule.DrtStopTask; -import org.matsim.contrib.drt.vrpagent.DrtActionCreator; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.passenger.PassengerHandler; -import org.matsim.contrib.dvrp.run.DvrpConfigGroup; -import org.matsim.contrib.dvrp.schedule.DriveTask; import org.matsim.contrib.dvrp.schedule.Task; -import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; -import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTrackerImpl; -import org.matsim.contrib.dvrp.tracker.OnlineTrackerListener; -import org.matsim.contrib.dvrp.tracker.TaskTrackers; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic.DynActionCreator; -import org.matsim.contrib.dvrp.vrpagent.VrpLeg; import org.matsim.contrib.dynagent.DynAction; import org.matsim.contrib.dynagent.DynAgent; -import org.matsim.contrib.drt.extension.operations.eshifts.charging.ChargingWaitForShiftActivity; import org.matsim.contrib.evrp.EvDvrpVehicle; import org.matsim.contrib.evrp.tracker.OfflineETaskTracker; -import org.matsim.contrib.evrp.tracker.OnlineEDriveTaskTracker; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtActionCreator; import org.matsim.core.mobsim.framework.MobsimTimer; /** @@ -29,19 +20,12 @@ */ public class ShiftEDrtActionCreator implements DynActionCreator { - private final DynActionCreator drtActionCreator; + private final ShiftDrtActionCreator delegate; private final MobsimTimer timer; private final PassengerHandler passengerHandler; - public ShiftEDrtActionCreator(PassengerHandler passengerHandler, MobsimTimer timer, DvrpConfigGroup dvrpCfg) { - this.timer = timer; - this.passengerHandler = passengerHandler; - drtActionCreator = new ShiftDrtActionCreator(passengerHandler, new DrtActionCreator(passengerHandler, - v -> createLeg(dvrpCfg.mobsimMode, v, timer))); - } - - public ShiftEDrtActionCreator(DynActionCreator delegate, MobsimTimer timer, PassengerHandler passengerHandler) { - this.drtActionCreator = delegate; + public ShiftEDrtActionCreator(ShiftDrtActionCreator delegate, MobsimTimer timer, PassengerHandler passengerHandler) { + this.delegate = delegate; this.timer = timer; this.passengerHandler = passengerHandler; } @@ -63,21 +47,10 @@ public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now return new ChargingWaitForShiftActivity(((EDrtWaitForShiftStayTask) task).getChargingTask()); } - DynAction dynAction = drtActionCreator.createAction(dynAgent, vehicle, now); + DynAction dynAction = delegate.createAction(dynAgent, vehicle, now); if (task.getTaskTracker() == null) { task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle) vehicle, timer)); } return dynAction; } - - private static VrpLeg createLeg(String mobsimMode, DvrpVehicle vehicle, MobsimTimer timer) { - DriveTask driveTask = (DriveTask) vehicle.getSchedule().getCurrentTask(); - VrpLeg leg = new VrpLeg(mobsimMode, driveTask.getPath()); - OnlineDriveTaskTracker onlineTracker = new OnlineDriveTaskTrackerImpl(vehicle, leg, - OnlineTrackerListener.NO_LISTENER, timer); - OnlineEDriveTaskTracker onlineETracker = new OnlineEDriveTaskTracker((EvDvrpVehicle) vehicle, timer, - onlineTracker); - TaskTrackers.initOnlineDriveTaskTracking(vehicle, leg, onlineETracker); - return leg; - } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java index e7ff875f574..5e0c085c1bb 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java @@ -1,25 +1,34 @@ package org.matsim.contrib.drt.extension.operations.eshifts.schedule; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilities; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeOverTask; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtTaskFactory; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask; import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift; +import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak; import org.matsim.contrib.drt.schedule.DrtDriveTask; import org.matsim.contrib.drt.schedule.DrtStayTask; import org.matsim.contrib.drt.schedule.DrtStopTask; import org.matsim.contrib.drt.schedule.DrtTaskType; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; -import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; -import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; import org.matsim.contrib.ev.infrastructure.Charger; import org.matsim.contrib.evrp.ChargingTask; import org.matsim.contrib.evrp.ChargingTaskImpl; import org.matsim.contrib.evrp.EvDvrpVehicle; -import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeOverTask; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtTaskFactory; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak; +import org.matsim.facilities.Facility; + +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Collectors; /** * @author nkuehnel / MOIA @@ -27,10 +36,14 @@ public class ShiftEDrtTaskFactoryImpl implements ShiftDrtTaskFactory { private final EDrtTaskFactoryImpl delegate; + private final OperationFacilities operationFacilities; - public ShiftEDrtTaskFactoryImpl(EDrtTaskFactoryImpl delegate) { + + public ShiftEDrtTaskFactoryImpl(EDrtTaskFactoryImpl delegate, OperationFacilities operationFacilities) { this.delegate = delegate; - } + this.operationFacilities = operationFacilities; + + } @Override public DrtDriveTask createDriveTask(DvrpVehicle vehicle, VrpPathWithTravelData path, DrtTaskType drtTaskType) { @@ -47,7 +60,26 @@ public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double return delegate.createStayTask(vehicle, beginTime, endTime, link); } - @Override + @Override + public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + final Map, List> facilitiesByLink = operationFacilities.getDrtOperationFacilities().values().stream().collect(Collectors.groupingBy(Facility::getLinkId)); + final OperationFacility operationFacility; + try { + operationFacility = facilitiesByLink.get(vehicle.getStartLink().getId()).stream().findFirst().orElseThrow((Supplier) () -> new RuntimeException("Vehicles must start at an operation facility!")); + } catch (Throwable e) { + throw new RuntimeException(e); + } + WaitForShiftStayTask waitForShiftStayTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(), + vehicle.getStartLink(), operationFacility); + boolean success = operationFacility.register(vehicle.getId()); + if (!success) { + throw new RuntimeException(String.format("Cannot register vehicle %s at facility %s at start-up. Please check" + + "facility capacity and initial fleet distribution.", vehicle.getId().toString(), operationFacility.getId().toString())); + } + return waitForShiftStayTask; + } + + @Override public ShiftBreakTask createShiftBreakTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link, DrtShiftBreak shiftBreak, OperationFacility facility) { return new EDrtShiftBreakTaskImpl(beginTime, endTime, link, shiftBreak, 0, null, facility); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java index 83f74ad89e0..7352f32c261 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java @@ -74,7 +74,6 @@ public EShiftTaskScheduler(Network network, TravelTime travelTime, TravelDisutil this.shiftsParams = shiftsParams; this.router = new SpeedyALTFactory().createPathCalculator(network, travelDisutility, travelTime); this.chargingInfrastructure = chargingInfrastructure; - ShiftSchedules.initSchedules(operationFacilities, fleet, taskFactory); } public void relocateForBreak(ShiftDvrpVehicle vehicle, OperationFacility breakFacility, DrtShift shift) { diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/BreakCorridorXY.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/BreakCorridorXY.java index 3a3b0762936..320b23977f9 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/BreakCorridorXY.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/BreakCorridorXY.java @@ -10,12 +10,12 @@ import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftsSpecification; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; import jakarta.inject.Provider; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.io.UncheckedIOException; import java.util.HashMap; import java.util.Map; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftAnalysisControlerListener.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftAnalysisControlerListener.java index 2db2c3d8fec..60c9c9e1cb0 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftAnalysisControlerListener.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftAnalysisControlerListener.java @@ -52,9 +52,10 @@ public ShiftAnalysisControlerListener(Config config, DrtConfigGroup drtConfigGro @Override public void notifyIterationEnds(IterationEndsEvent event) { - boolean createGraphs = event.getServices().getConfig().controler().isCreateGraphs(); + int createGraphsInterval = event.getServices().getConfig().controller().getCreateGraphsInterval(); + boolean createGraphs = createGraphsInterval >0 && event.getIteration() % createGraphsInterval == 0; - writeAndPlotShiftDurationComparison(shiftDurationXY.getShift2plannedVsActualDuration(), + writeAndPlotShiftDurationComparison(shiftDurationXY.getShift2plannedVsActualDuration(), filename(event, "shiftDurationComparison", ".png"), filename(event, "shiftDurationComparison", ".csv"), createGraphs); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftDurationXY.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftDurationXY.java index f370d7f6b4f..d2ff4dda184 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftDurationXY.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftDurationXY.java @@ -9,11 +9,11 @@ import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftsSpecification; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.io.UncheckedIOException; import java.util.HashMap; import java.util.Map; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogram.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogram.java index d4a519129fc..ce228469e50 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogram.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogram.java @@ -6,12 +6,12 @@ import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift; import org.matsim.core.config.Config; import org.matsim.core.utils.io.IOUtils; -import org.matsim.core.utils.io.UncheckedIOException; import org.matsim.core.utils.misc.Time; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.io.UncheckedIOException; import java.util.Set; /** diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramChart.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramChart.java index bd877f2843d..d39236c91ee 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramChart.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramChart.java @@ -9,11 +9,11 @@ import org.jfree.chart.plot.XYPlot; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; -import org.matsim.core.utils.io.UncheckedIOException; import java.awt.*; import java.io.File; import java.io.IOException; +import java.io.UncheckedIOException; /** * @author nkuehnel / MOIA diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramListener.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramListener.java index 18525c18a7f..aceaa023f7d 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramListener.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/ShiftHistogramListener.java @@ -35,7 +35,9 @@ public void notifyIterationStarts(final IterationStartsEvent event) { public void notifyIterationEnds(final IterationEndsEvent event) { this.shiftHistogram.write(matsimServices.getControlerIO().getIterationFilename(event.getIteration(), drtConfigGroup.getMode() + "_" + "shiftHistogram.txt")); this.printStats(); - boolean createGraphs = event.getServices().getConfig().controler().isCreateGraphs(); + int createGraphsInterval = event.getServices().getConfig().controller().getCreateGraphsInterval(); + boolean createGraphs = createGraphsInterval >0 && event.getIteration() % createGraphsInterval == 0; + if (createGraphs) { ShiftHistogramChart.writeGraphic(this.shiftHistogram, matsimServices.getControlerIO().getIterationFilename(event.getIteration(),drtConfigGroup.getMode() + "_" + "shiftHistogram.png")); } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyAnalysisControlerListener.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyAnalysisControlerListener.java index a7b7c8248ed..57e451f31b0 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyAnalysisControlerListener.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyAnalysisControlerListener.java @@ -56,9 +56,10 @@ public ShiftEfficiencyAnalysisControlerListener(DrtConfigGroup drtConfigGroup, @Override public void notifyIterationEnds(IterationEndsEvent event) { - boolean createGraphs = event.getServices().getConfig().controler().isCreateGraphs(); + int createGraphsInterval = event.getServices().getConfig().controller().getCreateGraphsInterval(); + boolean createGraphs = createGraphsInterval >0 && event.getIteration() % createGraphsInterval == 0; - writeAndPlotShiftEfficiency( + writeAndPlotShiftEfficiency( shiftEfficiencyTracker.getCurrentRecord().getRevenueByShift(), shiftEfficiencyTracker.getCurrentRecord().getRequestsByShift(), shiftEfficiencyTracker.getCurrentRecord().getFinishedShifts(), diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java index d51712bd996..2f7944d5b9d 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java @@ -13,7 +13,6 @@ import org.matsim.core.config.ConfigGroup; import java.net.URL; -import java.util.Map; /** * @author nkuehnel / MOIA @@ -30,6 +29,10 @@ public class ShiftsParams extends ReflectiveConfigGroupWithConfigurableParameter @Comment("changeover duration in [seconds]") public double changeoverDuration = 900; + @Parameter + @Comment("maximum delay of shift assignment after start time has passed in [seconds]. If a shift can not be assigned to a vehicle until the planned start of the shift plus the defined max delay, the shift is discarded. Defaults to 0") + public double maxUnscheduledShiftDelay = 0; + @Parameter @Comment("Time of shift assignment (i.e. which vehicle carries out a specific shift) before start of shift in [seconds]") public double shiftScheduleLookAhead = 1800; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java index dd0b17860ea..cb9e5d76a9f 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java @@ -22,10 +22,10 @@ public class DefaultShiftStartLogic implements ShiftStartLogic { @Override public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry peek) { // old shift hasn't ended yet - if (!peek.shift.equals(peek.vehicle.getShifts().peek())) { + if (!peek.shift().equals(peek.vehicle().getShifts().peek())) { return false; } - Schedule schedule = peek.vehicle.getSchedule(); + Schedule schedule = peek.vehicle().getSchedule(); // only active vehicles if (schedule.getStatus() != Schedule.ScheduleStatus.STARTED) { @@ -36,8 +36,8 @@ public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry peek) { Task currentTask = schedule.getCurrentTask(); if(currentTask instanceof WaitForShiftStayTask) { //check if optional location requirement is met - if(peek.shift.getOperationFacilityId().isPresent()) { - Id operationFacilityId = peek.shift.getOperationFacilityId().get(); + if(peek.shift().getOperationFacilityId().isPresent()) { + Id operationFacilityId = peek.shift().getOperationFacilityId().get(); Verify.verify((operationFacilityId.equals(((WaitForShiftStayTask) currentTask).getFacility().getId())), "Vehicle and shift start locations do not match."); } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcher.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcher.java index 8bb205b7635..4fd44648565 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcher.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcher.java @@ -12,15 +12,9 @@ */ public interface DrtShiftDispatcher { - final class ShiftEntry { - public final DrtShift shift; - public final ShiftDvrpVehicle vehicle; - - public ShiftEntry(DrtShift shift, ShiftDvrpVehicle vehicle) { - this.shift = shift; - this.vehicle = vehicle; - } - } + void initialize(); + + record ShiftEntry(DrtShift shift, ShiftDvrpVehicle vehicle){} void dispatch(double timeStep); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java index 1fd6de1e5b0..4c070bc1ebf 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java @@ -89,16 +89,15 @@ public DrtShiftDispatcherImpl(DrtShifts shifts, Fleet fleet, MobsimTimer timer, this.drtShiftParams = drtShiftParams; this.shiftStartLogic = shiftStartLogic; this.assignShiftToVehicleLogic = assignShiftToVehicleLogic; - - createQueues(); } + @Override + public void initialize() { - private void createQueues() { unscheduledShifts = new PriorityQueue<>(Comparator.comparingDouble(DrtShift::getStartTime)); unscheduledShifts.addAll(shifts.getShifts().values()); - assignedShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getStartTime())); + assignedShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getStartTime())); idleVehiclesQueues = new LinkedHashMap<>(); for(OperationFacility facility: operationFacilities.getDrtOperationFacilities().values()) { @@ -112,11 +111,11 @@ private void createQueues() { queue ); } - activeShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getEndTime())); - endingShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getEndTime())); + activeShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); + endingShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); } - @Override + @Override public void dispatch(double timeStep) { if(timeStep % drtShiftParams.loggingInterval == 0) { logger.info(String.format("Active shifts: %s | Assigned shifts: %s | Unscheduled shifts: %s", @@ -136,13 +135,13 @@ public void dispatch(double timeStep) { private void checkBreaks() { for (ShiftEntry activeShift : activeShifts) { - final DrtShift shift = activeShift.shift; + final DrtShift shift = activeShift.shift(); if (shift != null && shift.isStarted()) { OperationFacility breakFacility = decideOnBreak(activeShift); if (breakFacility != null) { - shiftTaskScheduler.relocateForBreak(activeShift.vehicle, breakFacility, shift); + shiftTaskScheduler.relocateForBreak(activeShift.vehicle(), breakFacility, shift); eventsManager.processEvent(new DrtShiftBreakScheduledEvent(timer.getTimeOfDay(), shift.getId(), - activeShift.vehicle.getId(), breakFacility.getLinkId(), + activeShift.vehicle().getId(), breakFacility.getLinkId(), shift.getBreak().orElseThrow().getScheduledLatestArrival())); } } @@ -154,23 +153,23 @@ private void startShifts(double timeStep) { final Iterator iterator = this.assignedShifts.iterator(); while (iterator.hasNext()) { final ShiftEntry next = iterator.next(); - if (next.shift.getStartTime() > timeStep) { + if (next.shift().getStartTime() > timeStep) { break; - } else if (next.shift.getEndTime() < timeStep) { - logger.warn("Too late to start shift " + next.shift.getId()); - next.vehicle.getShifts().remove(next.shift); + } else if (next.shift().getEndTime() < timeStep) { + logger.warn("Too late to start shift " + next.shift().getId()); + next.vehicle().getShifts().remove(next.shift()); iterator.remove(); continue; } if (shiftStartLogic.shiftStarts(next)) { - next.shift.start(); - shiftTaskScheduler.startShift(next.vehicle, timeStep, next.shift); + next.shift().start(); + shiftTaskScheduler.startShift(next.vehicle(), timeStep, next.shift()); activeShifts.add(next); iterator.remove(); - logger.debug("Started shift " + next.shift); - StayTask currentTask = (StayTask) next.vehicle.getSchedule().getCurrentTask(); - eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, next.shift.getId(), next.vehicle.getId(), + logger.debug("Started shift " + next.shift()); + StayTask currentTask = (StayTask) next.vehicle().getSchedule().getCurrentTask(); + eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, next.shift().getId(), next.vehicle().getId(), currentTask.getLink().getId())); } } @@ -178,7 +177,13 @@ private void startShifts(double timeStep) { private void assignShifts(double timeStep) { // Remove elapsed shifts - unscheduledShifts.removeIf(shift -> shift.getStartTime() < timeStep); + unscheduledShifts.removeIf(shift -> { + if (shift.getStartTime() + drtShiftParams.maxUnscheduledShiftDelay < timeStep ) { + logger.warn("Shift with ID " + shift.getId() + " could not be assigned and is being removed as start time is longer in the past than defined by maxUnscheduledShiftDelay."); + return true; + } + return false; + }); // Assign shifts Set assignableShifts = new LinkedHashSet<>(); @@ -190,20 +195,20 @@ private void assignShifts(double timeStep) { ShiftDvrpVehicle vehicle = null; for (ShiftEntry active : activeShifts) { - if (active.shift.getEndTime() > shift.getStartTime()) { + if (active.shift().getEndTime() > shift.getStartTime()) { break; } if(shift.getOperationFacilityId().isPresent()) { //we have to check that the vehicle ends the previous shift at the same facility where //the new shift is to start. - if(active.shift.getOperationFacilityId().isPresent()) { - if(!active.shift.getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) { + if(active.shift().getOperationFacilityId().isPresent()) { + if(!active.shift().getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) { continue; } } else { - Optional nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle.getSchedule()); + Optional nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle().getSchedule()); if(nextShiftChangeover.isPresent()) { - Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift)); + Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift())); if(!nextShiftChangeover.get().getFacility().getId().equals(shift.getOperationFacilityId().get())) { // there is already a shift changeover scheduled elsewhere continue; @@ -211,8 +216,8 @@ private void assignShifts(double timeStep) { } } } - if (assignShiftToVehicleLogic.canAssignVehicleToShift(active.vehicle, shift)) { - vehicle = active.vehicle; + if (assignShiftToVehicleLogic.canAssignVehicleToShift(active.vehicle(), shift)) { + vehicle = active.vehicle(); break; } } @@ -266,17 +271,17 @@ private void endShifts(double timeStep) { while (iterator.hasNext()) { final ShiftEntry next = iterator.next(); - if (timeStep + drtShiftParams.shiftEndLookAhead < next.shift.getEndTime()) { + if (timeStep + drtShiftParams.shiftEndLookAhead < next.shift().getEndTime()) { continue; } - final DrtShift active = next.shift; + final DrtShift active = next.shift(); - if (active != next.vehicle.getShifts().peek()) { + if (active != next.vehicle().getShifts().peek()) { throw new IllegalStateException("Shifts don't match!"); } - logger.debug("Scheduling shift end for shift " + next.shift.getId() + " of vehicle " + next.vehicle.getId()); + logger.debug("Scheduling shift end for shift " + next.shift().getId() + " of vehicle " + next.vehicle().getId()); scheduleShiftEnd(next); endingShifts.add(next); iterator.remove(); @@ -287,12 +292,12 @@ private void updateShiftEnds(double timeStep) { final Iterator endingShiftsIterator = this.endingShifts.iterator(); while (endingShiftsIterator.hasNext()) { final ShiftEntry next = endingShiftsIterator.next(); - if (next.shift.isEnded()) { + if (next.shift().isEnded()) { endingShiftsIterator.remove(); continue; } - if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift.getEndTime()) { - if (next.vehicle.getShifts().size() > 1) { + if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift().getEndTime()) { + if (next.vehicle().getShifts().size() > 1) { updateShiftEnd(next); } } else { @@ -303,17 +308,17 @@ private void updateShiftEnds(double timeStep) { private void updateShiftEnd(ShiftEntry next) { - if(next.shift.getOperationFacilityId().isPresent()) { + if(next.shift().getOperationFacilityId().isPresent()) { //start and end facility are fixed return; } - final List tasks = next.vehicle.getSchedule().getTasks(); + final List tasks = next.vehicle().getSchedule().getTasks(); Task lastTask = null; LinkTimePair start = null; ShiftChangeOverTask changeOverTask = null; - final Task currentTask = next.vehicle.getSchedule().getCurrentTask(); + final Task currentTask = next.vehicle().getSchedule().getCurrentTask(); for (Task task : tasks.subList(currentTask.getTaskIdx(), tasks.size())) { if (task instanceof ShiftChangeOverTask) { changeOverTask = (ShiftChangeOverTask) task; @@ -359,13 +364,13 @@ private void updateShiftEnd(ShiftEntry next) { if (shiftChangeFacility != null && changeOverTask != null && !(shiftChangeFacility.getId().equals(changeOverTask.getFacility().getId()))) { if (shiftChangeFacility.hasCapacity()) { - if (shiftTaskScheduler.updateShiftChange(next.vehicle, - network.getLinks().get(shiftChangeFacility.getLinkId()), next.shift, start, + if (shiftTaskScheduler.updateShiftChange(next.vehicle(), + network.getLinks().get(shiftChangeFacility.getLinkId()), next.shift(), start, shiftChangeFacility, lastTask)) { - shiftChangeFacility.register(next.vehicle.getId()); - changeOverTask.getFacility().deregisterVehicle(next.vehicle.getId()); + shiftChangeFacility.register(next.vehicle().getId()); + changeOverTask.getFacility().deregisterVehicle(next.vehicle().getId()); eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), - next.vehicle.getId(), shiftChangeFacility.getId())); + next.vehicle().getId(), shiftChangeFacility.getId())); } } } @@ -373,7 +378,7 @@ private void updateShiftEnd(ShiftEntry next) { private void scheduleShiftEnd(ShiftEntry endingShift) { // hub return - final Schedule schedule = endingShift.vehicle.getSchedule(); + final Schedule schedule = endingShift.vehicle().getSchedule(); Task currentTask = schedule.getCurrentTask(); Link lastLink; @@ -395,14 +400,14 @@ private void scheduleShiftEnd(ShiftEntry endingShift) { OperationFacility shiftChangeoverFacility = null; //check whether current shift has to end at specific facility - if(endingShift.shift.getOperationFacilityId().isPresent()) { + if(endingShift.shift().getOperationFacilityId().isPresent()) { shiftChangeoverFacility = operationFacilities .getDrtOperationFacilities() - .get(endingShift.shift.getOperationFacilityId().get()); + .get(endingShift.shift().getOperationFacilityId().get()); } else { //check whether next shift has to start at specific facility - for (DrtShift shift : endingShift.vehicle.getShifts()) { - if (shift != endingShift.shift) { + for (DrtShift shift : endingShift.vehicle().getShifts()) { + if (shift != endingShift.shift()) { if (shift.getOperationFacilityId().isPresent()) { shiftChangeoverFacility = operationFacilities .getDrtOperationFacilities() @@ -418,10 +423,10 @@ private void scheduleShiftEnd(ShiftEntry endingShift) { OperationFacilityType.hub); } - if (shiftChangeoverFacility != null && shiftChangeoverFacility.register(endingShift.vehicle.getId())) { - shiftTaskScheduler.relocateForShiftChange(endingShift.vehicle, - network.getLinks().get(shiftChangeoverFacility.getLinkId()), endingShift.shift, shiftChangeoverFacility); - eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), endingShift.vehicle.getId(), + if (shiftChangeoverFacility != null && shiftChangeoverFacility.register(endingShift.vehicle().getId())) { + shiftTaskScheduler.relocateForShiftChange(endingShift.vehicle(), + network.getLinks().get(shiftChangeoverFacility.getLinkId()), endingShift.shift(), shiftChangeoverFacility); + eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), endingShift.vehicle().getId(), shiftChangeoverFacility.getId())); } else { throw new RuntimeException("Could not find shift end location!"); @@ -429,9 +434,9 @@ private void scheduleShiftEnd(ShiftEntry endingShift) { } private OperationFacility decideOnBreak(ShiftEntry activeShift) { - if (activeShift.shift != null) { - if (shiftNeedsBreak(activeShift.shift, timer.getTimeOfDay())) { - final Schedule schedule = activeShift.vehicle.getSchedule(); + if (activeShift.shift() != null) { + if (shiftNeedsBreak(activeShift.shift(), timer.getTimeOfDay())) { + final Schedule schedule = activeShift.vehicle().getSchedule(); Task currentTask = schedule.getCurrentTask(); Link lastLink; if (currentTask instanceof DriveTask @@ -451,9 +456,9 @@ private OperationFacility decideOnBreak(ShiftEntry activeShift) { if (shiftBreakFacility == null) { throw new RuntimeException("Could not schedule break!"); } - if (shiftBreakFacility.register(activeShift.vehicle.getId())) { + if (shiftBreakFacility.register(activeShift.vehicle().getId())) { eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), - activeShift.vehicle.getId(), shiftBreakFacility.getId())); + activeShift.vehicle().getId(), shiftBreakFacility.getId())); return shiftBreakFacility; } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/DrtShiftsWriter.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/DrtShiftsWriter.java index 92d3c43812d..0d5f56e5d75 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/DrtShiftsWriter.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/DrtShiftsWriter.java @@ -11,9 +11,9 @@ import org.matsim.core.gbl.Gbl; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.io.MatsimXmlWriter; -import org.matsim.core.utils.io.UncheckedIOException; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.*; import java.util.stream.Collectors; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/OperationFacilitiesWriter.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/OperationFacilitiesWriter.java index 22c3a1712e5..91b247738d1 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/OperationFacilitiesWriter.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/io/OperationFacilitiesWriter.java @@ -11,9 +11,9 @@ import org.matsim.core.gbl.Gbl; import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.io.MatsimXmlWriter; -import org.matsim.core.utils.io.UncheckedIOException; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.*; import java.util.stream.Collectors; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftDrtOptimizer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftDrtOptimizer.java index f4ab679edd1..0ad63243a61 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftDrtOptimizer.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftDrtOptimizer.java @@ -10,11 +10,13 @@ import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.contrib.dvrp.schedule.Task; import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; /** * @author nkuehnel, fzwick / MOIA */ -public class ShiftDrtOptimizer implements DrtOptimizer { +public class ShiftDrtOptimizer implements DrtOptimizer, MobsimInitializedListener { private final DrtOptimizer optimizer; @@ -67,4 +69,8 @@ public void requestSubmitted(Request request) { this.optimizer.requestSubmitted(request); } + @Override + public void notifyMobsimInitialized(MobsimInitializedEvent e) { + dispatcher.initialize(); + } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftRequestInsertionScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftRequestInsertionScheduler.java deleted file mode 100644 index a4feba591cf..00000000000 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftRequestInsertionScheduler.java +++ /dev/null @@ -1,375 +0,0 @@ -package org.matsim.contrib.drt.extension.operations.shifts.optimizer; - -import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.DRIVE; -import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; - -import java.util.List; - -import org.matsim.api.core.v01.network.Link; -import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.OperationalStop; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeOverTask; -import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtTaskFactory; -import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftTaskScheduler; -import org.matsim.contrib.drt.optimizer.VehicleEntry; -import org.matsim.contrib.drt.optimizer.Waypoint; -import org.matsim.contrib.drt.optimizer.insertion.InsertionWithDetourData; -import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; -import org.matsim.contrib.drt.schedule.DrtDriveTask; -import org.matsim.contrib.drt.schedule.DrtStayTask; -import org.matsim.contrib.drt.schedule.DrtStopTask; -import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler; -import org.matsim.contrib.drt.stops.StopTimeCalculator; -import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; -import org.matsim.contrib.dvrp.path.VrpPaths; -import org.matsim.contrib.dvrp.schedule.Schedule; -import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; -import org.matsim.contrib.dvrp.schedule.StayTask; -import org.matsim.contrib.dvrp.schedule.Task; -import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; -import org.matsim.contrib.dvrp.util.LinkTimePair; -import org.matsim.core.mobsim.framework.MobsimTimer; -import org.matsim.core.router.util.TravelTime; - -/** - * @author nkuehnel / MOIA - */ -public class ShiftRequestInsertionScheduler implements RequestInsertionScheduler { - - private final MobsimTimer timer; - private final TravelTime travelTime; - private final ScheduleTimingUpdater scheduleTimingUpdater; - private final ShiftDrtTaskFactory taskFactory; - private StopTimeCalculator stopTimeCalculator; - - - public ShiftRequestInsertionScheduler(MobsimTimer timer, TravelTime travelTime, - ScheduleTimingUpdater scheduleTimingUpdater, ShiftDrtTaskFactory taskFactory, - StopTimeCalculator stopTimeCalculator) { - this.timer = timer; - this.travelTime = travelTime; - this.scheduleTimingUpdater = scheduleTimingUpdater; - this.taskFactory = taskFactory; - this.stopTimeCalculator = stopTimeCalculator; - } - - - @Override - public PickupDropoffTaskPair scheduleRequest(AcceptedDrtRequest request, InsertionWithDetourData insertion) { - var pickupTask = insertPickup(request, insertion); - var dropoffTask = insertDropoff(request, insertion, pickupTask); - return new PickupDropoffTaskPair(pickupTask, dropoffTask); - } - - private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetourData insertionWithDetourData) { - var insertion = insertionWithDetourData.insertion; - VehicleEntry vehicleEntry = insertion.vehicleEntry; - Schedule schedule = vehicleEntry.vehicle.getSchedule(); - List stops = vehicleEntry.stops; - int pickupIdx = insertion.pickup.index; - int dropoffIdx = insertion.dropoff.index; - var detourData = insertionWithDetourData.detourData; - - Schedule.ScheduleStatus scheduleStatus = schedule.getStatus(); - Task currentTask = scheduleStatus == Schedule.ScheduleStatus.PLANNED ? null : schedule.getCurrentTask(); - Task beforePickupTask; - - if (pickupIdx == 0 && scheduleStatus != Schedule.ScheduleStatus.PLANNED && DRIVE.isBaseTypeOf(currentTask)) { - LinkTimePair diversion = ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).getDiversionPoint(); - if (diversion != null) { // divert vehicle - beforePickupTask = currentTask; - VrpPathWithTravelData vrpPath = VrpPaths.createPath(vehicleEntry.start.link, request.getFromLink(), - vehicleEntry.start.time, detourData.detourToPickup, travelTime); - ((OnlineDriveTaskTracker) beforePickupTask.getTaskTracker()).divertPath(vrpPath); - } else { // too late for diversion - if (request.getFromLink() != vehicleEntry.start.link) { // add a new drive task - VrpPathWithTravelData vrpPath = VrpPaths.createPath(vehicleEntry.start.link, request.getFromLink(), - vehicleEntry.start.time, detourData.detourToPickup, travelTime); - beforePickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(currentTask.getTaskIdx() + 1, beforePickupTask); - } else { // no need for a new drive task - beforePickupTask = currentTask; - } - } - } else { // insert pickup after an existing stop/stay task - DrtStayTask stayTask = null; - DrtStopTask stopTask = null; - if (pickupIdx == 0) { - if (scheduleStatus == Schedule.ScheduleStatus.PLANNED) {// PLANNED schedule - stayTask = (DrtStayTask) schedule.getTasks().get(0); - stayTask.setEndTime(stayTask.getBeginTime());// could get later removed with ScheduleTimingUpdater - } else if (STAY.isBaseTypeOf(currentTask)) { - stayTask = (DrtStayTask) currentTask; // ongoing stay task - double now = timer.getTimeOfDay(); - if (stayTask.getEndTime() > now) { // stop stay task; a new stop/drive task can be inserted now - stayTask.setEndTime(now); - } - } else { - stopTask = (DrtStopTask) currentTask; // ongoing stop task - } - } else { - stopTask = stops.get(pickupIdx - 1).task; // future stop task - } - - if (stopTask != null && request.getFromLink() == stopTask.getLink()) { // no detour; no new stop task - // add pickup request to stop task - stopTask.addPickupRequest(request); - if (stopTask instanceof OperationalStop) { - if (request.getEarliestStartTime() > stopTask.getEndTime()) { - throw new RuntimeException("Cannot serve request!"); - } - } else { - /* - * TODO: insertionTime should be set to "now" here to avoid adding pickups to - * ongoing tasks "for free" and generating requests with zero wait time. See - * InsertionDetourTimeCalculator.calculatePickupIfSameLink for more details. - */ - - double insertionTime = stopTask.getBeginTime(); - stopTask.setEndTime(stopTimeCalculator.updateEndTimeForPickup(vehicleEntry.vehicle, stopTask, - insertionTime, request.getRequest())); - } - - /// ADDED - //// TODO this is copied, but has not been updated !!!!!!!!!!!!!!! - // add drive from pickup - if (pickupIdx == dropoffIdx) { - // remove drive i->i+1 (if there is one) - if (pickupIdx < stops.size()) {// there is at least one following stop - DrtStopTask nextStopTask = stops.get(pickupIdx).task; - if (nextStopTask instanceof ShiftChangeOverTask) { - if (stopTask.getTaskIdx() + 3 != nextStopTask.getTaskIdx()) {// there must a drive and stay task in - // between - throw new RuntimeException(); - } - } else if (stopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx()) {// there must a drive task in - // between - throw new RuntimeException(); - } - if (nextStopTask instanceof ShiftChangeOverTask) { - if (stopTask.getTaskIdx() + 3 == nextStopTask.getTaskIdx()) {// there must a drive task and stay in - // between - int driveTaskIdx = stopTask.getTaskIdx() + 1; - final Task task = schedule.getTasks().get(driveTaskIdx); - schedule.removeTask(task); - } - } else { - if (stopTask.getTaskIdx() + 2 == nextStopTask.getTaskIdx()) {// there must a drive task in - // between - int driveTaskIdx = stopTask.getTaskIdx() + 1; - final Task task = schedule.getTasks().get(driveTaskIdx); - schedule.removeTask(task); - } - } - } - - Link toLink = request.getToLink(); // pickup->dropoff - - VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getFromLink(), toLink, - stopTask.getEndTime(), detourData.detourFromPickup, travelTime); - Task driveFromPickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, - DrtDriveTask.TYPE); - schedule.addTask(stopTask.getTaskIdx() + 1, driveFromPickupTask); - - // update timings - // TODO should be enough to update the timeline only till dropoffIdx... - scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, - stopTask.getTaskIdx() + 2, driveFromPickupTask.getEndTime()); - /////// - } - - return stopTask; - } else { - StayTask stayOrStopTask = stayTask != null ? stayTask : stopTask; - - // remove drive i->i+1 (if there is one) - if (pickupIdx < stops.size()) {// there is at least one following stop - - DrtStopTask nextStopTask = stops.get(pickupIdx).task; - - if (nextStopTask instanceof ShiftChangeOverTask) { - if (stayOrStopTask.getTaskIdx() + 3 == nextStopTask.getTaskIdx()) { - // removing the drive task that is in between - int driveTaskIdx = stayOrStopTask.getTaskIdx() + 1; - final Task task = schedule.getTasks().get(driveTaskIdx); - schedule.removeTask(task); - } - } else { - // check: if there is at most one drive task in between - if (stayOrStopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx() // - && stayTask != null && stayTask.getTaskIdx() + 1 != nextStopTask.getTaskIdx()) { - throw new RuntimeException(); - } - if (stayOrStopTask.getTaskIdx() + 2 == nextStopTask.getTaskIdx()) { - // removing the drive task that is in between - int driveTaskIdx = stayOrStopTask.getTaskIdx() + 1; - final Task task = schedule.getTasks().get(driveTaskIdx); - schedule.removeTask(task); - } - } - } - - if (stayTask != null && request.getFromLink() == stayTask.getLink()) { - // the bus stays where it is - beforePickupTask = stayTask; - } else {// add drive task to pickup location - // insert drive i->pickup - VrpPathWithTravelData vrpPath = VrpPaths.createPath(stayOrStopTask.getLink(), request.getFromLink(), - stayOrStopTask.getEndTime(), detourData.detourToPickup, travelTime); - beforePickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(stayOrStopTask.getTaskIdx() + 1, beforePickupTask); - } - } - } - - // insert pickup stop task - double startTime = beforePickupTask.getEndTime(); - int taskIdx = beforePickupTask.getTaskIdx() + 1; - double stopEndTime = stopTimeCalculator.initEndTimeForPickup(vehicleEntry.vehicle, startTime, request.getRequest()); - DrtStopTask pickupStopTask = taskFactory.createStopTask(vehicleEntry.vehicle, startTime, - stopEndTime, request.getFromLink()); - schedule.addTask(taskIdx, pickupStopTask); - pickupStopTask.addPickupRequest(request); - - // add drive from pickup - Link toLink = pickupIdx == dropoffIdx ? request.getToLink() // pickup->dropoff - : stops.get(pickupIdx).task.getLink(); // pickup->i+1 - - VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getFromLink(), toLink, pickupStopTask.getEndTime(), - detourData.detourFromPickup, travelTime); - Task driveFromPickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(taskIdx + 1, driveFromPickupTask); - - // update timings - // TODO should be enough to update the timeline only till dropoffIdx... - scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, taskIdx + 2, - driveFromPickupTask.getEndTime()); - return pickupStopTask; - } - - private DrtStopTask insertDropoff(AcceptedDrtRequest request, InsertionWithDetourData insertionWithDetourData, - DrtStopTask pickupTask) { - var insertion = insertionWithDetourData.insertion; - VehicleEntry vehicleEntry = insertion.vehicleEntry; - Schedule schedule = vehicleEntry.vehicle.getSchedule(); - List stops = vehicleEntry.stops; - int pickupIdx = insertion.pickup.index; - int dropoffIdx = insertion.dropoff.index; - var detourData = insertionWithDetourData.detourData; - - Task driveToDropoffTask; - if (pickupIdx == dropoffIdx) { // no drive to dropoff - int pickupTaskIdx = pickupTask.getTaskIdx(); - driveToDropoffTask = schedule.getTasks().get(pickupTaskIdx + 1); - } else { - DrtStopTask stopTask = stops.get(dropoffIdx - 1).task; - if (request.getToLink() == stopTask.getLink()) { // no detour; no new stop task - // add dropoff request to stop task, and extend the stop task (when incremental stop task duration is used) - stopTask.addDropoffRequest(request); - - /* - * TODO: insertionTime should be set to "now" here to avoid adding pickups to - * ongoing tasks "for free" and generating requests with zero wait time. See - * InsertionDetourTimeCalculator.calculatePickupIfSameLink for more details. - */ - - double insertionTime = stopTask.getBeginTime(); - stopTask.setEndTime(stopTimeCalculator.updateEndTimeForDropoff(vehicleEntry.vehicle, stopTask, - insertionTime, request.getRequest())); - - return stopTask; - } else { // add drive task to dropoff location - - // remove drive j->j+1 (if j is not the last stop) - if (dropoffIdx < stops.size()) { - DrtStopTask nextStopTask = stops.get(dropoffIdx).task; - - // this is new - if ((nextStopTask instanceof ShiftChangeOverTask)) { - if (stopTask.getTaskIdx() + 3 != nextStopTask.getTaskIdx() - && !stopTask.getLink().getId().equals(nextStopTask.getLink().getId())) { - //include stay task before shift changeover - throw new IllegalStateException(); - } - } - //end of new - - else { - if (stopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx()) { - throw new IllegalStateException(); - } - } - int driveTaskIdx = stopTask.getTaskIdx() + 1; - - final Task task = schedule.getTasks().get(driveTaskIdx); - schedule.removeTask(task); - } - - // insert drive i->dropoff - VrpPathWithTravelData vrpPath = VrpPaths.createPath(stopTask.getLink(), request.getToLink(), - stopTask.getEndTime(), detourData.detourToDropoff, travelTime); - driveToDropoffTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(stopTask.getTaskIdx() + 1, driveToDropoffTask); - } - } - - // insert dropoff stop task - double startTime = driveToDropoffTask.getEndTime(); - int taskIdx = driveToDropoffTask.getTaskIdx() + 1; - double stopEndTime = stopTimeCalculator.initEndTimeForDropoff(vehicleEntry.vehicle, startTime, request.getRequest()); - DrtStopTask dropoffStopTask = taskFactory.createStopTask(vehicleEntry.vehicle, startTime, - stopEndTime, request.getToLink()); - schedule.addTask(taskIdx, dropoffStopTask); - dropoffStopTask.addDropoffRequest(request); - - // add drive from dropoff - if (dropoffIdx == stops.size()) {// bus stays at dropoff - if (taskIdx + 2 == schedule.getTaskCount()) {// remove stay task from the end of schedule, - DrtStayTask oldStayTask = (DrtStayTask) schedule.getTasks().get(taskIdx + 1); - schedule.removeTask(oldStayTask); - } - if (taskIdx + 1 == schedule.getTaskCount()) { - // no stay task at the end if the pickup follows the existing stay task - double beginTime = dropoffStopTask.getEndTime(); - double endTime = Math.max(beginTime, ((ShiftDvrpVehicle) vehicleEntry.vehicle).getShifts().peek().getEndTime()); - schedule.addTask(taskFactory.createStayTask(vehicleEntry.vehicle, beginTime, - endTime, dropoffStopTask.getLink())); - } else { - throw new RuntimeException(); - } - } else { - final DrtStopTask nextStopTask = stops.get(dropoffIdx).task; - Link toLink = nextStopTask.getLink(); // dropoff->j+1 - - VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getToLink(), toLink, dropoffStopTask.getEndTime(), - detourData.detourFromDropoff, travelTime); - - - Task driveFromDropoffTask; - if (nextStopTask instanceof ShiftChangeOverTask) { - driveFromDropoffTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, ShiftTaskScheduler.RELOCATE_VEHICLE_SHIFT_CHANGEOVER_TASK_TYPE); - schedule.addTask(taskIdx + 1, driveFromDropoffTask); - final List tasks = vehicleEntry.vehicle.getSchedule().getTasks(); - final Task task = tasks.get(tasks.indexOf(nextStopTask) - 1); - if (task instanceof DrtStayTask) { - schedule.removeTask(task); - } - final double arrivalTime = vrpPath.getArrivalTime(); - final double shiftEndTime = ((ShiftChangeOverTask) nextStopTask).getShift().getEndTime(); - if (arrivalTime <= shiftEndTime) { - DrtStayTask stayWaitShiftEndTask = taskFactory.createStayTask(vehicleEntry.vehicle, arrivalTime, - shiftEndTime, nextStopTask.getLink()); - schedule.addTask(tasks.indexOf(nextStopTask), stayWaitShiftEndTask); - } - } else { - driveFromDropoffTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(taskIdx + 1, driveFromDropoffTask); - } - - // update timings - scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, taskIdx + 2, - driveFromDropoffTask.getEndTime()); - } - return dropoffStopTask; - } -} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java index a765f59feda..e7f4f58b391 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java @@ -1,5 +1,7 @@ package org.matsim.contrib.drt.extension.operations.shifts.run; +import com.google.common.collect.ImmutableMap; +import com.google.inject.Singleton; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; @@ -13,7 +15,6 @@ import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.DrtShiftDispatcherImpl; import org.matsim.contrib.drt.extension.operations.shifts.fleet.DefaultShiftDvrpVehicle; import org.matsim.contrib.drt.extension.operations.shifts.optimizer.ShiftDrtOptimizer; -import org.matsim.contrib.drt.extension.operations.shifts.optimizer.ShiftRequestInsertionScheduler; import org.matsim.contrib.drt.extension.operations.shifts.optimizer.ShiftVehicleDataEntryFactory; import org.matsim.contrib.drt.extension.operations.shifts.optimizer.insertion.ShiftInsertionCostCalculator; import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtActionCreator; @@ -23,30 +24,21 @@ import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftDrtScheduleInquiry; import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftTaskScheduler; import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftTaskSchedulerImpl; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DefaultShiftBreakImpl; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreakSpecification; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftImpl; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShifts; -import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftsSpecification; -import org.matsim.contrib.drt.optimizer.DefaultDrtOptimizer; -import org.matsim.contrib.drt.optimizer.DrtOptimizer; -import org.matsim.contrib.drt.optimizer.DrtRequestInsertionRetryQueue; -import org.matsim.contrib.drt.optimizer.VehicleDataEntryFactoryImpl; -import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.extension.operations.shifts.shift.*; +import org.matsim.contrib.drt.optimizer.*; import org.matsim.contrib.drt.optimizer.depot.DepotFinder; import org.matsim.contrib.drt.optimizer.insertion.CostCalculationStrategy; import org.matsim.contrib.drt.optimizer.insertion.DefaultInsertionCostCalculator; import org.matsim.contrib.drt.optimizer.insertion.InsertionCostCalculator; import org.matsim.contrib.drt.optimizer.insertion.UnplannedRequestInserter; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtStayTaskEndTimeCalculator; import org.matsim.contrib.drt.schedule.DrtTaskFactory; import org.matsim.contrib.drt.schedule.DrtTaskFactoryImpl; import org.matsim.contrib.drt.scheduler.DrtScheduleInquiry; import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; -import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler; import org.matsim.contrib.drt.stops.StopTimeCalculator; import org.matsim.contrib.drt.vrpagent.DrtActionCreator; import org.matsim.contrib.dvrp.fleet.DvrpVehicleImpl; @@ -58,15 +50,15 @@ import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModes; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.tracker.OnlineTrackerListener; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.modal.ModalProviders; import org.matsim.core.router.costcalculators.TravelDisutilityFactory; import org.matsim.core.router.util.TravelTime; -import com.google.common.collect.ImmutableMap; - /** * @author nkuehnel, fzwick / MOIA */ @@ -108,7 +100,8 @@ public DrtShifts get() { }).asEagerSingleton(); addModalComponent(DrtOptimizer.class, modalProvider( - getter -> new ShiftDrtOptimizer( + getter -> { + return new ShiftDrtOptimizer( new DefaultDrtOptimizer(drtCfg, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), getter.getModal(DepotFinder.class), getter.getModal(RebalancingStrategy.class), getter.getModal(DrtScheduleInquiry.class), getter.getModal(ScheduleTimingUpdater.class), @@ -116,7 +109,8 @@ public DrtShifts get() { getter.getModal(DrtRequestInsertionRetryQueue.class) ), getter.getModal(DrtShiftDispatcher.class), - getter.getModal(ScheduleTimingUpdater.class)))); + getter.getModal(ScheduleTimingUpdater.class)); + })); bindModal(DrtShiftDispatcher.class).toProvider(modalProvider( getter -> new DrtShiftDispatcherImpl(getter.getModal(DrtShifts.class), getter.getModal(Fleet.class), @@ -129,27 +123,20 @@ shiftsParams, new DefaultShiftStartLogic(), new DefaultAssignShiftToVehicleLogic getter -> new ShiftInsertionCostCalculator(getter.get(MobsimTimer.class), new DefaultInsertionCostCalculator(getter.getModal(CostCalculationStrategy.class))))); - bindModal(VehicleEntry.EntryFactory.class).toInstance(new ShiftVehicleDataEntryFactory(new VehicleDataEntryFactoryImpl(drtCfg))); + bindModal(VehicleEntry.EntryFactory.class).toInstance(new ShiftVehicleDataEntryFactory(new VehicleDataEntryFactoryImpl())); - final ShiftDrtTaskFactoryImpl taskFactory = new ShiftDrtTaskFactoryImpl(new DrtTaskFactoryImpl()); - bindModal(DrtTaskFactory.class).toInstance(taskFactory); - bindModal(ShiftDrtTaskFactory.class).toInstance(taskFactory); + bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> new ShiftDrtTaskFactoryImpl(new DrtTaskFactoryImpl(), getter.getModal(OperationFacilities.class)))); + bindModal(ShiftDrtTaskFactory.class).toProvider(modalProvider(getter -> ((ShiftDrtTaskFactory) getter.getModal(DrtTaskFactory.class)))); bindModal(ShiftTaskScheduler.class).toProvider(modalProvider( getter -> new ShiftTaskSchedulerImpl(getter.getModal(Network.class), getter.getModal(TravelTime.class), getter.getModal(TravelDisutilityFactory.class).createTravelDisutility(getter.getModal(TravelTime.class)), - getter.get(MobsimTimer.class), taskFactory, shiftsParams, + getter.get(MobsimTimer.class), getter.getModal(ShiftDrtTaskFactory.class), shiftsParams, getter.getModal(OperationFacilities.class), getter.getModal(Fleet.class))) ).asEagerSingleton(); bindModal(DrtScheduleInquiry.class).to(ShiftDrtScheduleInquiry.class).asEagerSingleton(); - bindModal(RequestInsertionScheduler.class).toProvider(modalProvider( - getter -> new ShiftRequestInsertionScheduler( - getter.get(MobsimTimer.class), getter.getModal(TravelTime.class), - getter.getModal(ScheduleTimingUpdater.class), getter.getModal(ShiftDrtTaskFactory.class), - getter.getModal(StopTimeCalculator.class))) - ).asEagerSingleton(); bindModal(ScheduleTimingUpdater.class).toProvider(modalProvider( getter -> new ScheduleTimingUpdater(getter.get(MobsimTimer.class), @@ -157,12 +144,25 @@ shiftsParams, new DefaultShiftStartLogic(), new DefaultAssignShiftToVehicleLogic new DrtStayTaskEndTimeCalculator(getter.getModal(StopTimeCalculator.class))))) ).asEagerSingleton(); - bindModal(VrpAgentLogic.DynActionCreator.class).toProvider(modalProvider( - (getter) -> new ShiftDrtActionCreator(getter.getModal(PassengerHandler.class), - new DrtActionCreator(getter.getModal(PassengerHandler.class), getter.get(MobsimTimer.class), - getter.get(DvrpConfigGroup.class)))) - ).asEagerSingleton(); + // see DrtModeOptimizerQSimModule + bindModal(VrpLegFactory.class).toProvider(modalProvider(getter -> { + DvrpConfigGroup dvrpCfg = getter.get(DvrpConfigGroup.class); + MobsimTimer timer = getter.get(MobsimTimer.class); + + return v -> VrpLegFactory.createWithOnlineTracker(dvrpCfg.mobsimMode, v, OnlineTrackerListener.NO_LISTENER, + timer); + })).in(Singleton.class); + + bindModal(ShiftDrtActionCreator.class).toProvider(modalProvider((getter) -> { + VrpAgentLogic.DynActionCreator delegate = drtCfg.getPrebookingParams().isPresent() + ? getter.getModal(PrebookingActionCreator.class) + : getter.getModal(DrtActionCreator.class); + + // adds shift tasks + return new ShiftDrtActionCreator(getter.getModal(PassengerHandler.class), delegate); + })).asEagerSingleton(); + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(ShiftDrtActionCreator.class)); bindModal(Fleet.class).toProvider(new ModalProviders.AbstractProvider<>(getMode(), DvrpModes::mode) { @Override diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftBreakTaskImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftBreakTaskImpl.java index e295a531ef5..b718954da1b 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftBreakTaskImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftBreakTaskImpl.java @@ -63,4 +63,14 @@ public void addDropoffRequest(AcceptedDrtRequest request) { public void addPickupRequest(AcceptedDrtRequest request) { delegate.addPickupRequest(request); } + + @Override + public void removePickupRequest(Id requestId) { + delegate.removePickupRequest(requestId); + } + + @Override + public void removeDropoffRequest(Id requestId) { + delegate.removeDropoffRequest(requestId); + } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftChangeoverTaskImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftChangeoverTaskImpl.java index 76818598dd6..0af9ed0b7bf 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftChangeoverTaskImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftChangeoverTaskImpl.java @@ -1,5 +1,9 @@ package org.matsim.contrib.drt.extension.operations.shifts.schedule; +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STOP; + +import java.util.Map; + import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; @@ -11,10 +15,6 @@ import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.schedule.DefaultStayTask; -import java.util.Map; - -import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STOP; - /** * A task representing stopping and waiting for a new shift. * @author nkuehnel / MOIA @@ -64,5 +64,15 @@ public void addDropoffRequest(AcceptedDrtRequest request) { public void addPickupRequest(AcceptedDrtRequest request) { delegate.addPickupRequest(request); } + + @Override + public void removePickupRequest(Id requestId) { + delegate.removePickupRequest(requestId); + } + + @Override + public void removeDropoffRequest(Id requestId) { + delegate.removeDropoffRequest(requestId); + } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java index bb2b56e7aec..57460d2bee6 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java @@ -1,54 +1,84 @@ package org.matsim.contrib.drt.extension.operations.shifts.schedule; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilities; import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift; import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak; import org.matsim.contrib.drt.schedule.*; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; +import org.matsim.facilities.Facility; + +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Collectors; /** * @author nkuehnel, fzwick / MOIA */ public class ShiftDrtTaskFactoryImpl implements ShiftDrtTaskFactory { - private final DrtTaskFactory delegate; - - public ShiftDrtTaskFactoryImpl(DrtTaskFactory delegate) { - this.delegate = delegate; - } - - @Override - public DrtDriveTask createDriveTask(DvrpVehicle vehicle, VrpPathWithTravelData path, DrtTaskType drtTaskType) { - return delegate.createDriveTask(vehicle, path, drtTaskType); - } - - @Override - public DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { - return delegate.createStopTask(vehicle, beginTime, endTime, link); - } - - @Override - public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { - return delegate.createStayTask(vehicle, beginTime, endTime, link); - } - - @Override - public ShiftBreakTask createShiftBreakTask(DvrpVehicle vehicle, double beginTime, double endTime, - Link link, DrtShiftBreak shiftBreak, OperationFacility facility) { - return new ShiftBreakTaskImpl(beginTime, endTime, link, shiftBreak, facility); - } - - @Override - public ShiftChangeOverTask createShiftChangeoverTask(DvrpVehicle vehicle, double beginTime, double endTime, - Link link, DrtShift shift, OperationFacility facility) { - return new ShiftChangeoverTaskImpl(beginTime, endTime, link, shift, facility); - } - - @Override - public WaitForShiftStayTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, - Link link, OperationFacility facility) { - return new WaitForShiftStayTask(beginTime, endTime, link, facility); - } + private final DrtTaskFactory delegate; + private final OperationFacilities operationFacilities; + + public ShiftDrtTaskFactoryImpl(DrtTaskFactory delegate, OperationFacilities operationFacilities) { + this.delegate = delegate; + this.operationFacilities = operationFacilities; + } + + @Override + public DrtDriveTask createDriveTask(DvrpVehicle vehicle, VrpPathWithTravelData path, DrtTaskType drtTaskType) { + return delegate.createDriveTask(vehicle, path, drtTaskType); + } + + @Override + public DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return delegate.createStopTask(vehicle, beginTime, endTime, link); + } + + @Override + public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return delegate.createStayTask(vehicle, beginTime, endTime, link); + } + + @Override + public ShiftBreakTask createShiftBreakTask(DvrpVehicle vehicle, double beginTime, double endTime, + Link link, DrtShiftBreak shiftBreak, OperationFacility facility) { + return new ShiftBreakTaskImpl(beginTime, endTime, link, shiftBreak, facility); + } + + @Override + public ShiftChangeOverTask createShiftChangeoverTask(DvrpVehicle vehicle, double beginTime, double endTime, + Link link, DrtShift shift, OperationFacility facility) { + return new ShiftChangeoverTaskImpl(beginTime, endTime, link, shift, facility); + } + + @Override + public WaitForShiftStayTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, + Link link, OperationFacility facility) { + return new WaitForShiftStayTask(beginTime, endTime, link, facility); + } + + public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + final Map, List> facilitiesByLink = operationFacilities.getDrtOperationFacilities().values().stream().collect(Collectors.groupingBy(Facility::getLinkId)); + final OperationFacility operationFacility; + try { + operationFacility = facilitiesByLink.get(vehicle.getStartLink().getId()).stream().findFirst().orElseThrow((Supplier) () -> new RuntimeException("Vehicles must start at an operation facility!")); + } catch (Throwable e) { + throw new RuntimeException(e); + } + WaitForShiftStayTask waitForShiftStayTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(), + vehicle.getStartLink(), operationFacility); + boolean success = operationFacility.register(vehicle.getId()); + if (!success) { + throw new RuntimeException(String.format("Cannot register vehicle %s at facility %s at start-up. Please check" + + "facility capacity and initial fleet distribution.", vehicle.getId().toString(), operationFacility.getId().toString())); + } + return waitForShiftStayTask; + } + } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftSchedules.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftSchedules.java index 95fb45131e5..045a312c38f 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftSchedules.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftSchedules.java @@ -1,21 +1,10 @@ package org.matsim.contrib.drt.extension.operations.shifts.schedule; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilities; -import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; -import org.matsim.contrib.dvrp.fleet.DvrpVehicle; -import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.schedule.Schedule; import org.matsim.contrib.dvrp.schedule.Task; -import org.matsim.facilities.Facility; import java.util.Comparator; -import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.function.Supplier; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -31,22 +20,4 @@ public static Optional getNextShiftChangeover (Schedule sch .filter(t -> t.getTaskIdx() > taskIdx) .min(Comparator.comparingDouble(Task::getBeginTime)); } - - public static void initSchedules(OperationFacilities operationFacilities, Fleet fleet, ShiftDrtTaskFactory taskFactory) { - final Map, List> facilitiesByLink = operationFacilities.getDrtOperationFacilities().values().stream().collect(Collectors.groupingBy(Facility::getLinkId)); - for (DvrpVehicle veh : fleet.getVehicles().values()) { - try { - final OperationFacility operationFacility = facilitiesByLink.get(veh.getStartLink().getId()).stream().findFirst().orElseThrow((Supplier) () -> new RuntimeException("Vehicles must start at an operation facility!")); - veh.getSchedule() - .addTask(taskFactory.createWaitForShiftStayTask(veh, veh.getServiceBeginTime(), veh.getServiceEndTime(), - veh.getStartLink(), operationFacility)); - boolean success = operationFacility.register(veh.getId()); - if(!success) { - throw new RuntimeException(String.format("Cannot register vehicle %s at facility %s at start-up. Please check" + - "facility capacity and initial fleet distribution.", veh.getId().toString(), operationFacility.getId().toString())); - } } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java index 8b076be9b0d..d6d272371e9 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java @@ -4,7 +4,6 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams; import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle; import org.matsim.contrib.drt.extension.operations.shifts.schedule.*; @@ -26,7 +25,7 @@ import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; import org.matsim.contrib.dvrp.util.LinkTimePair; import org.matsim.core.mobsim.framework.MobsimTimer; -import org.matsim.core.router.FastAStarEuclideanFactory; +import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.TravelDisutility; import org.matsim.core.router.util.TravelTime; @@ -60,9 +59,7 @@ public ShiftTaskSchedulerImpl(Network network, TravelTime travelTime, TravelDisu this.taskFactory = taskFactory; this.network = network; this.drtShiftParams = drtShiftParams; - this.router = new FastAStarEuclideanFactory().createPathCalculator(network, travelDisutility, travelTime); - - ShiftSchedules.initSchedules(operationFacilities, fleet, taskFactory); + this.router = new SpeedyALTFactory().createPathCalculator(network, travelDisutility, travelTime); } @Override diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtModeOptimizerQSimModule.java index 8952fed6b09..d5b560d31fc 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtModeOptimizerQSimModule.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtModeOptimizerQSimModule.java @@ -34,12 +34,17 @@ import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.tracker.OnlineTrackerListener; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.router.costcalculators.TravelDisutilityFactory; import org.matsim.core.router.util.TravelTime; +import com.google.common.base.Preconditions; +import com.google.inject.Singleton; + /** * @author Michal Maciejewski (michalm) */ @@ -61,10 +66,17 @@ protected void configureQSim() { getter.getModal(ScheduleTimingUpdater.class)))); bindModal(DrtTaskFactory.class).toInstance(new DrtTaskFactoryImpl()); + + bindModal(VrpLegFactory.class).toProvider(modalProvider(getter -> { + DvrpConfigGroup dvrpCfg = getter.get(DvrpConfigGroup.class); + MobsimTimer timer = getter.get(MobsimTimer.class); + + return v -> VrpLegFactory.createWithOnlineTracker(dvrpCfg.mobsimMode, v, OnlineTrackerListener.NO_LISTENER, + timer); + })).in(Singleton.class); - bindModal(VrpAgentLogic.DynActionCreator.class).toProvider(modalProvider( - getter -> new DrtActionCreator(getter.getModal(PassengerHandler.class), getter.get(MobsimTimer.class), - getter.get(DvrpConfigGroup.class)))).asEagerSingleton(); + Preconditions.checkState(drtCfg.getPrebookingParams().isEmpty(), "cannot use preplanned schedules with prebooking"); + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(DrtActionCreator.class)); bindModal(VrpOptimizer.class).to(modalKey(DrtOptimizer.class)); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java index 0103e5bb66a..5dd5f1c8bf7 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java @@ -22,9 +22,7 @@ import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; -import java.util.HashMap; -import java.util.Map; -import java.util.Queue; +import java.util.*; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -118,7 +116,7 @@ public void requestSubmitted(Request request) { "Pre-planned request (%s) not assigned to any vehicle and not marked as unassigned.", preplannedRequest); eventsManager.processEvent(new PassengerRequestRejectedEvent(timer.getTimeOfDay(), mode, request.getId(), - drtRequest.getPassengerId(), "Marked as unassigned")); + drtRequest.getPassengerIds(), "Marked as unassigned")); return; } @@ -130,7 +128,7 @@ public void requestSubmitted(Request request) { //TODO in the current implementation we do not know the scheduled pickup and dropoff times eventsManager.processEvent( new PassengerRequestScheduledEvent(timer.getTimeOfDay(), drtRequest.getMode(), drtRequest.getId(), - drtRequest.getPassengerId(), vehicleId, Double.NaN, Double.NaN)); + drtRequest.getPassengerIds(), vehicleId, Double.NaN, Double.NaN)); } @Override @@ -203,7 +201,7 @@ public record PreplannedSchedules(Map> pre Map unassignedRequests) { } - public record PreplannedRequestKey(Id passengerId, Id fromLinkId, Id toLinkId) { + public record PreplannedRequestKey(Set> passengerIds, Id fromLinkId, Id toLinkId) { } // also input to the external optimiser @@ -212,7 +210,7 @@ public record PreplannedRequest(PreplannedRequestKey key, double earliestStartTi } static PreplannedRequest createFromRequest(DrtRequest request) { - return new PreplannedRequest(new PreplannedRequestKey(request.getPassengerId(), request.getFromLink().getId(), + return new PreplannedRequest(new PreplannedRequestKey(Set.copyOf(request.getPassengerIds()), request.getFromLink().getId(), request.getToLink().getId()), request.getEarliestStartTime(), request.getLatestStartTime(), request.getLatestArrivalTime()); } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/PreplannedDrtControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/PreplannedDrtControlerCreator.java index fbf6325b77a..bbf5fa4c5c2 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/PreplannedDrtControlerCreator.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/PreplannedDrtControlerCreator.java @@ -62,7 +62,7 @@ public final class PreplannedDrtControlerCreator { */ public static Controler createControler(Config config, boolean otfvis) { MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing()); Scenario scenario = createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/RunPreplannedDrtExample.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/RunPreplannedDrtExample.java index 04f7852c45a..e0463eb46f0 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/RunPreplannedDrtExample.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/run/RunPreplannedDrtExample.java @@ -43,7 +43,7 @@ public static void run(URL configUrl, boolean otfvis, int lastIteration, Map preplannedSchedulesByMode) { Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); Controler controler = PreplannedDrtControlerCreator.createControler(config, otfvis); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java index 4ca143f3cf3..7131c33a368 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java @@ -17,19 +17,21 @@ import org.matsim.contrib.vsp.scenario.SnzActivities; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; import org.matsim.simwrapper.SimWrapperModule; +import org.matsim.modechoice.InformedModeChoiceConfigGroup; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.VehicleType; import javax.annotation.Nullable; import java.net.URL; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.function.Consumer; @@ -65,8 +67,8 @@ public static Config loadConfig(MatsimTestUtils utils) { URL context = ExamplesUtils.getTestScenarioURL("kelheim"); Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(context, "config-with-drt.xml")); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); return config; } @@ -76,19 +78,21 @@ protected Config prepareConfig(Config config) { SnzActivities.addScoringParams(config); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("car interaction").setTypicalDuration(60)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("other").setTypicalDuration(600 * 3)); + config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("car interaction").setTypicalDuration(60)); + config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("other").setTypicalDuration(600 * 3)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("freight_start").setTypicalDuration(60 * 15)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("freight_end").setTypicalDuration(60 * 15)); + config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_start").setTypicalDuration(60 * 15)); + config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_end").setTypicalDuration(60 * 15)); + InformedModeChoiceConfigGroup imc = ConfigUtils.addOrGetModule(config, InformedModeChoiceConfigGroup.class); + imc.setModes(Set.of("drt", "av", "car", "pt", "bike", "walk")); MultiModeDrtConfigGroup multiModeDrtConfig = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing()); - config.plansCalcRoute().setAccessEgressType(PlansCalcRouteConfigGroup.AccessEgressType.accessEgressModeToLink); + config.routing().setAccessEgressType(RoutingConfigGroup.AccessEgressType.accessEgressModeToLink); prepareConfig.accept(config); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroupTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroupTest.java index bc0f9e22ba3..a169febcd9e 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroupTest.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroupTest.java @@ -19,14 +19,15 @@ package org.matsim.contrib.drt.extension; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.util.List; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.drt.extension.companions.DrtCompanionParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; @@ -45,10 +46,8 @@ public class DrtWithExtensionsConfigGroupTest { private final static double WEIGHT_2 = 1337.; private final static double WEIGHT_3 = 911.; - - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - + @TempDir + public File tempFolder; private static Config createConfig(List values) { Config config = ConfigUtils.createConfig(); @@ -70,25 +69,25 @@ private static Config createConfig(List values) { return config; } - private static Path writeConfig(final TemporaryFolder tempFolder, List weights) throws IOException { + private static Path writeConfig(final File tempFolder, List weights) throws IOException { Config config = createConfig(weights); - Path configFile = tempFolder.newFile("config.xml").toPath(); + Path configFile = new File(tempFolder, "config.xml").toPath(); ConfigUtils.writeConfig(config, configFile.toString()); return configFile; } - @Test - public void loadConfigGroupTest() throws IOException { + @Test + void loadConfigGroupTest() throws IOException { /* Test that exported values are correct imported again */ Path configFile = writeConfig(tempFolder, List.of(WEIGHT_1,WEIGHT_2,WEIGHT_3)); Config config = ConfigUtils.createConfig(); ConfigUtils.loadConfig(config, configFile.toString()); DrtWithExtensionsConfigGroup loadedCfg = ConfigUtils.addOrGetModule(config, DrtWithExtensionsConfigGroup.class); - Assert.assertTrue(loadedCfg.getDrtCompanionParams().isPresent()); - Assert.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(0).equals(WEIGHT_1)); - Assert.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(1).equals(WEIGHT_2)); - Assert.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(2).equals(WEIGHT_3)); + Assertions.assertTrue(loadedCfg.getDrtCompanionParams().isPresent()); + Assertions.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(0).equals(WEIGHT_1)); + Assertions.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(1).equals(WEIGHT_2)); + Assertions.assertTrue(loadedCfg.getDrtCompanionParams().get().getDrtCompanionSamplingWeights().get(2).equals(WEIGHT_3)); } } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java index de5534ab0e7..8ba86ac28d7 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/companions/RunDrtWithCompanionExampleIT.java @@ -24,14 +24,12 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; @@ -50,11 +48,11 @@ */ public class RunDrtWithCompanionExampleIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testRunDrtWithCompanions() { + void testRunDrtWithCompanions() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new OTFVisConfigGroup(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new), new DvrpConfigGroup()); @@ -62,16 +60,20 @@ public void testRunDrtWithCompanions() { // Add DrtCompanionParams with some default values into existing Drt configurations MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) multiModeDrtConfigGroup.getModalElements().iterator().next(); - drtWithExtensionsConfigGroup.addParameterSet(new DrtCompanionParams()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + DrtCompanionParams crtCompanionParams = new DrtCompanionParams(); + crtCompanionParams.setDrtCompanionSamplingWeights(List.of(0.5,0.2,0.1,0.1,0.1)); + + drtWithExtensionsConfigGroup.addParameterSet(crtCompanionParams); + + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); Controler controler = DrtCompanionControlerCreator.createControler(config); controler.run(); int actualRides = getTotalNumberOfDrtRides(); - Assertions.assertThat(actualRides).isEqualTo(471); + Assertions.assertThat(actualRides).isEqualTo(706); } private int getTotalNumberOfDrtRides() { diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/dashboards/DashboardTests.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/dashboards/DashboardTests.java index 43e8f7dfffe..78e7ccbeb5e 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/dashboards/DashboardTests.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/dashboards/DashboardTests.java @@ -1,8 +1,8 @@ package org.matsim.contrib.drt.extension.dashboards; import org.assertj.core.api.Assertions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.MATSimApplication; import org.matsim.contrib.drt.extension.DrtTestScenario; import org.matsim.contrib.drt.run.DrtConfigGroup; @@ -17,15 +17,15 @@ public class DashboardTests { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); private void run() { Config config = DrtTestScenario.loadConfig(utils); - config.controler().setLastIteration(4); - config.controler().setWritePlansInterval(4); - config.controler().setWriteEventsInterval(4); + config.controller().setLastIteration(4); + config.controller().setWritePlansInterval(4); + config.controller().setWriteEventsInterval(4); SimWrapperConfigGroup group = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class); group.defaultParams().sampleSize = 0.001; @@ -45,7 +45,7 @@ private void run() { } @Test - public void drtDefaults() { + void drtDefaults() { run(); // TODO: add test headers!? diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java index 49940884fc4..48a6c4aeeea 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/edrt/run/RunEDrtScenarioIT.java @@ -19,18 +19,161 @@ package org.matsim.contrib.drt.extension.edrt.run; import java.net.URL; +import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory; +import org.matsim.contrib.drt.prebooking.PrebookingParams; +import org.matsim.contrib.drt.prebooking.logic.ProbabilityBasedPrebookingLogic; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.DrtConfigs; +import org.matsim.contrib.drt.run.DrtControlerCreator; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.passenger.*; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpModule; +import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.contrib.ev.EvConfigGroup; +import org.matsim.contrib.ev.EvModule; +import org.matsim.contrib.ev.charging.*; +import org.matsim.contrib.ev.discharging.IdleDischargingHandler; +import org.matsim.contrib.ev.temperature.TemperatureService; +import org.matsim.contrib.evrp.EvDvrpFleetQSimModule; +import org.matsim.contrib.evrp.OperatingVehicleProvider; +import org.matsim.contrib.otfvis.OTFVisLiveModule; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.qsim.AbstractQSimModule; +import org.matsim.core.population.io.PopulationReader; +import org.matsim.core.population.io.PopulationWriter; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; +import org.matsim.vis.otfvis.OTFVisConfigGroup; /** * @author michalm */ public class RunEDrtScenarioIT { @Test - public void test() { + void test() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_edrt_config.xml"); RunEDrtScenario.run(configUrl, false); } + + @Test + void testMultiModeDrtDeterminism() { + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_multiModeEdrt_config.xml"); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + new OTFVisConfigGroup(), new EvConfigGroup()); + + + Controler controller = RunEDrtScenario.createControler(config, false); + config.controller().setLastIteration(2); + + PassengerPickUpTracker tracker = new PassengerPickUpTracker(); + tracker.install(controller); + + controller.run(); + + assertEquals(2011, tracker.passengerPickupEvents); + } + + + @Test + void testWithPrebooking() { + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_edrt_config.xml"); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + new OTFVisConfigGroup(), new EvConfigGroup()); + + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(config); + drtConfig.addParameterSet(new PrebookingParams()); + + Controler controller = RunEDrtScenario.createControler(config, false); + ProbabilityBasedPrebookingLogic.install(controller, drtConfig, 0.5, 4.0 * 3600.0); + + PrebookingTracker tracker = new PrebookingTracker(); + tracker.install(controller); + + controller.run(); + + assertEquals(74, tracker.immediateScheduled); + assertEquals(198, tracker.prebookedScheduled); + assertEquals(116, tracker.immediateRejected); + assertEquals(7, tracker.prebookedRejected); + } + + static private class PassengerPickUpTracker implements PassengerPickedUpEventHandler { + int passengerPickupEvents = 0; + + void install(Controler controller) { + PassengerPickUpTracker thisTracker = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(thisTracker); + } + }); + } + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + passengerPickupEvents++; + } + + @Override + public void reset(int iteration) { + passengerPickupEvents=0; + } + + } + + static private class PrebookingTracker implements PassengerRequestRejectedEventHandler, PassengerRequestScheduledEventHandler { + int immediateScheduled = 0; + int prebookedScheduled = 0; + int immediateRejected = 0; + int prebookedRejected = 0; + + @Override + public void handleEvent(PassengerRequestScheduledEvent event) { + if (event.getRequestId().toString().contains("prebooked")) { + prebookedScheduled++; + } else { + immediateScheduled++; + } + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + if (event.getRequestId().toString().contains("prebooked")) { + prebookedRejected++; + } else { + immediateRejected++; + } + } + + void install(Controler controller) { + PrebookingTracker thisTracker = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(thisTracker); + } + }); + } + } } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModaFixedDrtLegEstimatorTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModaFixedDrtLegEstimatorTest.java new file mode 100644 index 00000000000..5d4a8a1d5b6 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModaFixedDrtLegEstimatorTest.java @@ -0,0 +1,93 @@ +package org.matsim.contrib.drt.extension.estimator; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.application.MATSimApplication; +import org.matsim.contrib.drt.extension.DrtTestScenario; +import org.matsim.contrib.drt.extension.estimator.impl.ConstantDrtEstimator; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorModule; +import org.matsim.contrib.drt.extension.estimator.run.MultiModeDrtEstimatorConfigGroup; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.controler.Controler; +import org.matsim.modechoice.InformedModeChoiceModule; +import org.matsim.modechoice.ModeOptions; +import org.matsim.modechoice.estimators.DefaultLegScoreEstimator; +import org.matsim.modechoice.estimators.FixedCostsEstimator; +import org.matsim.testcases.MatsimTestUtils; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MultiModaFixedDrtLegEstimatorTest { + + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + private Controler controler; + + private static void prepare(Controler controler) { + InformedModeChoiceModule.Builder builder = InformedModeChoiceModule.newBuilder() + .withFixedCosts(FixedCostsEstimator.DailyConstant.class, "car") + .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.AlwaysAvailable.class, "bike", "walk", "pt") + .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.ConsiderYesAndNo.class, "car") + .withLegEstimator(MultiModalDrtLegEstimator.class, ModeOptions.AlwaysAvailable.class, "drt", "av"); + + controler.addOverridingModule(builder.build()); + controler.addOverridingModule(new DrtEstimatorModule() + .withInitialEstimator(cfg -> new ConstantDrtEstimator(cfg, 1.05, 300), "drt", "av")); + } + + private static void prepare(Config config) { + + MultiModeDrtEstimatorConfigGroup estimators = ConfigUtils.addOrGetModule(config, MultiModeDrtEstimatorConfigGroup.class); + + estimators.addParameterSet(new DrtEstimatorConfigGroup("drt") + .withEstimator(DrtEstimatorConfigGroup.EstimatorType.INITIAL)); + estimators.addParameterSet(new DrtEstimatorConfigGroup("av")); + + // Set subtour mode selection as strategy + List strategies = config.replanning().getStrategySettings().stream() + .filter(s -> !s.getStrategyName().toLowerCase().contains("mode") + ).collect(Collectors.toList()); + + strategies.add(new ReplanningConfigGroup.StrategySettings() + .setStrategyName(InformedModeChoiceModule.SELECT_SUBTOUR_MODE_STRATEGY) + .setSubpopulation("person") + .setWeight(0.2)); + + config.replanning().clearStrategySettings(); + strategies.forEach(s -> config.replanning().addStrategySettings(s)); + + } + + @BeforeEach + public void setUp() throws Exception { + + Config config = DrtTestScenario.loadConfig(utils); + + config.controller().setLastIteration(3); + + controler = MATSimApplication.prepare(new DrtTestScenario(MultiModaFixedDrtLegEstimatorTest::prepare, MultiModaFixedDrtLegEstimatorTest::prepare), config); + } + + @Test + void run() { + + String out = utils.getOutputDirectory(); + + controler.run(); + + assertThat(new File(out, "kelheim-mini-drt.drt_estimates_drt.csv")) + .exists() + .isNotEmpty(); + + + } +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java new file mode 100644 index 00000000000..90601b72b29 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java @@ -0,0 +1,90 @@ +package org.matsim.contrib.drt.extension.estimator; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.application.MATSimApplication; +import org.matsim.contrib.drt.extension.DrtTestScenario; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup; +import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorModule; +import org.matsim.contrib.drt.extension.estimator.run.MultiModeDrtEstimatorConfigGroup; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.controler.Controler; +import org.matsim.modechoice.InformedModeChoiceModule; +import org.matsim.modechoice.ModeOptions; +import org.matsim.modechoice.estimators.DefaultLegScoreEstimator; +import org.matsim.modechoice.estimators.FixedCostsEstimator; +import org.matsim.testcases.MatsimTestUtils; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MultiModalDrtLegEstimatorTest { + + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + private Controler controler; + + @BeforeEach + public void setUp() throws Exception { + + Config config = DrtTestScenario.loadConfig(utils); + + config.controller().setLastIteration(3); + + controler = MATSimApplication.prepare(new DrtTestScenario(MultiModalDrtLegEstimatorTest::prepare, MultiModalDrtLegEstimatorTest::prepare), config); + } + + private static void prepare(Controler controler) { + InformedModeChoiceModule.Builder builder = InformedModeChoiceModule.newBuilder() + .withFixedCosts(FixedCostsEstimator.DailyConstant.class, "car") + .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.AlwaysAvailable.class, "bike", "walk", "pt") + .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.ConsiderYesAndNo.class, "car") + .withLegEstimator(MultiModalDrtLegEstimator.class, ModeOptions.AlwaysAvailable.class, "drt", "av"); + + controler.addOverridingModule(builder.build()); + controler.addOverridingModule(new DrtEstimatorModule()); + } + + private static void prepare(Config config) { + + MultiModeDrtEstimatorConfigGroup estimators = ConfigUtils.addOrGetModule(config, MultiModeDrtEstimatorConfigGroup.class); + + estimators.addParameterSet(new DrtEstimatorConfigGroup("drt")); + estimators.addParameterSet(new DrtEstimatorConfigGroup("av")); + + // Set subtour mode selection as strategy + List strategies = config.replanning().getStrategySettings().stream() + .filter(s -> !s.getStrategyName().toLowerCase().contains("mode") + ).collect(Collectors.toList()); + + strategies.add(new ReplanningConfigGroup.StrategySettings() + .setStrategyName(InformedModeChoiceModule.SELECT_SUBTOUR_MODE_STRATEGY) + .setSubpopulation("person") + .setWeight(0.2)); + + config.replanning().clearStrategySettings(); + strategies.forEach(s -> config.replanning().addStrategySettings(s)); + + } + + @Test + void run() { + + String out = utils.getOutputDirectory(); + + controler.run(); + + assertThat(new File(out, "kelheim-mini-drt.drt_estimates_drt.csv")) + .exists() + .isNotEmpty(); + + + } +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java index c6ad3f7dff8..6034419d22e 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java @@ -1,7 +1,7 @@ package org.matsim.contrib.drt.extension.fiss; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.events.LinkLeaveEvent; import org.matsim.api.core.v01.events.handler.LinkLeaveEventHandler; @@ -20,9 +20,9 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; @@ -37,7 +37,7 @@ public class RunFissDrtScenarioIT { @Test - public void test() { + void test() { MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithOperationsConfigGroup::new); @@ -91,10 +91,10 @@ public void test() { modes.add("drt"); config.travelTimeCalculator().setAnalyzedModes(modes); - PlanCalcScoreConfigGroup.ModeParams scoreParams = new PlanCalcScoreConfigGroup.ModeParams("drt"); - config.planCalcScore().addModeParams(scoreParams); - PlanCalcScoreConfigGroup.ModeParams scoreParams2 = new PlanCalcScoreConfigGroup.ModeParams("walk"); - config.planCalcScore().addModeParams(scoreParams2); + ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt"); + config.scoring().addModeParams(scoreParams); + ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk"); + config.scoring().addModeParams(scoreParams2); config.plans().setInputFile(plansFile); config.network().setInputFile(networkFile); @@ -102,33 +102,33 @@ public void test() { config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); - final PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + final ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(8 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams other = new PlanCalcScoreConfigGroup.ActivityParams("other"); + final ScoringConfigGroup.ActivityParams other = new ScoringConfigGroup.ActivityParams("other"); other.setTypicalDuration(4 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams education = new PlanCalcScoreConfigGroup.ActivityParams("education"); + final ScoringConfigGroup.ActivityParams education = new ScoringConfigGroup.ActivityParams("education"); education.setTypicalDuration(6 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams shopping = new PlanCalcScoreConfigGroup.ActivityParams("shopping"); + final ScoringConfigGroup.ActivityParams shopping = new ScoringConfigGroup.ActivityParams("shopping"); shopping.setTypicalDuration(2 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + final ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(2 * 3600); - config.planCalcScore().addActivityParams(home); - config.planCalcScore().addActivityParams(other); - config.planCalcScore().addActivityParams(education); - config.planCalcScore().addActivityParams(shopping); - config.planCalcScore().addActivityParams(work); + config.scoring().addActivityParams(home); + config.scoring().addActivityParams(other); + config.scoring().addActivityParams(education); + config.scoring().addActivityParams(shopping); + config.scoring().addActivityParams(work); - final StrategyConfigGroup.StrategySettings stratSets = new StrategyConfigGroup.StrategySettings(); + final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings(); stratSets.setWeight(1); stratSets.setStrategyName("ChangeExpBeta"); - config.strategy().addStrategySettings(stratSets); + config.replanning().addStrategySettings(stratSets); - config.controler().setLastIteration(2); - config.controler().setWriteEventsInterval(1); + config.controller().setLastIteration(2); + config.controller().setWriteEventsInterval(1); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory("test/output/holzkirchen_shifts"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory("test/output/holzkirchen_shifts"); DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME); ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME); @@ -173,7 +173,7 @@ public void install() { } run.run(); - Assert.assertEquals(23961, linkCounter.getLinkLeaveCount()); + Assertions.assertEquals(23817, linkCounter.getLinkLeaveCount()); } static class LinkCounter implements LinkLeaveEventHandler { diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java new file mode 100644 index 00000000000..69febd3aab0 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/insertion/DrtInsertionExtensionIT.java @@ -0,0 +1,575 @@ +package org.matsim.contrib.drt.extension.insertion; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.net.URL; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.IdSet; +import org.matsim.api.core.v01.events.LinkEnterEvent; +import org.matsim.api.core.v01.events.handler.LinkEnterEventHandler; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.drt.extension.insertion.distances.DistanceApproximator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.DrtControlerCreator; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.drt.schedule.DrtTaskBaseType; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEvent; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEvent; +import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEvent; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEventHandler; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.dvrp.vrpagent.TaskEndedEvent; +import org.matsim.contrib.dvrp.vrpagent.TaskEndedEventHandler; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; +import org.matsim.core.utils.geometry.CoordUtils; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.examples.ExamplesUtils; +import org.matsim.testcases.MatsimTestUtils; +import org.matsim.vehicles.Vehicle; +import org.matsim.vis.otfvis.OTFVisConfigGroup; + +public class DrtInsertionExtensionIT { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + private Controler createController() { + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + new OTFVisConfigGroup()); + + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + + return DrtControlerCreator.createControler(config, false); + } + + @Test + void testExclusivityContraint() { + IdSet exclusiveRequestIds = new IdSet<>(Request.class); + + for (int i = 100; i <= 200; i++) { + exclusiveRequestIds.add(Id.create("drt_" + i, Request.class)); + } + + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) + .withExclusivity(request -> exclusiveRequestIds.contains(request.getId())); + + controller.addOverridingQSimModule(insertionModule); + + ExclusiveRequestsHandler handler = new ExclusiveRequestsHandler(); + handler.install(controller); + + controller.run(); + + IdSet unsharedRequestIds = handler.getUnsharedRequestIds(); + assertTrue(unsharedRequestIds.containsAll(exclusiveRequestIds)); + } + + static public class ExclusiveRequestsHandler implements PassengerPickedUpEventHandler, + PassengerDroppedOffEventHandler, PassengerRequestSubmittedEventHandler { + private final IdMap rideIntervals = new IdMap<>(Request.class); + private final IdSet rejectedIds = new IdSet<>(Request.class); + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + RideInterval interval = new RideInterval(); + interval.requestId = event.getRequestId(); + interval.vehicleId = event.getVehicleId(); + interval.startTime = event.getTime(); + rideIntervals.put(event.getRequestId(), interval); + } + + @Override + public void handleEvent(PassengerDroppedOffEvent event) { + rideIntervals.get(event.getRequestId()).endTime = event.getTime(); + } + + @Override + public void handleEvent(PassengerRequestSubmittedEvent event) { + rejectedIds.add(event.getRequestId()); + } + + static class RideInterval { + Id requestId; + Id vehicleId; + double startTime; + double endTime; + } + + public IdSet getUnsharedRequestIds() { + List rideList = new ArrayList<>(rideIntervals.values()); + + IdSet unsharedRequestIds = new IdSet<>(Request.class); + rideList.forEach(interval -> unsharedRequestIds.add(interval.requestId)); + + for (int i = 0; i < rideList.size(); i++) { + for (int j = i + 1; j < rideList.size(); j++) { + RideInterval firstInterval = rideList.get(i); + RideInterval secondInterval = rideList.get(j); + + if (firstInterval.startTime >= secondInterval.startTime + && firstInterval.startTime <= secondInterval.endTime) { + unsharedRequestIds.remove(firstInterval.requestId); + unsharedRequestIds.remove(secondInterval.requestId); + } + + if (firstInterval.endTime >= secondInterval.startTime + && firstInterval.endTime <= secondInterval.endTime) { + unsharedRequestIds.remove(firstInterval.requestId); + unsharedRequestIds.remove(secondInterval.requestId); + } + } + } + + unsharedRequestIds.addAll(rejectedIds); + return unsharedRequestIds; + } + + public IdSet getSharedRequestIds() { + IdSet sharedRequestIds = new IdSet<>(Request.class); + rideIntervals.values().forEach(interval -> sharedRequestIds.add(interval.requestId)); + + sharedRequestIds.removeAll(getUnsharedRequestIds()); + return sharedRequestIds; + } + + public void install(Controler controller) { + ExclusiveRequestsHandler self = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(self); + } + }); + } + } + + @Test + void testSkillsConstraint() { + IdSet restrictedRequestIds = new IdSet<>(Request.class); + for (int i = 100; i <= 200; i++) { + restrictedRequestIds.add(Id.create("drt_" + i, Request.class)); + } + + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig).withSkills( + v -> v.getId().toString().endsWith("_1") ? Set.of("skill") : null, + r -> restrictedRequestIds.contains(r.getId()) ? Set.of("skill") : null); + + controller.addOverridingQSimModule(insertionModule); + + SkillsHandler handler = new SkillsHandler(); + handler.install(controller); + + controller.run(); + + int totalRequests = 0; + int restrictedRequests = 0; + int validMatchings = 0; + int invalidMatchings = 0; + + for (var item : handler.vehicles.entrySet()) { + totalRequests++; + + if (restrictedRequestIds.contains(item.getKey())) { + restrictedRequests++; + + if (item.getValue().toString().endsWith("_1")) { + validMatchings++; + } else { + invalidMatchings++; + } + } + } + + assertEquals(343, totalRequests); + assertEquals(67, restrictedRequests); + assertEquals(67, validMatchings); + assertEquals(0, invalidMatchings); + } + + static public class SkillsHandler implements PassengerPickedUpEventHandler { + private final IdMap> vehicles = new IdMap<>(Request.class); + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + vehicles.put(event.getRequestId(), event.getVehicleId()); + } + + public void install(Controler controller) { + SkillsHandler self = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(self); + } + }); + } + } + + @Test + void testRangeConstraint() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .withVehicleRange(100.0 * 1e3); + + controller.addOverridingQSimModule(insertionModule); + + DistanceHandler handler = new DistanceHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + for (var item : handler.distances.entrySet()) { + assertTrue(item.getValue() < 100.0 * 1e3); + } + } + + @Test + void testRangeConstraintWithCustomInstances() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + CustomCalculator distanceCalculator = new CustomCalculator(); + CustomCalculator distanceApproximator = new CustomCalculator(); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .withVehicleRange(100.0 * 1e3) // + .withDistanceCalculator(distanceCalculator) // + .withDistanceApproximator(distanceApproximator); + + controller.addOverridingQSimModule(insertionModule); + + DistanceHandler handler = new DistanceHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + for (var item : handler.distances.entrySet()) { + assertTrue(item.getValue() < 100.0 * 1e3); + } + + assertEquals(1470, distanceCalculator.calculatedDistances); + assertEquals(5288, distanceApproximator.calculatedDistances); + } + + @Test + void testRangeConstraintWithCustomInjection() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + CustomDistanceCalculator distanceCalculator = new CustomDistanceCalculator(); + CustomDistanceApproximator distanceApproximator = new CustomDistanceApproximator(); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .withVehicleRange(100.0 * 1e3) // + .withDistanceCalculator(CustomDistanceCalculator.class) // + .withDistanceApproximator(CustomDistanceApproximator.class); + + controller.addOverridingQSimModule(insertionModule); + + controller.addOverridingQSimModule(new AbstractDvrpModeQSimModule("drt") { + @Override + protected void configureQSim() { + bindModal(CustomDistanceCalculator.class).toInstance(distanceCalculator); + bindModal(CustomDistanceApproximator.class).toInstance(distanceApproximator); + } + }); + + DistanceHandler handler = new DistanceHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + for (var item : handler.distances.entrySet()) { + assertTrue(item.getValue() < 100.0 * 1e3); + } + + assertEquals(1470, distanceCalculator.calculatedDistances); + assertEquals(5288, distanceApproximator.calculatedDistances); + } + + static class CustomDistanceCalculator extends CustomCalculator { + } + + static class CustomDistanceApproximator extends CustomCalculator { + } + + static class CustomCalculator implements DistanceApproximator { + int calculatedDistances = 0; + + @Override + public synchronized double calculateDistance(double departureTime, Link fromLink, Link toLink) { + calculatedDistances++; + return CoordUtils.calcEuclideanDistance(fromLink.getCoord(), toLink.getCoord()); + } + } + + static public class DistanceHandler implements LinkEnterEventHandler { + private final Network network; + private final IdMap distances = new IdMap<>(Vehicle.class); + + DistanceHandler(Network network) { + this.network = network; + } + + @Override + public void handleEvent(LinkEnterEvent event) { + distances.compute(event.getVehicleId(), + (id, val) -> val == null ? 0.0 : val + network.getLinks().get(event.getLinkId()).getLength()); + } + + public void install(Controler controller) { + DistanceHandler self = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(self); + } + }); + } + } + + @Test + void testCustomConstraint() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .withConstraint((request, insertion, detourInfo) -> { + return Integer.parseInt(request.getId().toString().split("_")[1]) > 100; + }); + + controller.addOverridingQSimModule(insertionModule); + + RejectedRequestsHandler handler = new RejectedRequestsHandler(); + handler.install(controller); + + controller.run(); + + for (int i = 0; i <= 100; i++) { + assertTrue(handler.rejectedRequests.contains(Id.create("drt_" + i, Request.class))); + } + + assertEquals(112, handler.rejectedRequests.size()); + } + + static public class RejectedRequestsHandler implements PassengerRequestRejectedEventHandler { + private final IdSet rejectedRequests = new IdSet<>(Request.class); + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + rejectedRequests.add(event.getRequestId()); + } + + public void install(Controler controller) { + RejectedRequestsHandler self = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(self); + } + }); + } + } + + @Test + void testDefaults() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig); + controller.addOverridingQSimModule(insertionModule); + + ObjectiveHandler handler = new ObjectiveHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + assertEquals(16, handler.rejectedRequests); + assertEquals(2112862.0, handler.fleetDistance, 1e-3); + assertEquals(698710.0, handler.activeTime(), 1e-3); + assertEquals(280.19623, handler.meanWaitTime(), 1e-3); + } + + @Test + void testVehicleActiveTimeObjective() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .minimizeVehicleActiveTime(); + + controller.addOverridingQSimModule(insertionModule); + + ObjectiveHandler handler = new ObjectiveHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + assertEquals(16, handler.rejectedRequests); + assertEquals(2112862.0, handler.fleetDistance, 1e-3); + assertEquals(698710.0, handler.activeTime(), 1e-3); + assertEquals(280.19623, handler.meanWaitTime(), 1e-3); + } + + @Test + void testVehicleDistanceObjective() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .minimizeVehicleDistance(); + + controller.addOverridingQSimModule(insertionModule); + + ObjectiveHandler handler = new ObjectiveHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + assertEquals(22, handler.rejectedRequests); + assertEquals(2066658.0, handler.fleetDistance, 1e-3); + assertEquals(694149.0, handler.activeTime(), 1e-3); + assertEquals(280.61475, handler.meanWaitTime(), 1e-3); + } + + @Test + void testPassengerPassengerDelayObjective() { + Controler controller = createController(); + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + + DrtInsertionModule insertionModule = new DrtInsertionModule(drtConfig) // + .minimizePassengerDelay(1.0, 0.0); + + controller.addOverridingQSimModule(insertionModule); + + ObjectiveHandler handler = new ObjectiveHandler(controller.getScenario().getNetwork()); + handler.install(controller); + + controller.run(); + + assertEquals(23, handler.rejectedRequests); + assertEquals(2141019.0, handler.fleetDistance, 1e-3); + assertEquals(704897.0, handler.activeTime(), 1e-3); + assertEquals(241.17808, handler.meanWaitTime(), 1e-3); + } + + static public class ObjectiveHandler + implements PassengerWaitingEventHandler, PassengerPickedUpEventHandler, PassengerDroppedOffEventHandler, + PassengerRequestRejectedEventHandler, LinkEnterEventHandler, TaskEndedEventHandler { + private final IdMap departureTimes = new IdMap<>(Request.class); + private final IdMap pickupTimes = new IdMap<>(Request.class); + private final IdMap dropoffTimes = new IdMap<>(Request.class); + private final IdMap lastNonStayTime = new IdMap<>(DvrpVehicle.class); + + private int rejectedRequests = 0; + private double fleetDistance = 0.0; + + private final Network network; + + ObjectiveHandler(Network network) { + this.network = network; + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + rejectedRequests++; + } + + @Override + public void handleEvent(PassengerWaitingEvent event) { + departureTimes.put(event.getRequestId(), event.getTime()); + } + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + pickupTimes.put(event.getRequestId(), event.getTime()); + + } + + @Override + public void handleEvent(PassengerDroppedOffEvent event) { + dropoffTimes.put(event.getRequestId(), event.getTime()); + } + + @Override + public void handleEvent(LinkEnterEvent event) { + fleetDistance += network.getLinks().get(event.getLinkId()).getLength(); + } + + @Override + public void handleEvent(TaskEndedEvent event) { + if (DrtTaskBaseType.DRIVE.isBaseTypeOf(event.getTaskType())) { + lastNonStayTime.put(event.getDvrpVehicleId(), event.getTime()); + } + } + + public double meanWaitTime() { + double totalWaitTime = 0.0; + double totalRequests = 0.0; + + List waitTimes = new LinkedList<>(); + + for (Id requestId : departureTimes.keySet()) { + if (pickupTimes.containsKey(requestId) && dropoffTimes.containsKey(requestId)) { + totalWaitTime += pickupTimes.get(requestId) - departureTimes.get(requestId); + waitTimes.add(pickupTimes.get(requestId) - departureTimes.get(requestId)); + totalRequests += 1; + } + } + + return totalWaitTime / totalRequests; + } + + public double activeTime() { + return lastNonStayTime.values().stream().mapToDouble(d -> d).sum(); + } + + public void install(Controler controller) { + ObjectiveHandler self = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(self); + } + }); + } + } +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java index 1f57b4d54c7..05e08557722 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/eshifts/run/RunEShiftDrtScenarioIT.java @@ -1,6 +1,6 @@ package org.matsim.contrib.drt.extension.operations.eshifts.run; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; @@ -20,9 +20,9 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; @@ -38,7 +38,7 @@ public class RunEShiftDrtScenarioIT { private static final double TEMPERATURE = 20;// oC @Test - public void test() { + void test() { MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithOperationsConfigGroup::new); @@ -94,10 +94,10 @@ public void test() { modes.add("drt"); config.travelTimeCalculator().setAnalyzedModes(modes); - PlanCalcScoreConfigGroup.ModeParams scoreParams = new PlanCalcScoreConfigGroup.ModeParams("drt"); - config.planCalcScore().addModeParams(scoreParams); - PlanCalcScoreConfigGroup.ModeParams scoreParams2 = new PlanCalcScoreConfigGroup.ModeParams("walk"); - config.planCalcScore().addModeParams(scoreParams2); + ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt"); + config.scoring().addModeParams(scoreParams); + ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk"); + config.scoring().addModeParams(scoreParams2); config.plans().setInputFile(plansFile); config.network().setInputFile(networkFile); @@ -106,33 +106,33 @@ public void test() { config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); - final PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + final ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(8 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams other = new PlanCalcScoreConfigGroup.ActivityParams("other"); + final ScoringConfigGroup.ActivityParams other = new ScoringConfigGroup.ActivityParams("other"); other.setTypicalDuration(4 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams education = new PlanCalcScoreConfigGroup.ActivityParams("education"); + final ScoringConfigGroup.ActivityParams education = new ScoringConfigGroup.ActivityParams("education"); education.setTypicalDuration(6 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams shopping = new PlanCalcScoreConfigGroup.ActivityParams("shopping"); + final ScoringConfigGroup.ActivityParams shopping = new ScoringConfigGroup.ActivityParams("shopping"); shopping.setTypicalDuration(2 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + final ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(2 * 3600); - config.planCalcScore().addActivityParams(home); - config.planCalcScore().addActivityParams(other); - config.planCalcScore().addActivityParams(education); - config.planCalcScore().addActivityParams(shopping); - config.planCalcScore().addActivityParams(work); + config.scoring().addActivityParams(home); + config.scoring().addActivityParams(other); + config.scoring().addActivityParams(education); + config.scoring().addActivityParams(shopping); + config.scoring().addActivityParams(work); - final StrategyConfigGroup.StrategySettings stratSets = new StrategyConfigGroup.StrategySettings(); + final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings(); stratSets.setWeight(1); stratSets.setStrategyName("ChangeExpBeta"); - config.strategy().addStrategySettings(stratSets); + config.replanning().addStrategySettings(stratSets); - config.controler().setLastIteration(1); - config.controler().setWriteEventsInterval(1); + config.controller().setLastIteration(1); + config.controller().setWriteEventsInterval(1); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory("test/output/holzkirchen_eshifts"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory("test/output/holzkirchen_eshifts"); DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME); ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesIOTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesIOTest.java index d1e2e231a43..06bcd185b89 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesIOTest.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilitiesIOTest.java @@ -1,8 +1,8 @@ package org.matsim.contrib.drt.extension.operations.operationFacilities; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -13,11 +13,11 @@ public class OperationFacilitiesIOTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - @Test - public void test() { + @Test + void test() { OperationFacilitiesSpecification operationFacilities = new OperationFacilitiesSpecificationImpl(); @@ -58,12 +58,12 @@ public void test() { Id charger = Id.create(i, Charger.class); Id charger2 = Id.create(i+"_2", Charger.class); final OperationFacilitySpecification facility = copy.getOperationFacilitySpecifications().get(id); - Assert.assertEquals(linkId.toString(), facility.getLinkId().toString()); - Assert.assertEquals(coord.getX(), facility.getCoord().getX(), 0); - Assert.assertEquals(coord.getY(), facility.getCoord().getY(), 0); - Assert.assertEquals(capacity, facility.getCapacity()); - Assert.assertEquals(charger.toString(), facility.getChargers().get(0).toString()); - Assert.assertEquals(charger2.toString(), facility.getChargers().get(1).toString()); + Assertions.assertEquals(linkId.toString(), facility.getLinkId().toString()); + Assertions.assertEquals(coord.getX(), facility.getCoord().getX(), 0); + Assertions.assertEquals(coord.getY(), facility.getCoord().getY(), 0); + Assertions.assertEquals(capacity, facility.getCapacity()); + Assertions.assertEquals(charger.toString(), facility.getChargers().get(0).toString()); + Assertions.assertEquals(charger2.toString(), facility.getChargers().get(1).toString()); } for (int i = 10; i < 20; i++) { @@ -73,11 +73,11 @@ public void test() { int capacity = i; Id charger = Id.create(i, Charger.class); final OperationFacilitySpecification facility = copy.getOperationFacilitySpecifications().get(id); - Assert.assertEquals(linkId.toString(), facility.getLinkId().toString()); - Assert.assertEquals(coord.getX(), facility.getCoord().getX(), 0); - Assert.assertEquals(coord.getY(), facility.getCoord().getY(), 0); - Assert.assertEquals(capacity, facility.getCapacity()); - Assert.assertEquals(charger.toString(), facility.getChargers().get(0).toString()); + Assertions.assertEquals(linkId.toString(), facility.getLinkId().toString()); + Assertions.assertEquals(coord.getX(), facility.getCoord().getX(), 0); + Assertions.assertEquals(coord.getY(), facility.getCoord().getY(), 0); + Assertions.assertEquals(capacity, facility.getCapacity()); + Assertions.assertEquals(charger.toString(), facility.getChargers().get(0).toString()); } } } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/ShiftsIOTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/ShiftsIOTest.java index 37a86a85098..ff5eb57ecdc 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/ShiftsIOTest.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/ShiftsIOTest.java @@ -1,12 +1,12 @@ package org.matsim.contrib.drt.extension.operations.shifts; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import java.io.File; import java.util.Optional; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; import org.matsim.contrib.drt.extension.operations.shifts.io.DrtShiftsReader; @@ -22,8 +22,8 @@ */ public class ShiftsIOTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); private static final String TESTSHIFTSINPUT = "testShifts.xml"; @@ -36,7 +36,8 @@ public class ShiftsIOTest { private final Id oid2 = Id.create("op2", OperationFacility.class); - @Test public void testBasicReaderWriter() { + @Test + void testBasicReaderWriter() { DrtShiftsSpecification shiftsSpecification = new DrtShiftsSpecificationImpl(); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyTest.java index e40e1331388..b3e8db5e38d 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyTest.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/analysis/efficiency/ShiftEfficiencyTest.java @@ -9,8 +9,8 @@ package org.matsim.contrib.drt.extension.operations.shifts.analysis.efficiency; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.PersonMoneyEvent; import org.matsim.api.core.v01.network.Link; @@ -38,7 +38,7 @@ public class ShiftEfficiencyTest { * Test method for {@link ShiftEfficiencyTracker}. */ @Test - public void testDrtShiftEfficiency() { + void testDrtShiftEfficiency() { EventsManager events = new EventsManagerImpl(); ShiftEfficiencyTracker shiftEfficiencyTracker = new ShiftEfficiencyTracker(); @@ -53,7 +53,7 @@ public void testDrtShiftEfficiency() { events.processEvent(new DrtShiftStartedEvent(10 * 3600, shift1, vehicle1, link1) ); // should throw because vehicle is already registered with another shift - Assert.assertThrows(RuntimeException.class, () -> { + Assertions.assertThrows(RuntimeException.class, () -> { events.processEvent(new DrtShiftStartedEvent(10 * 3600, shift1, vehicle1, link1)); }); @@ -62,14 +62,14 @@ public void testDrtShiftEfficiency() { events.processEvent(new PassengerDroppedOffEvent(11 * 3600, "drt", request1, person1, vehicle1)); - Assert.assertTrue(shiftEfficiencyTracker.getCurrentRecord().getRequestsByShift().get(shift1).contains(request1)); + Assertions.assertTrue(shiftEfficiencyTracker.getCurrentRecord().getRequestsByShift().get(shift1).contains(request1)); events.processEvent(new PersonMoneyEvent(11 * 3600, person1, -FARE, DrtFareHandler.PERSON_MONEY_EVENT_PURPOSE_DRT_FARE, "drt", request1.toString())); - Assert.assertEquals(FARE, shiftEfficiencyTracker.getCurrentRecord().getRevenueByShift().get(shift1), MatsimTestUtils.EPSILON); + Assertions.assertEquals(FARE, shiftEfficiencyTracker.getCurrentRecord().getRevenueByShift().get(shift1), MatsimTestUtils.EPSILON); - Assert.assertFalse(shiftEfficiencyTracker.getCurrentRecord().getFinishedShifts().containsKey(shift1)); + Assertions.assertFalse(shiftEfficiencyTracker.getCurrentRecord().getFinishedShifts().containsKey(shift1)); events.processEvent(new DrtShiftEndedEvent(20 * 3600, shift1, vehicle1, link1, operationFacility1)); - Assert.assertTrue(shiftEfficiencyTracker.getCurrentRecord().getFinishedShifts().containsKey(shift1)); + Assertions.assertTrue(shiftEfficiencyTracker.getCurrentRecord().getFinishedShifts().containsKey(shift1)); } } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java index 8b0e6b3a179..5b3f79ea7dd 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunMultiHubShiftDrtScenarioIT.java @@ -1,6 +1,6 @@ package org.matsim.contrib.drt.extension.operations.shifts.run; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator; @@ -17,9 +17,9 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.examples.ExamplesUtils; @@ -29,7 +29,7 @@ public class RunMultiHubShiftDrtScenarioIT { @Test - public void test() { + void test() { MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithOperationsConfigGroup::new); @@ -83,10 +83,10 @@ public void test() { modes.add("drt"); config.travelTimeCalculator().setAnalyzedModes(modes); - PlanCalcScoreConfigGroup.ModeParams scoreParams = new PlanCalcScoreConfigGroup.ModeParams("drt"); - config.planCalcScore().addModeParams(scoreParams); - PlanCalcScoreConfigGroup.ModeParams scoreParams2 = new PlanCalcScoreConfigGroup.ModeParams("walk"); - config.planCalcScore().addModeParams(scoreParams2); + ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt"); + config.scoring().addModeParams(scoreParams); + ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk"); + config.scoring().addModeParams(scoreParams2); config.plans().setInputFile(plansFile); config.network().setInputFile(networkFile); @@ -95,33 +95,33 @@ public void test() { config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); - final PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + final ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(8 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams other = new PlanCalcScoreConfigGroup.ActivityParams("other"); + final ScoringConfigGroup.ActivityParams other = new ScoringConfigGroup.ActivityParams("other"); other.setTypicalDuration(4 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams education = new PlanCalcScoreConfigGroup.ActivityParams("education"); + final ScoringConfigGroup.ActivityParams education = new ScoringConfigGroup.ActivityParams("education"); education.setTypicalDuration(6 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams shopping = new PlanCalcScoreConfigGroup.ActivityParams("shopping"); + final ScoringConfigGroup.ActivityParams shopping = new ScoringConfigGroup.ActivityParams("shopping"); shopping.setTypicalDuration(2 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + final ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(2 * 3600); - config.planCalcScore().addActivityParams(home); - config.planCalcScore().addActivityParams(other); - config.planCalcScore().addActivityParams(education); - config.planCalcScore().addActivityParams(shopping); - config.planCalcScore().addActivityParams(work); + config.scoring().addActivityParams(home); + config.scoring().addActivityParams(other); + config.scoring().addActivityParams(education); + config.scoring().addActivityParams(shopping); + config.scoring().addActivityParams(work); - final StrategyConfigGroup.StrategySettings stratSets = new StrategyConfigGroup.StrategySettings(); + final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings(); stratSets.setWeight(1); stratSets.setStrategyName("ChangeExpBeta"); - config.strategy().addStrategySettings(stratSets); + config.replanning().addStrategySettings(stratSets); - config.controler().setLastIteration(1); - config.controler().setWriteEventsInterval(1); + config.controller().setLastIteration(1); + config.controller().setWriteEventsInterval(1); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory("test/output/holzkirchen_shifts_multiHub"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory("test/output/holzkirchen_shifts_multiHub"); DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME); ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java index 3205bae0a4f..28034b937c6 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java @@ -1,6 +1,6 @@ package org.matsim.contrib.drt.extension.operations.shifts.run; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.drt.analysis.zonal.DrtZonalSystemParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator; @@ -17,9 +17,9 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.examples.ExamplesUtils; @@ -30,7 +30,7 @@ public class RunShiftDrtScenarioIT { @Test - public void test() { + void test() { MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithOperationsConfigGroup::new); @@ -84,10 +84,10 @@ public void test() { modes.add("drt"); config.travelTimeCalculator().setAnalyzedModes(modes); - PlanCalcScoreConfigGroup.ModeParams scoreParams = new PlanCalcScoreConfigGroup.ModeParams("drt"); - config.planCalcScore().addModeParams(scoreParams); - PlanCalcScoreConfigGroup.ModeParams scoreParams2 = new PlanCalcScoreConfigGroup.ModeParams("walk"); - config.planCalcScore().addModeParams(scoreParams2); + ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt"); + config.scoring().addModeParams(scoreParams); + ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk"); + config.scoring().addModeParams(scoreParams2); config.plans().setInputFile(plansFile); config.network().setInputFile(networkFile); @@ -95,33 +95,33 @@ public void test() { config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); - final PlanCalcScoreConfigGroup.ActivityParams home = new PlanCalcScoreConfigGroup.ActivityParams("home"); + final ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); home.setTypicalDuration(8 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams other = new PlanCalcScoreConfigGroup.ActivityParams("other"); + final ScoringConfigGroup.ActivityParams other = new ScoringConfigGroup.ActivityParams("other"); other.setTypicalDuration(4 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams education = new PlanCalcScoreConfigGroup.ActivityParams("education"); + final ScoringConfigGroup.ActivityParams education = new ScoringConfigGroup.ActivityParams("education"); education.setTypicalDuration(6 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams shopping = new PlanCalcScoreConfigGroup.ActivityParams("shopping"); + final ScoringConfigGroup.ActivityParams shopping = new ScoringConfigGroup.ActivityParams("shopping"); shopping.setTypicalDuration(2 * 3600); - final PlanCalcScoreConfigGroup.ActivityParams work = new PlanCalcScoreConfigGroup.ActivityParams("work"); + final ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); work.setTypicalDuration(2 * 3600); - config.planCalcScore().addActivityParams(home); - config.planCalcScore().addActivityParams(other); - config.planCalcScore().addActivityParams(education); - config.planCalcScore().addActivityParams(shopping); - config.planCalcScore().addActivityParams(work); + config.scoring().addActivityParams(home); + config.scoring().addActivityParams(other); + config.scoring().addActivityParams(education); + config.scoring().addActivityParams(shopping); + config.scoring().addActivityParams(work); - final StrategyConfigGroup.StrategySettings stratSets = new StrategyConfigGroup.StrategySettings(); + final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings(); stratSets.setWeight(1); stratSets.setStrategyName("ChangeExpBeta"); - config.strategy().addStrategySettings(stratSets); + config.replanning().addStrategySettings(stratSets); - config.controler().setLastIteration(1); - config.controler().setWriteEventsInterval(1); + config.controller().setLastIteration(1); + config.controller().setWriteEventsInterval(1); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory("test/output/holzkirchen_shifts"); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory("test/output/holzkirchen_shifts"); DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME); ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME); diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/preplanned/optimizer/RunPreplannedDrtExampleIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/preplanned/optimizer/RunPreplannedDrtExampleIT.java index 11bd8d5328b..e5477142a92 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/preplanned/optimizer/RunPreplannedDrtExampleIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/preplanned/optimizer/RunPreplannedDrtExampleIT.java @@ -25,15 +25,11 @@ import static org.matsim.contrib.drt.extension.preplanned.optimizer.PreplannedDrtOptimizer.PreplannedStop; import java.net.URL; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.extension.preplanned.optimizer.PreplannedDrtOptimizer.PreplannedRequestKey; import org.matsim.contrib.drt.extension.preplanned.optimizer.PreplannedDrtOptimizer.PreplannedSchedules; @@ -47,40 +43,40 @@ */ public class RunPreplannedDrtExampleIT { @Test - public void testRun() { + void testRun() { // scenario with 1 shared taxi (max 2 pax) and 10 requests URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "one_shared_taxi_config.xml"); // create preplanned requests (they will be mapped to drt requests created during simulation) var preplannedRequest_0 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_0"), Id.createLinkId("114"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_0")), Id.createLinkId("114"), Id.createLinkId("349")), 0.0, 900.0, 844.4); var preplannedRequest_1 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_1"), Id.createLinkId("144"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_1")), Id.createLinkId("144"), Id.createLinkId("437")), 300.0, 1200.0, 1011.8); var preplannedRequest_2 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_2"), Id.createLinkId("223"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_2")), Id.createLinkId("223"), Id.createLinkId("347")), 600.0, 1500.0, 1393.7); var preplannedRequest_3 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_3"), Id.createLinkId("234"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_3")), Id.createLinkId("234"), Id.createLinkId("119")), 900.0, 1800.0, 1825.0); var preplannedRequest_4 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_4"), Id.createLinkId("314"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_4")), Id.createLinkId("314"), Id.createLinkId("260")), 1200.0, 2100.0, 1997.6); var preplannedRequest_5 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_5"), Id.createLinkId("333"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_5")), Id.createLinkId("333"), Id.createLinkId("438")), 1500.0, 2400.0, 2349.6); var preplannedRequest_6 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_6"), Id.createLinkId("325"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_6")), Id.createLinkId("325"), Id.createLinkId("111")), 1800.0, 2700.0, 2600.2); var preplannedRequest_7 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_7"), Id.createLinkId("412"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_7")), Id.createLinkId("412"), Id.createLinkId("318")), 2100.0, 3000.0, 2989.9); var preplannedRequest_8 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_8"), Id.createLinkId("455"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_8")), Id.createLinkId("455"), Id.createLinkId("236")), 2400.0, 3300.0, 3110.5); var preplannedRequest_9 = new PreplannedRequest( - new PreplannedRequestKey(Id.createPersonId("passenger_9"), Id.createLinkId("139"), + new PreplannedRequestKey(Set.of(Id.createPersonId("passenger_9")), Id.createLinkId("139"), Id.createLinkId("330")), 2700.0, 3600.0, 3410.5); var preplannedRequests = List.of(preplannedRequest_0, preplannedRequest_1, preplannedRequest_2, preplannedRequest_3, preplannedRequest_4, preplannedRequest_5, preplannedRequest_6); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java index 17f55751141..399804f9aee 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtAnalysisControlerListener.java @@ -35,7 +35,6 @@ import org.jfree.data.xy.XYSeries; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.events.PersonDepartureEvent; import org.matsim.api.core.v01.events.PersonMoneyEvent; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; @@ -110,7 +109,7 @@ public class DrtAnalysisControlerListener implements IterationEndsListener, Shut this.vehicleOccupancyProfileCalculator = vehicleOccupancyProfileCalculator; this.drtCfg = drtCfg; this.qSimCfg = config.qsim(); - runId = Optional.ofNullable(config.controler().getRunId()).orElse(notAvailableString); + runId = Optional.ofNullable(config.controller().getRunId()).orElse(notAvailableString); maxcap = findMaxVehicleCapacity(fleet); format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); @@ -121,39 +120,48 @@ public class DrtAnalysisControlerListener implements IterationEndsListener, Shut this.delimiter = config.global().getDefaultDelimiter(); } - private record DrtLeg(Id request, double departureTime, Id person, Id vehicle, Id fromLinkId, Coord fromCoord, + private record DrtLeg(Id request, double submissionTime, double departureTime, Id person, Id vehicle, Id fromLinkId, Coord fromCoord, Id toLinkId, Coord toCoord, double waitTime, double unsharedDistanceEstimate_m, double unsharedTimeEstimate_m, - double arrivalTime, double fare, double latestDepartureTime, double latestArrivalTime) { + double arrivalTime, double fare, double earliestDepartureTime, double latestDepartureTime, double latestArrivalTime) { } - private static DrtLeg newDrtLeg(EventSequence sequence, Function, ? extends Link> linkProvider) { + private static List newDrtLegs(EventSequence sequence, Function, ? extends Link> linkProvider) { Preconditions.checkArgument(sequence.isCompleted()); + List legs = new ArrayList<>(); DrtRequestSubmittedEvent submittedEvent = sequence.getSubmitted(); - PersonDepartureEvent departureEvent = sequence.getDeparture().get(); - PassengerPickedUpEvent pickedUpEvent = sequence.getPickedUp().get(); + + Map, EventSequence.PersonEvents> personEvents = sequence.getPersonEvents(); + var request = submittedEvent.getRequestId(); - var departureTime = departureEvent.getTime(); - var person = submittedEvent.getPersonId(); - var vehicle = pickedUpEvent.getVehicleId(); + var submissionTime = submittedEvent.getTime(); var fromLinkId = submittedEvent.getFromLinkId(); var fromCoord = linkProvider.apply(fromLinkId).getToNode().getCoord(); var toLinkId = submittedEvent.getToLinkId(); var toCoord = linkProvider.apply(toLinkId).getToNode().getCoord(); - var waitTime = pickedUpEvent.getTime() - departureEvent.getTime(); var unsharedDistanceEstimate_m = submittedEvent.getUnsharedRideDistance(); var unsharedTimeEstimate_m = submittedEvent.getUnsharedRideTime(); - var arrivalTime = sequence.getDroppedOff().get().getTime(); // PersonMoneyEvent has negative amount because the agent's money is reduced -> for the operator that is a positive amount var fare = sequence.getDrtFares().stream().mapToDouble(PersonMoneyEvent::getAmount).sum(); + var earliestDepartureTime = sequence.getSubmitted().getEarliestDepartureTime(); var latestDepartureTime = sequence.getSubmitted().getLatestPickupTime(); var latestArrivalTime = sequence.getSubmitted().getLatestDropoffTime(); - return new DrtLeg(request, departureTime, person, vehicle, fromLinkId, fromCoord, toLinkId, toCoord, waitTime, unsharedDistanceEstimate_m, - unsharedTimeEstimate_m, arrivalTime, fare, latestDepartureTime, latestArrivalTime); + + for (Id person : submittedEvent.getPersonIds()) { + var departureTime = personEvents.get(person).getDeparture().get().getTime(); + PassengerPickedUpEvent pickedUp = personEvents.get(person).getPickedUp().get(); + var vehicle = pickedUp.getVehicleId(); + var waitTime = pickedUp.getTime() - personEvents.get(person).getDeparture().get().getTime(); + var arrivalTime = personEvents.get(person).getDroppedOff().get().getTime(); + legs.add(new DrtLeg(request, submissionTime, departureTime, person, vehicle, fromLinkId, fromCoord, toLinkId, toCoord, waitTime, unsharedDistanceEstimate_m, + unsharedTimeEstimate_m, arrivalTime, fare, earliestDepartureTime, latestDepartureTime, latestArrivalTime)); + } + return legs; } @Override public void notifyIterationEnds(IterationEndsEvent event) { - boolean createGraphs = event.getServices().getConfig().controler().isCreateGraphs(); + int createGraphsInterval = event.getServices().getConfig().controller().getCreateGraphsInterval(); + boolean createGraphs = createGraphsInterval >0 && event.getIteration() % createGraphsInterval == 0; writeAndPlotWaitTimeEstimateComparison(drtEventSequenceCollector.getPerformedRequestSequences().values(), filename(event, "waitTimeComparison", ".png"), filename(event, "waitTimeComparison", ".csv"), createGraphs); @@ -162,33 +170,37 @@ public void notifyIterationEnds(IterationEndsEvent event) { .values() .stream() .filter(EventSequence::isCompleted) - .map(sequence -> newDrtLeg(sequence, network.getLinks()::get)) + .map(sequence -> newDrtLegs(sequence, network.getLinks()::get)) + .flatMap(Collection::stream) .sorted(Comparator.comparing(leg -> leg.departureTime)) .collect(toList()); List rejectionEvents = drtEventSequenceCollector.getRejectedRequestSequences() - .values() - .stream() - .map(eventSequence -> eventSequence.getRejected().get()) - .sorted(Comparator.comparing(rejectionEvent -> rejectionEvent.getTime())) - .collect(toList()); + .values() + .stream() + .map(eventSequence -> eventSequence.getRejected().get()) + .sorted(Comparator.comparing(rejectionEvent -> rejectionEvent.getTime())) + .collect(toList()); collection2Text(drtEventSequenceCollector.getRejectedRequestSequences().values(), filename(event, "drt_rejections", ".csv"), - String.join(delimiter, "time", "personId", "fromLinkId", "toLinkId", "fromX", "fromY", "toX", "toY"), seq -> { + String.join(delimiter, "time", "personIds", "requestId", "fromLinkId", "toLinkId", "fromX", "fromY", "toX", "toY", "cause"), seq -> { DrtRequestSubmittedEvent submission = seq.getSubmitted(); Coord fromCoord = network.getLinks().get(submission.getFromLinkId()).getToNode().getCoord(); Coord toCoord = network.getLinks().get(submission.getToLinkId()).getToNode().getCoord(); + PassengerRequestRejectedEvent rejection = seq.getRejected().get(); return String.join(delimiter, submission.getTime() + "",// - submission.getPersonId() + "",// + submission.getPersonIds().stream().map(Object::toString).collect(Collectors.joining("-")) + "",// + submission.getRequestId() + "",// submission.getFromLinkId() + "",// submission.getToLinkId() + "",// fromCoord.getX() + "",// fromCoord.getY() + "",// toCoord.getX() + "",// - toCoord.getY() + ""); + toCoord.getY() + "",// + rejection.getCause()); }); - double rejectionRate = (double)drtEventSequenceCollector.getRejectedRequestSequences().size() + double rejectionRate = (double) drtEventSequenceCollector.getRejectedRequestSequences().size() / drtEventSequenceCollector.getRequestSubmissions().size(); String legsSummarize = summarizeLegs(legs, drtVehicleStats.getTravelDistances(), drtEventSequenceCollector.getDrtFarePersonMoneyEvents(), delimiter); @@ -209,8 +221,11 @@ public void notifyIterationEnds(IterationEndsEvent event) { String occStats = summarizeDetailedOccupancyStats(drtVehicleStats.getVehicleStates(), delimiter, maxcap); writeIterationVehicleStats(vehStats, occStats, event.getIteration()); if (drtCfg.plotDetailedCustomerStats) { - String header = String.join(delimiter, "departureTime",// + String header = String.join(delimiter, // + "submissionTime", // + "departureTime",// "personId",// + "requestId",// "vehicleId",// "fromLinkId",// "fromX",// @@ -224,12 +239,15 @@ public void notifyIterationEnds(IterationEndsEvent event) { "travelDistance_m",// "directTravelDistance_m",// "fareForLeg", // + "earliestDepartureTime", "latestDepartureTime", // "latestArrivalTime"); collection2Text(legs, filename(event, "drt_legs", ".csv"), header, leg -> String.join(delimiter,// + (Double)leg.submissionTime + "",// (Double)leg.departureTime + "",// leg.person + "",// + leg.request + "",// leg.vehicle + "",// leg.fromLinkId + "",// format.format(leg.fromCoord.getX()),// @@ -243,13 +261,14 @@ public void notifyIterationEnds(IterationEndsEvent event) { format.format(drtVehicleStats.getTravelDistances().get(leg.request)),// format.format(leg.unsharedDistanceEstimate_m),// format.format(leg.fare), // + format.format(leg.earliestDepartureTime), // format.format(leg.latestDepartureTime), // format.format(leg.latestArrivalTime))); } writeVehicleDistances(drtVehicleStats.getVehicleStates(), filename(event, "vehicleDistanceStats", ".csv"), delimiter); analyseDetours(network, legs, drtVehicleStats.getTravelDistances(), drtCfg, filename(event, "drt_detours"), createGraphs, delimiter); analyseWaitTimes(filename(event, "waitStats"), legs, 1800, createGraphs, delimiter); - analyseRejections(filename(event,"drt_rejections_perTimeBin"), rejectionEvents,1800, createGraphs, delimiter); + analyseRejections(filename(event, "drt_rejections_perTimeBin"), rejectionEvents, 1800, createGraphs, delimiter); analyseConstraints(filename(event, "constraints"), legs, createGraphs); double endTime = qSimCfg.getEndTime() @@ -331,7 +350,7 @@ private void writeIterationPassengerStats(String summarizeLegs, int it) { private void writeIterationVehicleStats(String summarizeVehicles, String vehOcc, int it) { try (var bw = getAppendingBufferedWriter("drt_vehicle_stats", ".csv")) { if (!vheaderWritten) { - bw.write(line("runId", "iteration", "vehicles", "totalServiceDuration", "totalDistance", "totalEmptyDistance", "emptyRatio", "totalPassengerDistanceTraveled", + bw.write(line("runId", "iteration", "vehicles", "totalServiceDuration", "totalDistance", "totalEmptyDistance", "emptyRatio", "totalPassengerDistanceTraveled", "averageDrivenDistance", "averageEmptyDistance", "averagePassengerDistanceTraveled", "d_p/d_t", "l_det", "minShareIdleVehicles", "minCountIdleVehicles")); } @@ -363,11 +382,17 @@ private void writeAndPlotWaitTimeEstimateComparison(Collection pe bw.append(line("RequestId", "actualWaitTime", "estimatedWaitTime", "deviate")); for (EventSequence seq : performedRequestEventSequences) { - if (seq.getPickedUp().isPresent()) { - double actualWaitTime = seq.getPickedUp().get().getTime() - seq.getDeparture().get().getTime(); - double estimatedWaitTime = seq.getScheduled().get().getPickupTime() - seq.getDeparture().get().getTime(); - bw.append(line(seq.getSubmitted().getRequestId(), actualWaitTime, estimatedWaitTime, actualWaitTime - estimatedWaitTime)); - times.add(actualWaitTime, estimatedWaitTime); + List> personIds = seq.getSubmitted().getPersonIds(); + for (Id person : personIds) { + if(seq.getPersonEvents().containsKey(person)) { + EventSequence.PersonEvents personEvents = seq.getPersonEvents().get(person); + if(personEvents.getPickedUp().isPresent() && personEvents.getDeparture().isPresent()) { + double actualWaitTime = personEvents.getPickedUp().get().getTime() - personEvents.getDeparture().get().getTime(); + double estimatedWaitTime = seq.getScheduled().get().getPickupTime() - seq.getSubmitted().getEarliestDepartureTime(); + bw.append(line(seq.getSubmitted().getRequestId(), actualWaitTime, estimatedWaitTime, actualWaitTime - estimatedWaitTime)); + times.add(actualWaitTime, estimatedWaitTime); + } + } } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtEventSequenceCollector.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtEventSequenceCollector.java index f70931a4e06..b8b095cd1dc 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtEventSequenceCollector.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtEventSequenceCollector.java @@ -24,12 +24,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -52,22 +52,62 @@ import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEvent; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEventHandler; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; /** - * Creates PerformedRequestEventSequence (for scheduled requests) and RejectedRequestEventSequence (for rejected requests). - * Almost all data for request/leg analysis is there (except info on actual paths), so should be quite reusable. + * Creates PerformedRequestEventSequence (for scheduled requests) and + * RejectedRequestEventSequence (for rejected requests). Almost all data for + * request/leg analysis is there (except info on actual paths), so should be + * quite reusable. + * + * Without prebooking, the order of sequences is always the same: First the + * agent *departs* then the request is *submitted*, then it is *rejected* or + * picked up. With prebooking, the order of departure and submission can be + * reversed: An agent first submits the request, and only later departs on the + * leg. Since *departure* is core MATSim, the respective event has no + * information about the request identifier. It could now happen that two + * submission with same characteristics have been submitted (person id, origin + * id). Then it is not clear which request belongs to the current departure. For + * that purpose the PassengerWaiting event has been introduced which is fired + * right after a departure has been processed by a DRT-related PassengerEngine. + * This events allows to link the latest departure of an agent to a request id. * * @author jbischoff * @author Michal Maciejewski + * @author Sebastian Hörl (sebhoerl), IRT SystemX */ public class DrtEventSequenceCollector implements PassengerRequestRejectedEventHandler, PassengerRequestScheduledEventHandler, - DrtRequestSubmittedEventHandler, PassengerPickedUpEventHandler, PassengerDroppedOffEventHandler, + DrtRequestSubmittedEventHandler, PassengerWaitingEventHandler, PassengerPickedUpEventHandler, PassengerDroppedOffEventHandler, PersonMoneyEventHandler, PersonDepartureEventHandler { public static class EventSequence { + + public static class PersonEvents { + + @Nullable + private PersonDepartureEvent departure; + @Nullable + private PassengerPickedUpEvent pickedUp; + @Nullable + private PassengerDroppedOffEvent droppedOff; + + public Optional getDeparture() { + return Optional.ofNullable(departure); + } + + public Optional getPickedUp() { + return Optional.ofNullable(pickedUp); + } + + public Optional getDroppedOff() { + return Optional.ofNullable(droppedOff); + } + } private final DrtRequestSubmittedEvent submitted; @Nullable @@ -75,12 +115,8 @@ public static class EventSequence { @Nullable private PassengerRequestRejectedEvent rejected; - @Nullable - private PersonDepartureEvent departure; - @Nullable - private PassengerPickedUpEvent pickedUp; - @Nullable - private PassengerDroppedOffEvent droppedOff; + private final Map, PersonEvents> personEvents = new HashMap<>(); + @Nullable private List drtFares = new LinkedList<>(); @@ -88,15 +124,17 @@ public static class EventSequence { this.submitted = Objects.requireNonNull(submitted); } - public EventSequence(PersonDepartureEvent departure, DrtRequestSubmittedEvent submitted, + public EventSequence(Id personId, PersonDepartureEvent departure, DrtRequestSubmittedEvent submitted, PassengerRequestScheduledEvent scheduled, PassengerPickedUpEvent pickedUp, PassengerDroppedOffEvent droppedOff, List drtFares) { this.submitted = Objects.requireNonNull(submitted); this.scheduled = scheduled; - this.departure = departure; - this.pickedUp = pickedUp; - this.droppedOff = droppedOff; this.drtFares = new ArrayList<>(drtFares); + PersonEvents personEvents = new PersonEvents(); + personEvents.departure = departure; + personEvents.pickedUp = pickedUp; + personEvents.droppedOff = droppedOff; + this.personEvents.put(personId, personEvents); } public DrtRequestSubmittedEvent getSubmitted() { @@ -111,24 +149,17 @@ public Optional getRejected() { return Optional.ofNullable(rejected); } - public Optional getDeparture() { - return Optional.ofNullable(departure); - } - - public Optional getPickedUp() { - return Optional.ofNullable(pickedUp); + public Map, PersonEvents> getPersonEvents() { + return personEvents; } - public Optional getDroppedOff() { - return Optional.ofNullable(droppedOff); - } public List getDrtFares() { return Collections.unmodifiableList(drtFares); } public boolean isCompleted() { - return droppedOff != null; + return personEvents.values().stream().allMatch(pe -> pe.droppedOff != null); } } @@ -137,8 +168,8 @@ public boolean isCompleted() { private final Map, EventSequence> sequences = new HashMap<>(); private final List drtFarePersonMoneyEvents = new ArrayList<>(); - private final Map, List> sequencesWithoutDeparture = new HashMap<>(); - private final Map, List> departuresWithoutSequence = new HashMap<>(); + private final Map, PersonDepartureEvent> latestDepartures = new HashMap<>(); + private final Map, List> waitingForSubmission = new HashMap<>(); public DrtEventSequenceCollector(String mode) { this.mode = mode; @@ -158,6 +189,8 @@ public Map, EventSequence> getRejectedRequestSequences() { public Map, EventSequence> getPerformedRequestSequences() { return sequences.entrySet().stream() // .filter(e -> e.getValue().getRejected().isEmpty()) // + .filter(e -> e.getValue().personEvents.values().stream().allMatch(pe -> pe.departure != null)) // + .filter(e -> e.getValue().personEvents.values().stream().allMatch(pe -> pe.pickedUp != null)) // .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); } @@ -169,8 +202,8 @@ public List getDrtFarePersonMoneyEvents() { public void reset(int iteration) { sequences.clear(); drtFarePersonMoneyEvents.clear(); - sequencesWithoutDeparture.clear(); - departuresWithoutSequence.clear(); + latestDepartures.clear(); + waitingForSubmission.clear(); } @Override @@ -179,14 +212,14 @@ public void handleEvent(DrtRequestSubmittedEvent event) { EventSequence sequence = new EventSequence(event); sequences.put(event.getRequestId(), sequence); - PersonDepartureEvent departureEvent = popDepartureForSubmission(event); - - if (departureEvent == null) { - // We have a submitted request, but no departure event yet (i.e. a prebooking). We start the - // sequence and note down the person id to fill in the departure event later on. - sequencesWithoutDeparture.computeIfAbsent(event.getPersonId(), id -> new LinkedList<>()).add(sequence); - } else { - sequence.departure = departureEvent; + // if we already have a departure + List waiting = waitingForSubmission.remove(event.getRequestId()); + if(waiting != null) { + for (PersonDepartureEvent departure : waiting) { + sequence.getPersonEvents().computeIfAbsent( + departure.getPersonId(), personId -> new EventSequence.PersonEvents() + ).departure = departure; + } } } } @@ -194,15 +227,31 @@ public void handleEvent(DrtRequestSubmittedEvent event) { @Override public void handleEvent(PersonDepartureEvent event) { if (event.getLegMode().equals(mode)) { - EventSequence sequence = popSequenceForDeparture(event); - - if (sequence == null) { - // We have a departure event, but no submission yet (i.e. and instant booking). - // We note down the departure event here to recover it later when the submission - // is down (usually right after). - departuresWithoutSequence.computeIfAbsent(event.getPersonId(), id -> new LinkedList<>()).add(event); - } else { - sequence.departure = event; + // note down the departure event here, for now we don't know which request it + // belongs to, see below + Preconditions.checkState(!latestDepartures.containsKey(event.getPersonId()), + "Attempt to register a departure event for " + mode + " and person " + event.getPersonId() + + ", but there is still a departure that has not been consumed"); + latestDepartures.put(event.getPersonId(), event); + } + } + + @Override + public void handleEvent(PassengerWaitingEvent event) { + if (event.getMode().equals(mode)) { + EventSequence sequence = sequences.get(event.getRequestId()); + for (Id personId : event.getPersonIds()) { + // must exist, otherwise something is wrong + PersonDepartureEvent departureEvent = Objects.requireNonNull(latestDepartures.remove(personId)); + + if (sequence != null) { + // prebooked request, we already have the submission + Verify.verifyNotNull(sequence.submitted); + sequence.personEvents.computeIfAbsent(personId, p -> new EventSequence.PersonEvents()).departure = departureEvent; + } else { + // immediate request, submission event should come soon + waitingForSubmission.computeIfAbsent(event.getRequestId(), requestId -> new ArrayList<>()).add(departureEvent); + } } } } @@ -224,14 +273,14 @@ public void handleEvent(PassengerRequestRejectedEvent event) { @Override public void handleEvent(PassengerPickedUpEvent event) { if (event.getMode().equals(mode)) { - sequences.get(event.getRequestId()).pickedUp = event; + sequences.get(event.getRequestId()).personEvents.get(event.getPersonId()).pickedUp = event; } } @Override public void handleEvent(PassengerDroppedOffEvent event) { if (event.getMode().equals(mode)) { - sequences.get(event.getRequestId()).droppedOff = event; + sequences.get(event.getRequestId()).personEvents.get(event.getPersonId()).droppedOff = event; } } @@ -254,72 +303,4 @@ public void handleEvent(PersonMoneyEvent event) { } } } - - /* - * This function is helper that finds a PersonDepartureEvent for a given - * DrtRequestSubmittedEvent. This means that the departure has happened before - * submission, which is the usually case for instant requests. - */ - private PersonDepartureEvent popDepartureForSubmission(DrtRequestSubmittedEvent event) { - List potentialDepartures = departuresWithoutSequence.get(event.getPersonId()); - PersonDepartureEvent result = null; - - if (potentialDepartures != null) { - Iterator iterator = potentialDepartures.iterator(); - - while (iterator.hasNext()) { - PersonDepartureEvent departureEvent = iterator.next(); - - if (event.getFromLinkId().equals(departureEvent.getLinkId())) { - if (result != null) { - throw new IllegalStateException( - "Ambiguous matching between submission and departure - not sure how to solve this"); - } - - iterator.remove(); - result = departureEvent; - } - } - - if (potentialDepartures.size() == 0) { - departuresWithoutSequence.remove(event.getPersonId()); - } - } - - return result; - } - - /* - * This function is helper that finds a sequence given a PersonDepartureEvent. - * This means that a sequence has started (the request has been submitted) - * before the agent has departed, i.e. this is a pre-booking of some sort. - */ - private EventSequence popSequenceForDeparture(PersonDepartureEvent event) { - EventSequence result = null; - List potentialSequences = sequencesWithoutDeparture.get(event.getPersonId()); - - if (potentialSequences != null) { - Iterator iterator = potentialSequences.iterator(); - - while (iterator.hasNext()) { - EventSequence sequence = iterator.next(); - - if (sequence.submitted.getFromLinkId().equals(event.getLinkId())) { - if (result != null) { - throw new IllegalStateException( - "Ambiguous matching between submission and departure - not sure how to solve this"); - } - - iterator.remove(); - result = sequence; - } - } - - if (potentialSequences.size() == 0) { - sequencesWithoutDeparture.remove(event.getPersonId()); - } - } - - return result; - } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtModeAnalysisModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtModeAnalysisModule.java index e362e4d4935..67d38dad708 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtModeAnalysisModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/DrtModeAnalysisModule.java @@ -34,6 +34,7 @@ import org.matsim.contrib.drt.schedule.DrtDriveTask; import org.matsim.contrib.drt.schedule.DrtStayTask; import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; +import org.matsim.contrib.drt.sharingmetrics.SharingMetricsModule; import org.matsim.contrib.dvrp.analysis.ExecutedScheduleCollector; import org.matsim.contrib.dvrp.fleet.FleetSpecification; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; @@ -136,5 +137,7 @@ public void install() { getter.getModal(DrtVehicleDistanceStats.class), getter.get(MatsimServices.class), getter.get(Network.class), getter.getModal(DrtEventSequenceCollector.class), getter.getModal(VehicleOccupancyProfileCalculator.class)))) .asEagerSingleton(); + + install(new SharingMetricsModule(drtCfg)); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java index be03eda92f5..40c885b5531 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java @@ -39,6 +39,8 @@ import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Polygon; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector.EventSequence; import org.matsim.contrib.drt.run.DrtConfigGroup; @@ -138,11 +140,13 @@ private Map createZonalStats() { zoneStats.put(zoneIdForOutsideOfZonalSystem, new DescriptiveStatistics()); for (EventSequence seq : requestAnalyzer.getPerformedRequestSequences().values()) { - if (seq.getPickedUp().isPresent()) { - DrtZone zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId()); - final String zoneStr = zone != null ? zone.getId() : zoneIdForOutsideOfZonalSystem; - double waitTime = seq.getPickedUp().get().getTime() - seq.getSubmitted().getTime(); - zoneStats.get(zoneStr).addValue(waitTime); + for (Map.Entry, EventSequence.PersonEvents> entry : seq.getPersonEvents().entrySet()) { + if(entry.getValue().getPickedUp().isPresent()) { + DrtZone zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId()); + final String zoneStr = zone != null ? zone.getId() : zoneIdForOutsideOfZonalSystem; + double waitTime = entry.getValue().getPickedUp().get() .getTime() - seq.getSubmitted().getTime(); + zoneStats.get(zoneStr).addValue(waitTime); + } } } return zoneStats; diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DefaultDrtOptimizer.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DefaultDrtOptimizer.java index 0c7fd8da55e..436601c82d2 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DefaultDrtOptimizer.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DefaultDrtOptimizer.java @@ -19,14 +19,17 @@ package org.matsim.contrib.drt.optimizer; +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; + +import java.util.LinkedList; import java.util.List; +import java.util.Queue; import java.util.stream.Stream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.depot.DepotFinder; -import org.matsim.contrib.drt.optimizer.depot.Depots; import org.matsim.contrib.drt.optimizer.insertion.UnplannedRequestInserter; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy.Relocation; @@ -38,7 +41,6 @@ import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.optimizer.Request; -import org.matsim.contrib.dvrp.passenger.RequestQueue; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; @@ -61,7 +63,7 @@ public class DefaultDrtOptimizer implements DrtOptimizer { private final UnplannedRequestInserter requestInserter; private final DrtRequestInsertionRetryQueue insertionRetryQueue; - private final RequestQueue unplannedRequests; + private final Queue unplannedRequests = new LinkedList<>(); public DefaultDrtOptimizer(DrtConfigGroup drtCfg, Fleet fleet, MobsimTimer mobsimTimer, DepotFinder depotFinder, RebalancingStrategy rebalancingStrategy, DrtScheduleInquiry scheduleInquiry, ScheduleTimingUpdater scheduleTimingUpdater, @@ -78,23 +80,21 @@ public DefaultDrtOptimizer(DrtConfigGroup drtCfg, Fleet fleet, MobsimTimer mobsi this.insertionRetryQueue = insertionRetryQueue; rebalancingInterval = drtCfg.getRebalancingParams().map(rebalancingParams -> rebalancingParams.interval).orElse(null); - unplannedRequests = RequestQueue.withLimitedAdvanceRequestPlanningHorizon(drtCfg.advanceRequestPlanningHorizon); } @Override public void notifyMobsimBeforeSimStep(@SuppressWarnings("rawtypes") MobsimBeforeSimStepEvent e) { - unplannedRequests.updateQueuesOnNextTimeSteps(e.getSimulationTime()); - boolean scheduleTimingUpdated = false; - if (!unplannedRequests.getSchedulableRequests().isEmpty() || insertionRetryQueue.hasRequestsToRetryNow(e.getSimulationTime())) { + if (!unplannedRequests.isEmpty() || insertionRetryQueue.hasRequestsToRetryNow(e.getSimulationTime())) { for (DvrpVehicle v : fleet.getVehicles().values()) { scheduleTimingUpdater.updateTimings(v); } scheduleTimingUpdated = true; - requestInserter.scheduleUnplannedRequests(unplannedRequests.getSchedulableRequests()); + requestInserter.scheduleUnplannedRequests(unplannedRequests); } + relocateVehiclesToDepot(drtCfg.returnToDepotEvaluationInterval, drtCfg.returnToDepotTimeout); if (rebalancingInterval != null && e.getSimulationTime() % rebalancingInterval == 0) { if (!scheduleTimingUpdated) { for (DvrpVehicle v : fleet.getVehicles().values()) { @@ -116,7 +116,7 @@ private void rebalanceFleet() { for (Relocation r : relocations) { Link currentLink = ((DrtStayTask)r.vehicle.getSchedule().getCurrentTask()).getLink(); if (currentLink != r.link) { - relocator.relocateVehicle(r.vehicle, r.link); + relocator.relocateVehicle(r.vehicle, r.link, EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE); } } } @@ -124,21 +124,35 @@ private void rebalanceFleet() { @Override public void requestSubmitted(Request request) { - unplannedRequests.addRequest((DrtRequest)request); + unplannedRequests.add((DrtRequest)request); } @Override public void nextTask(DvrpVehicle vehicle) { scheduleTimingUpdater.updateBeforeNextTask(vehicle); - vehicle.getSchedule().nextTask(); + } - // if STOP->STAY then choose the best depot - if (drtCfg.idleVehiclesReturnToDepots && Depots.isSwitchingFromStopToStay(vehicle)) { - Link depotLink = depotFinder.findDepot(vehicle); - if (depotLink != null) { - relocator.relocateVehicle(vehicle, depotLink); - } + private void relocateVehiclesToDepot(double evaluationInterval, double timeout) { + if (drtCfg.idleVehiclesReturnToDepots && mobsimTimer.getTimeOfDay() % evaluationInterval == 0) { + fleet.getVehicles().values().stream() + .filter(scheduleInquiry::isIdle) + .filter(v -> stayTimeoutExceeded(v, timeout)) + .forEach(v -> { + Link depotLink = depotFinder.findDepot(v); + if (depotLink != null) { + relocator.relocateVehicle(v, depotLink, EmptyVehicleRelocator.RELOCATE_VEHICLE_TO_DEPOT_TASK_TYPE); + } + }); + } + } + + boolean stayTimeoutExceeded(DvrpVehicle vehicle, double timeout) { + if (STAY.isBaseTypeOf(vehicle.getSchedule().getCurrentTask())) { + double now = mobsimTimer.getTimeOfDay(); + double taskStart = vehicle.getSchedule().getCurrentTask().getBeginTime(); + return (now - taskStart) > timeout; } + return false; } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DrtModeOptimizerQSimModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DrtModeOptimizerQSimModule.java index a9bc339564f..8534468ce81 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DrtModeOptimizerQSimModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/DrtModeOptimizerQSimModule.java @@ -37,6 +37,7 @@ import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchQSimModule; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; import org.matsim.contrib.drt.passenger.DrtOfferAcceptor; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtStayTaskEndTimeCalculator; import org.matsim.contrib.drt.schedule.DrtTaskFactory; @@ -50,12 +51,13 @@ import org.matsim.contrib.drt.vrpagent.DrtActionCreator; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; -import org.matsim.contrib.dvrp.passenger.PassengerHandler; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModes; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.tracker.OnlineTrackerListener; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.framework.MobsimTimer; import org.matsim.core.modal.ModalProviders; @@ -64,6 +66,7 @@ import org.matsim.core.router.util.TravelTime; import com.google.inject.Inject; +import com.google.inject.Singleton; /** * @author Michal Maciejewski (michalm) @@ -79,11 +82,13 @@ public DrtModeOptimizerQSimModule(DrtConfigGroup drtCfg) { @Override protected void configureQSim() { addModalComponent(DrtOptimizer.class, modalProvider( - getter -> new DefaultDrtOptimizer(drtCfg, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), + getter -> { + return new DefaultDrtOptimizer(drtCfg, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), getter.getModal(DepotFinder.class), getter.getModal(RebalancingStrategy.class), getter.getModal(DrtScheduleInquiry.class), getter.getModal(ScheduleTimingUpdater.class), getter.getModal(EmptyVehicleRelocator.class), getter.getModal(UnplannedRequestInserter.class), - getter.getModal(DrtRequestInsertionRetryQueue.class)))); + getter.getModal(DrtRequestInsertionRetryQueue.class)); + })); bindModal(DepotFinder.class).toProvider( modalProvider(getter -> new NearestStartLinkAsDepot(getter.getModal(Fleet.class)))).asEagerSingleton(); @@ -100,14 +105,15 @@ protected void configureQSim() { getter.getModal(RequestInsertionScheduler.class), getter.getModal(VehicleEntry.EntryFactory.class), getter.getModal(DrtInsertionSearch.class), getter.getModal(DrtRequestInsertionRetryQueue.class), getter.getModal(DrtOfferAcceptor.class), - getter.getModal(QSimScopeForkJoinPoolHolder.class).getPool()))).asEagerSingleton(); + getter.getModal(QSimScopeForkJoinPoolHolder.class).getPool(), + getter.getModal(PassengerStopDurationProvider.class)))).asEagerSingleton(); bindModal(InsertionCostCalculator.class).toProvider(modalProvider( getter -> new DefaultInsertionCostCalculator(getter.getModal(CostCalculationStrategy.class)))); install(getInsertionSearchQSimModule(drtCfg)); - bindModal(VehicleEntry.EntryFactory.class).toInstance(new VehicleDataEntryFactoryImpl(drtCfg)); + bindModal(VehicleEntry.EntryFactory.class).toInstance(new VehicleDataEntryFactoryImpl()); bindModal(CostCalculationStrategy.class).to(drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated ? CostCalculationStrategy.RejectSoftConstraintViolations.class : @@ -132,12 +138,13 @@ public EmptyVehicleRelocator get() { }).asEagerSingleton(); bindModal(DrtScheduleInquiry.class).to(DrtScheduleInquiry.class).asEagerSingleton(); - + + boolean scheduleWaitBeforeDrive = drtCfg.getPrebookingParams().map(p -> p.scheduleWaitBeforeDrive).orElse(false); bindModal(RequestInsertionScheduler.class).toProvider(modalProvider( getter -> new DefaultRequestInsertionScheduler(getter.getModal(Fleet.class), getter.get(MobsimTimer.class), getter.getModal(TravelTime.class), getter.getModal(ScheduleTimingUpdater.class), getter.getModal(DrtTaskFactory.class), - getter.getModal(StopTimeCalculator.class)))) + getter.getModal(StopTimeCalculator.class), scheduleWaitBeforeDrive))) .asEagerSingleton(); bindModal(DrtOfferAcceptor.class).toInstance(DrtOfferAcceptor.DEFAULT_ACCEPTOR); @@ -146,9 +153,19 @@ public EmptyVehicleRelocator get() { getter -> new ScheduleTimingUpdater(getter.get(MobsimTimer.class), new DrtStayTaskEndTimeCalculator(getter.getModal(StopTimeCalculator.class))))).asEagerSingleton(); - bindModal(VrpAgentLogic.DynActionCreator.class).toProvider(modalProvider( - getter -> new DrtActionCreator(getter.getModal(PassengerHandler.class), getter.get(MobsimTimer.class), - getter.get(DvrpConfigGroup.class)))).asEagerSingleton(); + bindModal(VrpLegFactory.class).toProvider(modalProvider(getter -> { + DvrpConfigGroup dvrpCfg = getter.get(DvrpConfigGroup.class); + MobsimTimer timer = getter.get(MobsimTimer.class); + + return v -> VrpLegFactory.createWithOnlineTracker(dvrpCfg.mobsimMode, v, OnlineTrackerListener.NO_LISTENER, + timer); + })).in(Singleton.class); + + if (drtCfg.getPrebookingParams().isEmpty()) { + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(DrtActionCreator.class)); + } else { + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(PrebookingActionCreator.class)); + } bindModal(VrpOptimizer.class).to(modalKey(DrtOptimizer.class)); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImpl.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImpl.java index 98b961e2204..663b480ff74 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImpl.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImpl.java @@ -18,14 +18,13 @@ package org.matsim.contrib.drt.optimizer; +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STOP; import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.getBaseTypeOrElseThrow; import java.util.ArrayList; import java.util.List; -import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; -import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.schedule.DrtStopTask; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.schedule.DriveTask; @@ -37,31 +36,13 @@ import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; import org.matsim.contrib.dvrp.util.LinkTimePair; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; /** * @author michalm */ public class VehicleDataEntryFactoryImpl implements VehicleEntry.EntryFactory { - private final double lookAhead; - - public VehicleDataEntryFactoryImpl(DrtConfigGroup drtCfg) { - if (drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated) { - lookAhead = drtCfg.maxWaitTime - drtCfg.stopDuration; - Preconditions.checkArgument(lookAhead >= 0, - "maxWaitTime must not be smaller than stopDuration"); - } else { - // if no rejection due to max wait time, the look ahead is infinite - lookAhead = Double.POSITIVE_INFINITY; - } - } - public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { - if (isNotEligibleForRequestInsertion(vehicle, currentTime)) { - return null; - } - Schedule schedule = vehicle.getSchedule(); final LinkTimePair start; final Task startTask; @@ -89,9 +70,21 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { List tasks = schedule.getTasks(); List stopTasks = new ArrayList<>(); + + // find stop tasks and note down stay time before each task + double accumulatedStayTime = 0.0; + if (startTask != null && STAY.isBaseTypeOf(startTask)) { + accumulatedStayTime = Math.max(0.0, startTask.getEndTime() - currentTime); + } + + List precedingStayTimes = new ArrayList<>(); for (Task task : tasks.subList(nextTaskIdx, tasks.size())) { - if (STOP.isBaseTypeOf(task)) { + if (STAY.isBaseTypeOf(task)) { + accumulatedStayTime += task.getEndTime() - task.getBeginTime(); + } else if (STOP.isBaseTypeOf(task)) { stopTasks.add((DrtStopTask)task); + precedingStayTimes.add(accumulatedStayTime); + accumulatedStayTime = 0.0; } } @@ -106,17 +99,13 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { ? new Waypoint.Stop((DrtStopTask) startTask, 0) : null; - var slackTimes = computeSlackTimes(vehicle, currentTime, stops, startStop); + var slackTimes = computeSlackTimes(vehicle, currentTime, stops, startStop, precedingStayTimes); return new VehicleEntry(vehicle, new Waypoint.Start(startTask, start.link, start.time, outgoingOccupancy), - ImmutableList.copyOf(stops), slackTimes, currentTime); - } - - public boolean isNotEligibleForRequestInsertion(DvrpVehicle vehicle, double currentTime) { - return currentTime + lookAhead < vehicle.getServiceBeginTime() || currentTime >= vehicle.getServiceEndTime(); + ImmutableList.copyOf(stops), slackTimes, precedingStayTimes, currentTime); } - static double[] computeSlackTimes(DvrpVehicle vehicle, double now, Waypoint.Stop[] stops, Waypoint.Stop start) { + static double[] computeSlackTimes(DvrpVehicle vehicle, double now, Waypoint.Stop[] stops, Waypoint.Stop start, List precedingStayTimes) { double[] slackTimes = new double[stops.length + 2]; //vehicle @@ -128,6 +117,7 @@ static double[] computeSlackTimes(DvrpVehicle vehicle, double now, Waypoint.Stop var stop = stops[i]; slackTime = Math.min(stop.latestArrivalTime - stop.task.getBeginTime(), slackTime); slackTime = Math.min(stop.latestDepartureTime - stop.task.getEndTime(), slackTime); + slackTime += precedingStayTimes.get(i); // reset slack before prebooked request slackTimes[i + 1] = slackTime; } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleEntry.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleEntry.java index df2bd47957b..60f2d0f9766 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleEntry.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/VehicleEntry.java @@ -20,6 +20,8 @@ package org.matsim.contrib.drt.optimizer; +import java.util.List; + import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import com.google.common.collect.ImmutableList; @@ -36,16 +38,18 @@ public interface EntryFactory { public final Waypoint.Start start; public final ImmutableList stops; public final Waypoint.End end; - private final double[] slackTimes;// for all insertion points + private final double[] slackTimes;// for all insertion points (start, stops, end) + private final List precedingStayTimes;// for all stops public final double createTime; public VehicleEntry(DvrpVehicle vehicle, Waypoint.Start start, ImmutableList stops, - double[] slackTimes, double createTime) { + double[] slackTimes, List precedingStayTimes, double createTime) { this.vehicle = vehicle; this.start = start; this.stops = stops; this.end = Waypoint.End.OPEN_END; this.slackTimes = slackTimes; + this.precedingStayTimes = precedingStayTimes; this.createTime = createTime; } @@ -55,6 +59,7 @@ protected VehicleEntry(VehicleEntry that) { this.stops = that.stops; this.end = that.end; this.slackTimes = that.slackTimes; + this.precedingStayTimes = that.precedingStayTimes; this.createTime = that.createTime; } @@ -73,4 +78,8 @@ public double getSlackTime(int index) { public double getStartSlackTime() { return slackTimes[0]; } + + public double getPrecedingStayTime(int index) { + return precedingStayTimes.get(index); + } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/Waypoint.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/Waypoint.java index 3e99d3df631..d8540facde3 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/Waypoint.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/Waypoint.java @@ -182,7 +182,8 @@ public int getOutgoingOccupancy() { } public int getOccupancyChange() { - return task.getPickupRequests().size() - task.getDropoffRequests().size(); + return task.getPickupRequests().values().stream().mapToInt(AcceptedDrtRequest::getPassengerCount).sum() - + task.getDropoffRequests().values().stream().mapToInt(AcceptedDrtRequest::getPassengerCount).sum(); } private double calcLatestArrivalTime() { diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java index 50919dde3af..0d35c029215 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/depot/Depots.java @@ -51,19 +51,28 @@ public static boolean isSwitchingFromStopToStay(DvrpVehicle vehicle) { return false; } + // only if stay task is last task: with prebooking we may also idle during the day, but + // currently all the downstream relocation/charging logic assumes that we only stay at + // the end of the schedule + if (currentTask.getTaskIdx() < schedule.getTaskCount() - 1) { + return false; + } + // previous task was STOP int previousTaskIdx = currentTask.getTaskIdx() - 1; return (previousTaskIdx >= 0 && STOP.isBaseTypeOf(schedule.getTasks().get(previousTaskIdx))); } public static Link findStraightLineNearestDepot(DvrpVehicle vehicle, Set links) { - Link currentLink = ((DrtStayTask)vehicle.getSchedule().getCurrentTask()).getLink(); + Link currentLink = ((DrtStayTask) vehicle.getSchedule().getCurrentTask()).getLink(); return links.contains(currentLink) ? - null /* already at a depot*/ : - links.stream() - .min(Comparator.comparing( - l -> DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(), - l.getFromNode().getCoord()))) - .get(); + null /* already at a depot*/ : + links.stream().map(l -> new DepotCandidates(l, DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(), + l.getFromNode().getCoord()))) + .min(Comparator.comparing(DepotCandidates::distance) + .thenComparing(h -> h.link.getId())) + .get().link(); } + + record DepotCandidates(Link link, double distance) {} } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultInsertionCostCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultInsertionCostCalculator.java index 849d2dc02c4..1b16c140d50 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultInsertionCostCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultInsertionCostCalculator.java @@ -50,8 +50,14 @@ public DefaultInsertionCostCalculator(CostCalculationStrategy costCalculationStr public double calculate(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) { var vEntry = insertion.vehicleEntry; + // in case of prebooking, we may have intermediate stay times after pickup + // insertion that may reduce the effective pickup delay that remains that the + // dropoff insertion point + double effectiveDropoffTimeLoss = InsertionDetourTimeCalculator.calculateRemainingPickupTimeLossAtDropoff( + insertion, detourTimeInfo.pickupDetourInfo) + detourTimeInfo.dropoffDetourInfo.dropoffTimeLoss; + if (vEntry.getSlackTime(insertion.pickup.index) < detourTimeInfo.pickupDetourInfo.pickupTimeLoss - || vEntry.getSlackTime(insertion.dropoff.index) < detourTimeInfo.getTotalTimeLoss()) { + || vEntry.getSlackTime(insertion.dropoff.index) < effectiveDropoffTimeLoss) { return INFEASIBLE_SOLUTION_COST; } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserter.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserter.java index 056d5ae0d4e..0f8443f0141 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserter.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserter.java @@ -38,6 +38,7 @@ import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; @@ -64,21 +65,22 @@ public class DefaultUnplannedRequestInserter implements UnplannedRequestInserter private final DrtRequestInsertionRetryQueue insertionRetryQueue; private final DrtOfferAcceptor drtOfferAcceptor; private final ForkJoinPool forkJoinPool; + private final PassengerStopDurationProvider stopDurationProvider; public DefaultUnplannedRequestInserter(DrtConfigGroup drtCfg, Fleet fleet, MobsimTimer mobsimTimer, EventsManager eventsManager, RequestInsertionScheduler insertionScheduler, VehicleEntry.EntryFactory vehicleEntryFactory, DrtInsertionSearch insertionSearch, DrtRequestInsertionRetryQueue insertionRetryQueue, DrtOfferAcceptor drtOfferAcceptor, - ForkJoinPool forkJoinPool) { + ForkJoinPool forkJoinPool, PassengerStopDurationProvider stopDurationProvider) { this(drtCfg.getMode(), fleet, mobsimTimer::getTimeOfDay, eventsManager, insertionScheduler, vehicleEntryFactory, - insertionRetryQueue, insertionSearch, drtOfferAcceptor, forkJoinPool); + insertionRetryQueue, insertionSearch, drtOfferAcceptor, forkJoinPool, stopDurationProvider); } @VisibleForTesting DefaultUnplannedRequestInserter(String mode, Fleet fleet, DoubleSupplier timeOfDay, EventsManager eventsManager, RequestInsertionScheduler insertionScheduler, VehicleEntry.EntryFactory vehicleEntryFactory, DrtRequestInsertionRetryQueue insertionRetryQueue, DrtInsertionSearch insertionSearch, - DrtOfferAcceptor drtOfferAcceptor, ForkJoinPool forkJoinPool) { + DrtOfferAcceptor drtOfferAcceptor, ForkJoinPool forkJoinPool, PassengerStopDurationProvider stopDurationProvider) { this.mode = mode; this.fleet = fleet; this.timeOfDay = timeOfDay; @@ -89,6 +91,7 @@ public DefaultUnplannedRequestInserter(DrtConfigGroup drtCfg, Fleet fleet, Mobsi this.insertionSearch = insertionSearch; this.drtOfferAcceptor = drtOfferAcceptor; this.forkJoinPool = forkJoinPool; + this.stopDurationProvider = stopDurationProvider; } @Override @@ -124,12 +127,12 @@ private void scheduleUnplannedRequest(DrtRequest req, Map, Vehic if (best.isEmpty()) { if (!insertionRetryQueue.tryAddFailedRequest(req, now)) { eventsManager.processEvent( - new PassengerRequestRejectedEvent(now, mode, req.getId(), req.getPassengerId(), + new PassengerRequestRejectedEvent(now, mode, req.getId(), req.getPassengerIds(), NO_INSERTION_FOUND_CAUSE)); log.debug("No insertion found for drt request " + req - + " from passenger id=" - + req.getPassengerId() + + " with passenger ids=" + + req.getPassengerIds().stream().map(Object::toString).collect(Collectors.joining(",")) + " fromLinkId=" + req.getFromLink().getId()); } @@ -151,10 +154,16 @@ private void scheduleUnplannedRequest(DrtRequest req, Map, Vehic vehicleEntries.remove(vehicle.getId()); } + double expectedPickupTime = pickupDropoffTaskPair.pickupTask.getBeginTime(); + expectedPickupTime = Math.max(expectedPickupTime, acceptedRequest.get().getEarliestStartTime()); + expectedPickupTime += stopDurationProvider.calcPickupDuration(vehicle, req); + + double expectedDropoffTime = pickupDropoffTaskPair.dropoffTask.getBeginTime(); + expectedDropoffTime += stopDurationProvider.calcDropoffDuration(vehicle, req); + eventsManager.processEvent( - new PassengerRequestScheduledEvent(now, mode, req.getId(), req.getPassengerId(), vehicle.getId(), - pickupDropoffTaskPair.pickupTask.getEndTime(), - pickupDropoffTaskPair.dropoffTask.getBeginTime())); + new PassengerRequestScheduledEvent(now, mode, req.getId(), req.getPassengerIds(), vehicle.getId(), + expectedPickupTime, expectedDropoffTime)); } } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculator.java index 4e0006320cc..2de0d4dd640 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculator.java @@ -81,7 +81,8 @@ public DropoffDetourInfo calcDropoffDetourInfo(Insertion insertion, double toDro VehicleEntry vEntry = insertion.vehicleEntry; if (dropoff.newWaypoint.getLink() == dropoff.previousWaypoint.getLink()) { - double arrivalTime = dropoff.previousWaypoint.getArrivalTime() + pickupDetourInfo.pickupTimeLoss; + double remainingPickupTimeLoss = calculateRemainingPickupTimeLossAtDropoff(insertion, pickupDetourInfo); + double arrivalTime = dropoff.previousWaypoint.getArrivalTime() + remainingPickupTimeLoss; DrtStopTask stopTask = findStopTaskIfSameLinkAsPrevious(vEntry, dropoff.index); double departureTime = stopTimeCalculator.updateEndTimeForDropoff(vEntry.vehicle, stopTask, arrivalTime, drtRequest); @@ -93,7 +94,8 @@ public DropoffDetourInfo calcDropoffDetourInfo(Insertion insertion, double toDro } double toDropoffDepartureTime = dropoff.previousWaypoint.getDepartureTime(); - double arrivalTime = toDropoffDepartureTime + pickupDetourInfo.pickupTimeLoss + toDropoffTT; + double remainingPickupTimeLoss = calculateRemainingPickupTimeLossAtDropoff(insertion, pickupDetourInfo); + double arrivalTime = toDropoffDepartureTime + remainingPickupTimeLoss + toDropoffTT; double departureTime = stopTimeCalculator.initEndTimeForDropoff(vEntry.vehicle, arrivalTime, drtRequest); double stopDuration = departureTime - arrivalTime; double replacedDriveTT = calculateReplacedDriveDuration(vEntry, dropoff.index, toDropoffDepartureTime); @@ -188,7 +190,33 @@ private double calculateReplacedDriveDuration(VehicleEntry vEntry, int insertion double replacedDriveStartTime = vEntry.getWaypoint(insertionIdx).getDepartureTime(); double replacedDriveEndTime = vEntry.stops.get(insertionIdx).task.getBeginTime(); - return replacedDriveEndTime - replacedDriveStartTime; + + // reduce by the idle time before the next stop, to get the actual drive time + return replacedDriveEndTime - replacedDriveStartTime - vEntry.getPrecedingStayTime(insertionIdx); + } + + /* + * When inserting a pickup, we generate a "pickup loss" which describes by how + * much time we have to shift all following tasks to the future. + * + * In the case that some of the following stops are prebooked, however, there + * may be a stay time buffer between the insertion point and the stop. Hence, if + * a following stop only happens in four hours, we may not need to shift the + * task to the future. A preceding stay time, hence, reduces the introduced + * pickup loss. + * + * The present function calculates the remaining pickup loss at the dropoff + * insertion point after deducting all the stay times up to the dropoff. + */ + public static double calculateRemainingPickupTimeLossAtDropoff(Insertion insertion, PickupDetourInfo pickupDetourInfo) { + VehicleEntry vEntry = insertion.vehicleEntry; + double remainingPickupTimeLoss = pickupDetourInfo.pickupTimeLoss; + + for (int i = insertion.pickup.index + 1; i < insertion.dropoff.index; i++) { + remainingPickupTimeLoss = Math.max(remainingPickupTimeLoss - vEntry.getPrecedingStayTime(i), 0.0); + } + + return remainingPickupTimeLoss; } public static class PickupDetourInfo { diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGenerator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGenerator.java index 1316ccde366..60e27e4bc5a 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGenerator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGenerator.java @@ -20,6 +20,7 @@ package org.matsim.contrib.drt.optimizer.insertion; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -152,15 +153,49 @@ public InsertionGenerator(StopTimeCalculator stopTimeCalculator, DetourTimeEstim public List generateInsertions(DrtRequest drtRequest, VehicleEntry vEntry) { int stopCount = vEntry.stops.size(); List insertions = new ArrayList<>(); + + if (drtRequest.getPassengerCount() > vEntry.vehicle.getCapacity()) { + //exit early + return Collections.EMPTY_LIST; + } + int occupancy = vEntry.start.occupancy; + for (int i = 0; i < stopCount; i++) {// insertions up to before last stop Waypoint.Stop nextStop = nextStop(vEntry, i); - if (occupancy < vEntry.vehicle.getCapacity()) {// only not fully loaded arcs + // (1) only not fully loaded arcs + boolean allowed = occupancy + drtRequest.getPassengerCount() <= vEntry.vehicle.getCapacity(); + + // (2) check if the request wants to depart after the departure time of the next + // stop. We can early on filter out the current insertion, because we will + // neither be able to insert our stop before the next stop nor merge the request + // into it. + allowed &= drtRequest.getEarliestStartTime() <= nextStop.getDepartureTime(); + + if (allowed) { if (drtRequest.getFromLink() != nextStop.task.getLink()) {// next stop at different link generateDropoffInsertions(drtRequest, vEntry, i, insertions); + } else { + // this is the case where we insert a new request *before* a stop that is + // on the same link as the pickup link. Initially, the reasoning was that the + // new request will be merged *into* the existing task if all constraints hold, + // i.e. the request will be appended. So only the insertion *after* this task is + // necessary to evaluate. However, with prebooking, the situation is different: + // if the next task is prebooked (in the future), we may want to insert another + // task here on the same link (maybe a pickup followed by its dropoff) but much + // earlier. In that case it is actually a valid insertion. + + if (drtRequest.getEarliestStartTime() < nextStop.getArrivalTime()) { + // the new request wants to depart before the start of the next stop, which may + // be a viable insertion. Note that if the requested wanted to depart after the + // start of the next stop, but before its end, this is a special case that is + // covered further downstream as a special case of merging the pickup into the + // existing stop task. + + generateDropoffInsertions(drtRequest, vEntry, i, insertions); + } } - // else: do not evaluate insertion _before_stop i, evaluate only insertion _after_ stop i } occupancy = nextStop.outgoingOccupancy; @@ -177,12 +212,13 @@ private void generateDropoffInsertions(DrtRequest request, VehicleEntry vEntry, double toPickupDepartureTime = pickupInsertion.previousWaypoint.getDepartureTime(); double toPickupTT = detourTimeEstimator.estimateTime(pickupInsertion.previousWaypoint.getLink(), request.getFromLink(), toPickupDepartureTime); + double earliestPickupStartTime = Math.max(toPickupDepartureTime + toPickupTT, request.getEarliestStartTime()); double fromPickupTT = detourTimeEstimator.estimateTime(request.getFromLink(), pickupInsertion.nextWaypoint.getLink(), - toPickupDepartureTime + toPickupTT); //TODO stopDuration not included + earliestPickupStartTime); //TODO stopDuration not included var pickupDetourInfo = detourTimeCalculator.calcPickupDetourInfo(vEntry, pickupInsertion, toPickupTT, fromPickupTT, true, request); - + if (i == 0 && !checkStartSlack(vEntry, request, pickupDetourInfo)) { // Inserting at schedule start and extending an ongoing stop task further than allowed return; @@ -210,7 +246,7 @@ private void generateDropoffInsertions(DrtRequest request, VehicleEntry vEntry, //calculate it once for all j > i pickupInsertion = createPickupInsertion(request, vEntry, i, false); fromPickupTT = detourTimeEstimator.estimateTime(request.getFromLink(), pickupInsertion.nextWaypoint.getLink(), - toPickupDepartureTime + toPickupTT); //TODO stopDuration not included + earliestPickupStartTime); //TODO stopDuration not included pickupDetourInfo = detourTimeCalculator.calcPickupDetourInfo(vEntry, pickupInsertion, toPickupTT, fromPickupTT, false, request); @@ -222,7 +258,7 @@ private void generateDropoffInsertions(DrtRequest request, VehicleEntry vEntry, // i -> pickup -> i+1 && j -> dropoff -> j+1 // check the capacity constraints if i < j (already validated for `i == j`) Waypoint.Stop currentStop = currentStop(vEntry, j); - if (currentStop.outgoingOccupancy == vEntry.vehicle.getCapacity()) { + if (currentStop.outgoingOccupancy + request.getPassengerCount() > vEntry.vehicle.getCapacity()) { if (request.getToLink() == currentStop.task.getLink()) { //special case -- we can insert dropoff exactly at node j addInsertion(insertions, @@ -259,24 +295,24 @@ private Waypoint.Stop currentStop(VehicleEntry entry, int insertionIdx) { private Waypoint.Stop nextStop(VehicleEntry entry, int insertionIdx) { return entry.stops.get(insertionIdx); } - + private boolean checkStartSlack(VehicleEntry vEntry, DrtRequest request, PickupDetourInfo pickupDetourInfo) { if (vEntry.start.task.isEmpty()) { return true; } - + Task startTask = vEntry.start.task.get(); - + if (!DrtTaskBaseType.STOP.isBaseTypeOf(startTask)) { return true; } - + DrtStopTask stopTask = (DrtStopTask) startTask; - + if (stopTask.getLink() != request.getFromLink()) { return true; } - + return vEntry.getStartSlackTime() >= pickupDetourInfo.departureTime - stopTask.getEndTime(); } diff --git a/matsim/src/main/java/org/matsim/pt/counts/package-info.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/CustomRebalancingStrategyParams.java similarity index 67% rename from matsim/src/main/java/org/matsim/pt/counts/package-info.java rename to contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/CustomRebalancingStrategyParams.java index 6a25ff406fd..266229bc349 100644 --- a/matsim/src/main/java/org/matsim/pt/counts/package-info.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/CustomRebalancingStrategyParams.java @@ -1,11 +1,8 @@ - /* *********************************************************************** * * project: org.matsim.* - * package-info.java - * * * *********************************************************************** * * * - * copyright : (C) 2019 by the members listed in the COPYING, * + * copyright : (C) 2023 by the members listed in the COPYING, * * LICENSE and WARRANTY file. * * email : info at matsim dot org * * * @@ -19,7 +16,18 @@ * * * *********************************************************************** */ - /** - * This package contains classes for Count functionality of "pt". Except OccupancyAnalyzer and SimpleWriter all the other classes in this package are modified copies of classes from org.matsim.counts. - */ -package org.matsim.pt.counts; \ No newline at end of file +package org.matsim.contrib.drt.optimizer.rebalancing; + +import org.matsim.core.config.ReflectiveConfigGroup; + +/** + * Custom rebalancing strategy parameters. User is responsible for installing rebalancing module and parameters. + */ +public final class CustomRebalancingStrategyParams extends ReflectiveConfigGroup + implements RebalancingParams.RebalancingStrategyParams { + public static final String SET_NAME = "CustomRebalancingStrategy"; + + public CustomRebalancingStrategyParams() { + super(SET_NAME); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingModule.java index a263bca4e35..b9c008bc3a1 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingModule.java @@ -54,6 +54,8 @@ public void install() { install(new DrtModePlusOneRebalanceModule(drtCfg)); } else if (rebalancingParams.getRebalancingStrategyParams() instanceof FeedforwardRebalancingStrategyParams) { install(new DrtModeFeedforwardRebalanceModule(drtCfg)); + } else if (rebalancingParams.getRebalancingStrategyParams() instanceof CustomRebalancingStrategyParams) { + // User is responsible for installing custom module } else { throw new RuntimeException( "Unsupported rebalancingStrategyParams: " + rebalancingParams.getRebalancingStrategyParams()); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java index 09c826427c4..07b422912d9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/RebalancingParams.java @@ -79,6 +79,9 @@ private void initSingletonParameterSets() { addDefinition(PlusOneRebalancingStrategyParams.SET_NAME, PlusOneRebalancingStrategyParams::new, () -> (ConfigGroup)rebalancingStrategyParams, params -> rebalancingStrategyParams = (RebalancingStrategyParams)params); + addDefinition(CustomRebalancingStrategyParams.SET_NAME, CustomRebalancingStrategyParams::new, + () -> (ConfigGroup)rebalancingStrategyParams, + params -> rebalancingStrategyParams = (RebalancingStrategyParams)params); } @Override diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java index 04753cebeb3..2529a02b8d3 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/NetDepartureReplenishDemandEstimator.java @@ -43,7 +43,7 @@ public NetDepartureReplenishDemandEstimator(DrtZonalSystem zonalSystem, DrtConfi public void handleEvent(PassengerRequestRejectedEvent event) { if (event.getMode().equals(mode)) { // Ignore rejected request. - potentialDrtTripsMap.remove(event.getPersonId()); + potentialDrtTripsMap.remove(event.getRequestId()); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/AcceptedDrtRequest.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/AcceptedDrtRequest.java index 4b3e594020b..d053f6e74b9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/AcceptedDrtRequest.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/AcceptedDrtRequest.java @@ -20,12 +20,13 @@ package org.matsim.contrib.drt.passenger; +import com.google.common.base.MoreObjects; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; -import com.google.common.base.MoreObjects; +import java.util.List; /** * @author Michal Maciejewski (michalm) @@ -98,8 +99,12 @@ public Link getToLink() { return request.getToLink(); } - public Id getPassengerId() { - return request.getPassengerId(); + public List> getPassengerIds() { + return request.getPassengerIds(); + } + + public int getPassengerCount() { + return request.getPassengerCount(); } public String getMode() { diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequest.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequest.java index 64a64ee58ff..e1c034f2a92 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequest.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequest.java @@ -20,13 +20,15 @@ package org.matsim.contrib.drt.passenger; +import com.google.common.base.MoreObjects; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.passenger.PassengerRequest; -import com.google.common.base.MoreObjects; +import java.util.*; +import java.util.stream.Collectors; /** * @author michalm @@ -38,7 +40,7 @@ public class DrtRequest implements PassengerRequest { private final double latestStartTime; private final double latestArrivalTime; - private final Id passengerId; + private final List> passengerIds = new ArrayList<>(); private final String mode; private final Link fromLink; @@ -50,7 +52,7 @@ private DrtRequest(Builder builder) { earliestStartTime = builder.earliestStartTime; latestStartTime = builder.latestStartTime; latestArrivalTime = builder.latestArrivalTime; - passengerId = builder.passengerId; + passengerIds.addAll(builder.passengerIds); mode = builder.mode; fromLink = builder.fromLink; toLink = builder.toLink; @@ -67,7 +69,7 @@ public static Builder newBuilder(DrtRequest copy) { builder.earliestStartTime = copy.getEarliestStartTime(); builder.latestStartTime = copy.getLatestStartTime(); builder.latestArrivalTime = copy.getLatestArrivalTime(); - builder.passengerId = copy.getPassengerId(); + builder.passengerIds = new ArrayList<>(copy.getPassengerIds()); builder.mode = copy.getMode(); builder.fromLink = copy.getFromLink(); builder.toLink = copy.getToLink(); @@ -109,8 +111,8 @@ public Link getToLink() { } @Override - public Id getPassengerId() { - return passengerId; + public List> getPassengerIds() { + return List.copyOf(passengerIds); } @Override @@ -118,6 +120,11 @@ public String getMode() { return mode; } + @Override + public int getPassengerCount() { + return passengerIds.size(); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -126,7 +133,7 @@ public String toString() { .add("earliestStartTime", earliestStartTime) .add("latestStartTime", latestStartTime) .add("latestArrivalTime", latestArrivalTime) - .add("passengerId", passengerId) + .add("passengerIds", passengerIds.stream().map(Object::toString).collect(Collectors.joining(","))) .add("mode", mode) .add("fromLink", fromLink) .add("toLink", toLink) @@ -139,7 +146,7 @@ public static final class Builder { private double earliestStartTime; private double latestStartTime; private double latestArrivalTime; - private Id passengerId; + private List> passengerIds = new ArrayList<>(); private String mode; private Link fromLink; private Link toLink; @@ -172,8 +179,8 @@ public Builder latestArrivalTime(double val) { return this; } - public Builder passengerId(Id val) { - passengerId = val; + public Builder passengerIds(List> val) { + passengerIds = new ArrayList<>(val); return this; } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequestCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequestCreator.java index 22a1fad6ceb..8a2cff7227e 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequestCreator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtRequestCreator.java @@ -31,6 +31,8 @@ import org.matsim.contrib.dvrp.passenger.PassengerRequestCreator; import org.matsim.core.api.experimental.events.EventsManager; +import java.util.List; + /** * @author michalm */ @@ -45,19 +47,19 @@ public DrtRequestCreator(String mode, EventsManager eventsManager) { } @Override - public DrtRequest createRequest(Id id, Id passengerId, Route route, Link fromLink, Link toLink, - double departureTime, double submissionTime) { + public DrtRequest createRequest(Id id, List> passengerIds, Route route, Link fromLink, Link toLink, + double departureTime, double submissionTime) { DrtRoute drtRoute = (DrtRoute)route; double latestDepartureTime = departureTime + drtRoute.getMaxWaitTime(); double latestArrivalTime = departureTime + drtRoute.getTravelTime().seconds(); eventsManager.processEvent( - new DrtRequestSubmittedEvent(submissionTime, mode, id, passengerId, fromLink.getId(), toLink.getId(), - drtRoute.getDirectRideTime(), drtRoute.getDistance(), latestDepartureTime, latestArrivalTime)); + new DrtRequestSubmittedEvent(submissionTime, mode, id, passengerIds, fromLink.getId(), toLink.getId(), + drtRoute.getDirectRideTime(), drtRoute.getDistance(), departureTime, latestDepartureTime, latestArrivalTime)); DrtRequest request = DrtRequest.newBuilder() .id(id) - .passengerId(passengerId) + .passengerIds(passengerIds) .mode(mode) .fromLink(fromLink) .toLink(toLink) diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtStopActivity.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtStopActivity.java index e646c761df1..0f1e36e5706 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtStopActivity.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/DrtStopActivity.java @@ -20,15 +20,17 @@ package org.matsim.contrib.drt.passenger; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Supplier; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.passenger.PassengerHandler; import org.matsim.contrib.dvrp.passenger.PassengerPickupActivity; -import org.matsim.contrib.dvrp.schedule.StayTask; import org.matsim.contrib.dynagent.DynAgent; import org.matsim.contrib.dynagent.FirstLastSimStepDynActivity; import org.matsim.core.mobsim.framework.MobsimPassengerAgent; @@ -67,7 +69,7 @@ protected boolean isLastStep(double now) { protected void beforeFirstStep(double now) { // TODO probably we should simulate it more accurately (passenger by passenger, not all at once...) for (var request : dropoffRequests.values()) { - passengerHandler.dropOffPassenger(driver, request.getId(), now); + passengerHandler.dropOffPassengers(driver, request.getId(), now); } } @@ -75,7 +77,7 @@ protected void beforeFirstStep(double now) { protected void simStep(double now) { if (now == endTime.get()) { for (var request : pickupRequests.values()) { - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { passengersPickedUp++; } } @@ -83,23 +85,23 @@ protected void simStep(double now) { } @Override - public void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, double now) { + public void notifyPassengersAreReadyForDeparture(List passengers, double now) { if (now < endTime.get()) { return;// pick up only at the end of stop activity } - var request = getRequestForPassenger(passenger.getId()); - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { + var request = getRequestForPassengers(passengers.stream().map(Identifiable::getId).toList()); + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { passengersPickedUp++; } else { throw new IllegalStateException("The passenger is not on the link or not available for departure!"); } } - private AcceptedDrtRequest getRequestForPassenger(Id passengerId) { + private AcceptedDrtRequest getRequestForPassengers(List> passengerIds) { return pickupRequests.values() .stream() - .filter(r -> passengerId.equals(r.getPassengerId())) + .filter(r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) .findAny() .orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/events/DrtRequestSubmittedEvent.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/events/DrtRequestSubmittedEvent.java index fe7d745c436..09f04e814d9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/events/DrtRequestSubmittedEvent.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/passenger/events/DrtRequestSubmittedEvent.java @@ -19,9 +19,6 @@ package org.matsim.contrib.drt.passenger.events; -import java.util.Map; -import java.util.Objects; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.GenericEvent; import org.matsim.api.core.v01.network.Link; @@ -29,6 +26,8 @@ import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import java.util.*; + /** * @author michalm */ @@ -38,21 +37,24 @@ public class DrtRequestSubmittedEvent extends PassengerRequestSubmittedEvent { public static final String ATTRIBUTE_UNSHARED_RIDE_TIME = "unsharedRideTime"; public static final String ATTRIBUTE_UNSHARED_RIDE_DISTANCE = "unsharedRideDistance"; + public static final String ATTRIBUTE_EARLIEST_DEPARTURE_TIME = "earliestDepartureTime"; public static final String ATTRIBUTE_LATEST_PICKUP_TIME = "latestPickupTime"; public static final String ATTRIBUTE_LATEST_DROPOFF_TIME = "latestDropoffTime"; private final double unsharedRideTime; private final double unsharedRideDistance; + private final double earliestDepartureTime; private final double latestPickupTime; private final double latestDropoffTime; - public DrtRequestSubmittedEvent(double time, String mode, Id requestId, Id personId, + public DrtRequestSubmittedEvent(double time, String mode, Id requestId, List> personIds, Id fromLinkId, Id toLinkId, double unsharedRideTime, double unsharedRideDistance, - double latestPickupTime, double latestDropoffTime) { - super(time, mode, requestId, personId, fromLinkId, toLinkId); + double earliestDepartureTime, double latestPickupTime, double latestDropoffTime) { + super(time, mode, requestId, personIds, fromLinkId, toLinkId); this.unsharedRideTime = unsharedRideTime; this.unsharedRideDistance = unsharedRideDistance; + this.earliestDepartureTime = earliestDepartureTime; this.latestPickupTime = latestPickupTime; this.latestDropoffTime = latestDropoffTime; } @@ -76,6 +78,10 @@ public final double getUnsharedRideDistance() { return unsharedRideDistance; } + public final double getEarliestDepartureTime() { + return earliestDepartureTime; + } + public final double getLatestPickupTime() { return latestPickupTime; } @@ -89,6 +95,7 @@ public Map getAttributes() { Map attr = super.getAttributes(); attr.put(ATTRIBUTE_UNSHARED_RIDE_TIME, unsharedRideTime + ""); attr.put(ATTRIBUTE_UNSHARED_RIDE_DISTANCE, unsharedRideDistance + ""); + attr.put(ATTRIBUTE_EARLIEST_DEPARTURE_TIME, earliestDepartureTime + ""); attr.put(ATTRIBUTE_LATEST_PICKUP_TIME, latestPickupTime + ""); attr.put(ATTRIBUTE_LATEST_DROPOFF_TIME, latestDropoffTime + ""); return attr; @@ -99,14 +106,19 @@ public static DrtRequestSubmittedEvent convert(GenericEvent event) { double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); - Id personId = Id.createPersonId(attributes.get(ATTRIBUTE_PERSON)); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = new ArrayList<>(); + for (String person : personIdsAttribute) { + personIds.add(Id.create(person, Person.class)); + } Id fromLinkId = Id.createLinkId(attributes.get(ATTRIBUTE_FROM_LINK)); Id toLinkId = Id.createLinkId(attributes.get(ATTRIBUTE_TO_LINK)); double unsharedRideTime = Double.parseDouble(attributes.get(ATTRIBUTE_UNSHARED_RIDE_TIME)); double unsharedRideDistance = Double.parseDouble(attributes.get(ATTRIBUTE_UNSHARED_RIDE_DISTANCE)); + double earliestDepartureTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_EARLIEST_DEPARTURE_TIME, "NaN")); double latestPickupTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_LATEST_PICKUP_TIME, "NaN")); double latestDropoffTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_LATEST_DROPOFF_TIME, "NaN")); - return new DrtRequestSubmittedEvent(time, mode, requestId, personId, fromLinkId, toLinkId, unsharedRideTime, - unsharedRideDistance, latestPickupTime, latestDropoffTime); + return new DrtRequestSubmittedEvent(time, mode, requestId, personIds, fromLinkId, toLinkId, unsharedRideTime, + unsharedRideDistance, earliestDepartureTime, latestPickupTime, latestDropoffTime); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEvent.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEvent.java new file mode 100644 index 00000000000..7d14a3650e6 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEvent.java @@ -0,0 +1,35 @@ +package org.matsim.contrib.drt.prebooking; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.GenericEvent; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.AbstractPassengerRequestEvent; + +import java.util.*; + +/** + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PassengerRequestBookedEvent extends AbstractPassengerRequestEvent { + public static final String EVENT_TYPE = "PassengerRequest booked"; + + public PassengerRequestBookedEvent(double time, String mode, Id requestId, List> personIds) { + super(time, mode, requestId, personIds); + } + + @Override + public String getEventType() { + return EVENT_TYPE; + } + + public static PassengerRequestBookedEvent convert(GenericEvent event) { + Map attributes = event.getAttributes(); + double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); + String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); + Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = Arrays.stream(personIdsAttribute).map(Id::createPersonId).toList(); + return new PassengerRequestBookedEvent(time, mode, requestId, personIds); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEventHandler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEventHandler.java new file mode 100644 index 00000000000..19a47c3fb9c --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PassengerRequestBookedEventHandler.java @@ -0,0 +1,10 @@ +package org.matsim.contrib.drt.prebooking; + +import org.matsim.core.events.handler.EventHandler; + +/** + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public interface PassengerRequestBookedEventHandler extends EventHandler { + void handleEvent(final PassengerRequestBookedEvent event); +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingActionCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingActionCreator.java new file mode 100644 index 00000000000..aa29bc7253f --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingActionCreator.java @@ -0,0 +1,57 @@ +package org.matsim.contrib.drt.prebooking; + +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.getBaseTypeOrElseThrow; + +import org.matsim.contrib.drt.prebooking.abandon.AbandonVoter; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.drt.schedule.DrtTaskBaseType; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.passenger.PassengerHandler; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dynagent.DynAction; +import org.matsim.contrib.dynagent.DynAgent; + +/** + * For prebooking, we implement an alternative DynActivity that handles entering + * / exiting passengers more flexibly than the standard DrtStopActivity. + * + * Specifically, we track when a person is ready for departure and then add the + * expected duration of the interaction into a queue. The agent only actually + * enters the vehicle after this time has elapsed. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PrebookingActionCreator implements VrpAgentLogic.DynActionCreator { + private final VrpAgentLogic.DynActionCreator delegate; + private final PassengerHandler passengerHandler; + private final PassengerStopDurationProvider stopDurationProvider; + private final PrebookingManager prebookingManager; + private final AbandonVoter abandonVoter; + + public PrebookingActionCreator(PassengerHandler passengerHandler, VrpAgentLogic.DynActionCreator delegate, + PassengerStopDurationProvider stopDurationProvider, PrebookingManager prebookingManager, + AbandonVoter abandonVoter) { + this.delegate = delegate; + this.passengerHandler = passengerHandler; + this.stopDurationProvider = stopDurationProvider; + this.prebookingManager = prebookingManager; + this.abandonVoter = abandonVoter; + } + + @Override + public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now) { + Task task = vehicle.getSchedule().getCurrentTask(); + + if (getBaseTypeOrElseThrow(task).equals(DrtTaskBaseType.STOP)) { + DrtStopTask stopTask = (DrtStopTask) task; + return new PrebookingStopActivity(passengerHandler, dynAgent, stopTask, stopTask.getDropoffRequests(), + stopTask.getPickupRequests(), DrtActionCreator.DRT_STOP_NAME, () -> stopTask.getEndTime(), + stopDurationProvider, vehicle, prebookingManager, abandonVoter); + } + + return delegate.createAction(dynAgent, vehicle, now); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java new file mode 100644 index 00000000000..ed79cd0bf9f --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java @@ -0,0 +1,458 @@ +package org.matsim.contrib.drt.prebooking; + +import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.IdSet; +import org.matsim.api.core.v01.events.PersonStuckEvent; +import org.matsim.api.core.v01.events.handler.PersonStuckEventHandler; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.prebooking.unscheduler.RequestUnscheduler; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; +import org.matsim.contrib.dvrp.passenger.*; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.mobsim.framework.MobsimAgent; +import org.matsim.core.mobsim.framework.MobsimAgent.State; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.mobsim.framework.events.MobsimAfterSimStepEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimAfterSimStepListener; +import org.matsim.core.mobsim.qsim.InternalInterface; +import org.matsim.core.mobsim.qsim.agents.WithinDayAgentUtils; +import org.matsim.core.mobsim.qsim.interfaces.MobsimEngine; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * This class manages prebooked requests. One instance of PrebookingManager + * exists per mode. The entry point is PrebookingManager::prebook to which you + * need to pass a person, a leg with the respective DRT mode, the + * requested/expected earliest departure time, and the time at which the request + * should be submitted / taken into account in the system. + * + * Preplanned requests can be submitted any time before the planned + * departure/submission times. + * + * Internally, the prebooking manager will create a request identifier and + * return the request once the agent actually wants to depart on the planned + * leg. The link between a leg and a request is managed by inserting a special + * attribute in the leg instance. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PrebookingManager implements MobsimEngine, MobsimAfterSimStepListener, AdvanceRequestProvider, + PassengerRequestScheduledEventHandler, PassengerRequestRejectedEventHandler, PersonStuckEventHandler { + private final String mode; + + private final Network network; + private final EventsManager eventsManager; + + private final VrpOptimizer optimizer; + private final RequestUnscheduler unscheduler; + + private final MobsimTimer mobsimTimer; + + public PrebookingManager(String mode, Network network, PassengerRequestCreator requestCreator, + VrpOptimizer optimizer, MobsimTimer mobsimTimer, PassengerRequestValidator requestValidator, + EventsManager eventsManager, RequestUnscheduler unscheduler) { + this.network = network; + this.mode = mode; + this.requestCreator = requestCreator; + this.optimizer = optimizer; + this.requestAttribute = PREBOOKED_REQUEST_PREFIX + ":" + mode; + this.requestValidator = requestValidator; + this.mobsimTimer = mobsimTimer; + this.eventsManager = eventsManager; + this.unscheduler = unscheduler; + } + + // Functionality for ID management + + private static final String PREBOOKED_REQUEST_PREFIX = "prebookedRequestId"; + private final AtomicInteger currentRequestIndex = new AtomicInteger(-1); + private final String requestAttribute; + + private Id createRequestId() { + return Id.create(mode + "_prebooked_" + currentRequestIndex.incrementAndGet(), Request.class); + } + + public boolean isPrebookedRequest(Id requestId) { + return requestId.toString().startsWith(mode + "_prebooked_"); + } + + public Id getRequestId(Leg leg) { + String rawRequestId = (String) leg.getAttributes().getAttribute(requestAttribute); + + if (rawRequestId == null) { + return null; + } + + return Id.create(rawRequestId, Request.class); + } + + // Event handling: We track events in parallel and process them later in + // notifyMobsimAfterSimStep + + private final ConcurrentLinkedQueue scheduledEvents = new ConcurrentLinkedQueue<>(); + private final ConcurrentLinkedQueue> rejectedEventIds = new ConcurrentLinkedQueue<>(); + private final ConcurrentLinkedQueue> stuckPersonsIds = new ConcurrentLinkedQueue<>(); + + @Override + public void handleEvent(PassengerRequestScheduledEvent event) { + scheduledEvents.add(event); + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + rejectedEventIds.add(event.getRequestId()); + } + + @Override + public void handleEvent(PersonStuckEvent event) { + stuckPersonsIds.add(event.getPersonId()); + } + + // Event handling: We don't want to process events in notifyMobsimAfterSimStep, + // so we do it at the next time step + private record RejectionItem(Id requestId, List> personIds, String cause) { + } + + public record PersonLeg(MobsimAgent agent, Leg leg){} + + private final ConcurrentLinkedQueue rejections = new ConcurrentLinkedQueue<>(); + + private void processRejection(PassengerRequest request, String cause) { + rejections.add(new RejectionItem(request.getId(), request.getPassengerIds(), cause)); + } + + private void flushRejections(double now) { + for (RejectionItem item : rejections) { + eventsManager.processEvent( + new PassengerRequestRejectedEvent(now, mode, item.requestId, item.personIds, item.cause)); + } + + rejections.clear(); + } + + // Booking functionality + + private final PassengerRequestCreator requestCreator; + private final PassengerRequestValidator requestValidator; + + // collects new bookings that need to be submitted + private final ConcurrentLinkedQueue bookingQueue = new ConcurrentLinkedQueue<>(); + + public void prebook(MobsimAgent agent, Leg leg, double earliestDepartureTime) { + prebook(List.of(new PersonLeg(agent, leg)), earliestDepartureTime); + } + + public void prebook(List personsLegs, double earliestDepartureTime) { + for (PersonLeg personLeg : personsLegs) { + Preconditions.checkArgument(personLeg.leg().getMode().equals(mode), "Invalid mode for this prebooking manager"); + Preconditions.checkState(!personLeg.agent().getState().equals(State.ABORT), "Cannot prebook aborted agent"); + } + + Id requestId = createRequestId(); + double now = mobsimTimer.getTimeOfDay(); + + List> personIds = personsLegs.stream().map(p -> p.agent().getId()).toList(); + eventsManager.processEvent(new PassengerRequestBookedEvent(now, mode, requestId, personIds)); + + Leg representativeLeg = personsLegs.get(0).leg(); + PassengerRequest request = requestCreator.createRequest(requestId, personIds, representativeLeg.getRoute(), + getLink(representativeLeg.getRoute().getStartLinkId()), getLink(representativeLeg.getRoute().getEndLinkId()), earliestDepartureTime, + now); + + Set violations = requestValidator.validateRequest(request); + + for (PersonLeg personLeg : personsLegs) { + Plan plan = WithinDayAgentUtils.getModifiablePlan(personLeg.agent()); + int currentLegIndex = WithinDayAgentUtils.getCurrentPlanElementIndex(personLeg.agent()); + int prebookingLegIndex = plan.getPlanElements().indexOf(personLeg.leg()); + + if (prebookingLegIndex <= currentLegIndex) { + violations = new HashSet<>(violations); + violations.add("past leg"); // the leg for which the booking was made has already happened + } + } + + if (!violations.isEmpty()) { + String cause = String.join(", ", violations); + processRejection(request, cause); + } else { + for (PersonLeg personLeg : personsLegs) { + personLeg.leg().getAttributes().putAttribute(requestAttribute, request.getId().toString()); + } + bookingQueue.add(request); + } + } + + private void processBookingQueue(double now) { + for (PassengerRequest request : bookingQueue) { + + synchronized (optimizer) { // needed? + optimizer.requestSubmitted(request); + } + + requests.put(request.getId(), new RequestItem(request)); + } + + bookingQueue.clear(); + } + + private Link getLink(Id linkId) { + return Preconditions.checkNotNull(network.getLinks().get(linkId), + "Link id=%s does not exist in network for mode %s. Agent departs from a link that does not belong to that network?", + linkId, mode); + } + + // Interface with PassengerEngine + + @Override + @Nullable + public PassengerRequest retrieveRequest(MobsimAgent agent, Leg leg) { + Preconditions.checkArgument(leg.getMode().equals(mode), "Invalid mode for this prebooking manager"); + + Id requestId = getRequestId(leg); + + if (requestId == null) { + return null; + } + + RequestItem item = requests.get(requestId); + + if (item == null) { + return null; + } + + return item.request; + } + + // Housekeeping of requests + + private IdMap requests = new IdMap<>(Request.class); + + private class RequestItem { + final PassengerRequest request; + + Id vehicleId = null; + boolean onboard = false; + + RequestItem(PassengerRequest request) { + this.request = request; + } + } + + void notifyPickup(double now, AcceptedDrtRequest request) { + RequestItem item = requests.get(request.getId()); + + if (item != null) { + // may be null, we treat all (also non-prebooked) requests here + item.onboard = true; + } + } + + void notifyDropoff(Id requestId) { + requests.remove(requestId); + } + + private IdSet unscheduleUponVehicleAssignment = new IdSet<>(Request.class); + + private void processScheduledRequests(double now) { + for (PassengerRequestScheduledEvent event : scheduledEvents) { + RequestItem item = requests.get(event.getRequestId()); + + if (item != null) { + item.vehicleId = event.getVehicleId(); + } + + if (unscheduleUponVehicleAssignment.contains(event.getRequestId())) { + // this is the case if a request has been rejected / canceled after submission + // but before scheduling + unscheduler.unscheduleRequest(now, event.getVehicleId(), event.getRequestId()); + unscheduleUponVehicleAssignment.remove(event.getRequestId()); + } + } + + scheduledEvents.clear(); + } + + // Functionality for canceling requests + + private static final String CANCEL_REASON = "canceled"; + private final List cancelQueue = new LinkedList<>(); + + private void processCanceledRequests(double now) { + for (CancelItem cancelItem : cancelQueue) { + Id requestId = cancelItem.requestId; + RequestItem item = requests.remove(requestId); + + if (item != null) { // might be null if abandoned before canceling + Verify.verify(!item.onboard, "cannot cancel onboard request"); + + // unschedule if requests is scheduled already + if (item.vehicleId != null) { + unscheduler.unscheduleRequest(now, item.vehicleId, requestId); + } else { + unscheduleUponVehicleAssignment.add(requestId); + } + + String reason = CANCEL_REASON; + + if (cancelItem.reason != null) { + reason = CANCEL_REASON + ":" + cancelItem.reason; + } + + processRejection(item.request, reason); + } + } + + cancelQueue.clear(); + } + + public void cancel(Leg leg) { + cancel(leg, null); + } + + public void cancel(Leg leg, String reason) { + Id requestId = getRequestId(leg); + + if (requestId != null) { + cancel(requestId, reason); + } + } + + public void cancel(Id requestId, String reason) { + cancelQueue.add(new CancelItem(requestId, reason)); + } + + public void cancel(Id requestId) { + cancel(requestId, null); + } + + private record CancelItem(Id requestId, String reason) { + } + + // Functionality for abandoning requests + + private static final String ABANDONED_REASON = "abandoned by vehicle"; + private final ConcurrentLinkedQueue> abandonQueue = new ConcurrentLinkedQueue<>(); + + void abandon(Id requestId) { + abandonQueue.add(requestId); + } + + private void processAbandonedRequests(double now) { + for (Id requestId : abandonQueue) { + RequestItem item = Objects.requireNonNull(requests.remove(requestId)); + Verify.verify(!item.onboard, "cannot abandon request that is already onboard"); + + // remove request from scheduled if already scheduled + if (item.vehicleId != null) { + unscheduler.unscheduleRequest(now, item.vehicleId, item.request.getId()); + } else { + unscheduleUponVehicleAssignment.add(item.request.getId()); + } + + processRejection(item.request, ABANDONED_REASON); + } + + abandonQueue.clear(); + } + + // Rejections + + private void processRejections(double now) { + for (Id requestId : rejectedEventIds) { + RequestItem item = requests.remove(requestId); + + if (item != null) { + // should this fail gracefully? + Verify.verify(!item.onboard, "cannot reject onboard request"); + + // unschedule if already scheduled + if (item.vehicleId != null) { + unscheduler.unscheduleRequest(now, item.vehicleId, requestId); + } else { + unscheduleUponVehicleAssignment.add(requestId); + } + } + } + + rejectedEventIds.clear(); + } + + // Stuck + + private void processStuckAgents(double now) { + bookingQueue.removeIf(request -> stuckPersonsIds.containsAll(request.getPassengerIds())); + + for (RequestItem item : requests.values()) { + if (stuckPersonsIds.containsAll(item.request.getPassengerIds())) { + cancel(item.request.getId()); + } + } + + stuckPersonsIds.clear(); + } + + // Engine code + + @Override + public void onPrepareSim() { + eventsManager.addHandler(this); + } + + @Override + public void doSimStep(double now) { + // avoid method as it runs in parallel with events, only process rejections + flushRejections(now); + } + + @Override + public void notifyMobsimAfterSimStep(@SuppressWarnings("rawtypes") MobsimAfterSimStepEvent e) { + // here we are back in the main thread and all events + // have been processed + + double now = mobsimTimer.getTimeOfDay(); + + // first process scheduled events (this happened, we cannot change it) + processScheduledRequests(now); + + // process rejected requests, potential problem if a person has entered the + // vehicle in just this simstep, but also a rejection has been sent + processRejections(now); + + // process stuck agents, they are added to the cancel queue + processStuckAgents(now); + + // process abandoned requests (by vehicle), here we are sure that the person + // cannot have entered in this iteration + processAbandonedRequests(now); + + // process cancel requests, same situation as for rejections + processCanceledRequests(now); + + // submit requests + processBookingQueue(now); + } + + @Override + public void afterSim() { + eventsManager.removeHandler(this); + } + + @Override + public void setInternalInterface(InternalInterface internalInterface) { + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingModeQSimModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingModeQSimModule.java new file mode 100644 index 00000000000..badbb8624f5 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingModeQSimModule.java @@ -0,0 +1,106 @@ +package org.matsim.contrib.drt.prebooking; + +import com.google.inject.Singleton; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.prebooking.abandon.AbandonVoter; +import org.matsim.contrib.drt.prebooking.abandon.MaximumDelayAbandonVoter; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator.PopulationIteratorFactory; +import org.matsim.contrib.drt.prebooking.logic.helpers.PrebookingQueue; +import org.matsim.contrib.drt.prebooking.unscheduler.ComplexRequestUnscheduler; +import org.matsim.contrib.drt.prebooking.unscheduler.RequestUnscheduler; +import org.matsim.contrib.drt.prebooking.unscheduler.SimpleRequestUnscheduler; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleLookup; +import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; +import org.matsim.contrib.dvrp.passenger.*; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.TravelTime; + +public class PrebookingModeQSimModule extends AbstractDvrpModeQSimModule { + private final PrebookingParams prebookingParams; + + public PrebookingModeQSimModule(String mode, PrebookingParams prebookingParams) { + super(mode); + this.prebookingParams = prebookingParams; + } + + @Override + protected void configureQSim() { + bindModal(PrebookingActionCreator.class).toProvider(modalProvider(getter -> { + PassengerHandler passengerHandler = (PassengerEngine) getter.getModal(PassengerHandler.class); + DrtActionCreator delegate = getter.getModal(DrtActionCreator.class); + PassengerStopDurationProvider stopDurationProvider = getter.getModal(PassengerStopDurationProvider.class); + PrebookingManager prebookingManager = getter.getModal(PrebookingManager.class); + AbandonVoter abandonVoter = getter.getModal(AbandonVoter.class); + + return new PrebookingActionCreator(passengerHandler, delegate, stopDurationProvider, prebookingManager, + abandonVoter); + })).in(Singleton.class); + + bindModal(PrebookingManager.class).toProvider(modalProvider(getter -> { + Network network = getter.getModal(Network.class); + PassengerRequestCreator requestCreator = getter.getModal(PassengerRequestCreator.class); + VrpOptimizer optimizer = getter.getModal(VrpOptimizer.class); + PassengerRequestValidator requestValidator = getter.getModal(PassengerRequestValidator.class); + EventsManager eventsManager = getter.get(EventsManager.class); + RequestUnscheduler requestUnscheduler = getter.getModal(RequestUnscheduler.class); + MobsimTimer mobsimTimer = getter.get(MobsimTimer.class); + + return new PrebookingManager(getMode(), network, requestCreator, optimizer, mobsimTimer, requestValidator, + eventsManager, requestUnscheduler); + })).in(Singleton.class); + addModalQSimComponentBinding().to(modalKey(PrebookingManager.class)); + + bindModal(PrebookingQueue.class).toProvider(modalProvider(getter -> { + return new PrebookingQueue(getter.getModal(PrebookingManager.class), getter.getModal(PassengerGroupIdentifier.class)); + })).in(Singleton.class); + addModalQSimComponentBinding().to(modalKey(PrebookingQueue.class)); + + bindModal(PopulationIteratorFactory.class).toProvider(modalProvider(getter -> { + return new PopulationIteratorFactory(getter.get(Population.class), getter.get(QSim.class)); + })); + + bindModal(MaximumDelayAbandonVoter.class).toProvider(modalProvider(getter -> { + double maximumDelay = prebookingParams.maximumPassengerDelay; + return new MaximumDelayAbandonVoter(maximumDelay); + })).in(Singleton.class); + bindModal(AbandonVoter.class).to(modalKey(MaximumDelayAbandonVoter.class)); + + bindModal(SimpleRequestUnscheduler.class).toProvider(modalProvider(getter -> { + DvrpVehicleLookup vehicleLookup = getter.get(DvrpVehicleLookup.class); + return new SimpleRequestUnscheduler(vehicleLookup); + })).in(Singleton.class); + + bindModal(ComplexRequestUnscheduler.class).toProvider(modalProvider(getter -> { + DvrpVehicleLookup vehicleLookup = getter.get(DvrpVehicleLookup.class); + VehicleEntry.EntryFactory entryFactory = getter.getModal(VehicleEntry.EntryFactory.class); + DrtTaskFactory taskFactory = getter.getModal(DrtTaskFactory.class); + LeastCostPathCalculator router = getter.getModal(LeastCostPathCalculator.class); + TravelTime travelTime = getter.getModal(TravelTime.class); + ScheduleTimingUpdater timingUpdater = getter.getModal(ScheduleTimingUpdater.class); + + return new ComplexRequestUnscheduler(vehicleLookup, entryFactory, taskFactory, router, travelTime, + timingUpdater, prebookingParams.scheduleWaitBeforeDrive); + })).in(Singleton.class); + + switch (prebookingParams.unschedulingMode) { + case StopBased: + bindModal(RequestUnscheduler.class).to(modalKey(SimpleRequestUnscheduler.class)); + break; + case Routing: + bindModal(RequestUnscheduler.class).to(modalKey(ComplexRequestUnscheduler.class)); + break; + default: + throw new IllegalStateException("No binding for selected RequestUnscheduler"); + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingParams.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingParams.java new file mode 100644 index 00000000000..fdf678bb272 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingParams.java @@ -0,0 +1,41 @@ +package org.matsim.contrib.drt.prebooking; + +import org.matsim.core.config.ReflectiveConfigGroup; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; + +public class PrebookingParams extends ReflectiveConfigGroup { + public static final String SET_NAME = "prebooking"; + + public PrebookingParams() { + super(SET_NAME); + } + + @Parameter + @Comment("Defines whether vehicles drive immediately to the next" + + " (prebooked) future task and wait for the planned stop to begin, or wait at the current" + + " position and depart to arrive on time at the following stop. The latter behavior (not" + + " the default) may lead to larger ucnertainty in highly congested scenarios.") + public boolean scheduleWaitBeforeDrive = false; // in the future, this could also become a double value indicating + // how many minutes before the next stop the vehicle should plan to + // be there + + @Parameter + @Comment("Request gets rejected if a vehicle waits longer than the indicated duration at the stop") + @NotNull + @Positive + public double maximumPassengerDelay = Double.POSITIVE_INFINITY; + + public enum UnschedulingMode { + StopBased, Routing + } + + @Parameter + @Comment("When unscheduling requests because they have been canceled," + + " we either simply remove the requests from the planned stops" + + " along the vehicle's schedule or we adaptively reconfigure and reroute the vehicle's schedule.") + @NotNull + public UnschedulingMode unschedulingMode = UnschedulingMode.StopBased; + +} \ No newline at end of file diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java new file mode 100644 index 00000000000..3fef9b0c932 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java @@ -0,0 +1,165 @@ +package org.matsim.contrib.drt.prebooking; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.Identifiable; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.prebooking.abandon.AbandonVoter; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerHandler; +import org.matsim.contrib.dvrp.passenger.PassengerPickupActivity; +import org.matsim.contrib.dvrp.schedule.StayTask; +import org.matsim.contrib.dynagent.DynAgent; +import org.matsim.contrib.dynagent.FirstLastSimStepDynActivity; +import org.matsim.core.mobsim.framework.MobsimPassengerAgent; + +import com.google.common.base.Verify; + +/** + * Modified version of DrtStopActivity which handles parallel mounting and + * alighting of passengers according to individual pickup and dropoff times. + * + * @author Sebastian Hörl, IRT SystemX (sebhoerl) + */ +public class PrebookingStopActivity extends FirstLastSimStepDynActivity implements PassengerPickupActivity { + private final DynAgent driver; + private final DvrpVehicle vehicle; + + private final Map, ? extends AcceptedDrtRequest> pickupRequests; + private final Map, ? extends AcceptedDrtRequest> dropoffRequests; + + private final IdMap enterTimes = new IdMap<>(Request.class); + private final IdMap leaveTimes = new IdMap<>(Request.class); + private final Set> enteredRequests = new HashSet<>(); + + private final PrebookingManager prebookingManager; + private final PassengerHandler passengerHandler; + + private final PassengerStopDurationProvider stopDurationProvider; + private final AbandonVoter abandonVoter; + + private final Supplier endTime; + + public PrebookingStopActivity(PassengerHandler passengerHandler, DynAgent driver, StayTask task, + Map, ? extends AcceptedDrtRequest> dropoffRequests, + Map, ? extends AcceptedDrtRequest> pickupRequests, String activityType, + Supplier endTime, PassengerStopDurationProvider stopDurationProvider, DvrpVehicle vehicle, + PrebookingManager prebookingManager, AbandonVoter abandonVoter) { + super(activityType); + this.passengerHandler = passengerHandler; + this.driver = driver; + this.dropoffRequests = dropoffRequests; + this.pickupRequests = pickupRequests; + this.stopDurationProvider = stopDurationProvider; + this.vehicle = vehicle; + this.prebookingManager = prebookingManager; + this.abandonVoter = abandonVoter; + this.endTime = endTime; + } + + @Override + protected boolean isLastStep(double now) { + return updatePickupRequests(now) && leaveTimes.size() == 0 && now >= endTime.get(); + } + + @Override + protected void beforeFirstStep(double now) { + initDropoffRequests(now); + updatePickupRequests(now); + } + + private void initDropoffRequests(double now) { + for (var request : dropoffRequests.values()) { + double leaveTime = now + stopDurationProvider.calcDropoffDuration(vehicle, request.getRequest()); + leaveTimes.put(request.getId(), leaveTime); + } + + processDropoffRequests(now); + } + + private void processDropoffRequests(double now) { + var iterator = leaveTimes.entrySet().iterator(); + + while (iterator.hasNext()) { + var entry = iterator.next(); + + if (entry.getValue() <= now) { // Request should leave now + passengerHandler.dropOffPassengers(driver, entry.getKey(), now); + prebookingManager.notifyDropoff(entry.getKey()); + iterator.remove(); + } + } + } + + private boolean updatePickupRequests(double now) { + var pickupIterator = pickupRequests.values().iterator(); + + while (pickupIterator.hasNext()) { + var request = pickupIterator.next(); + + if (!enteredRequests.contains(request.getId()) && !enterTimes.containsKey(request.getId())) { + // this is a new request that has been added after the activity has been created + // or that had not arrived yet + + if (passengerHandler.notifyWaitForPassengers(this, this.driver, request.getId())) { + // agent starts to enter + queuePickup(request, now); + } else if (now > request.getEarliestStartTime()) { + if (abandonVoter.abandonRequest(now, vehicle, request)) { + prebookingManager.abandon(request.getId()); + } + } + } + } + + var enterIterator = enterTimes.entrySet().iterator(); + + while (enterIterator.hasNext()) { + var entry = enterIterator.next(); + + if (entry.getValue() <= now) { + // let agent enter now + Verify.verify(passengerHandler.tryPickUpPassengers(this, driver, entry.getKey(), now)); + enteredRequests.add(entry.getKey()); + enterIterator.remove(); + } + } + + return enterTimes.size() == 0 && pickupRequests.size() == enteredRequests.size(); + } + + private void queuePickup(AcceptedDrtRequest request, double now) { + prebookingManager.notifyPickup(now, request); + double enterTime = now + stopDurationProvider.calcPickupDuration(vehicle, request.getRequest()); + enterTimes.put(request.getId(), enterTime); + } + + @Override + protected void simStep(double now) { + // dynamics are handled in isLastStep -> updatePickupRequests + } + + @Override + public void notifyPassengersAreReadyForDeparture(List passengers, double now) { + var request = getRequestForPassengers(passengers.stream().map(Identifiable::getId).toList()); + queuePickup(request, now); + } + + + private AcceptedDrtRequest getRequestForPassengers(List> passengerIds) { + return pickupRequests.values() + .stream() + .filter(r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/AbandonVoter.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/AbandonVoter.java new file mode 100644 index 00000000000..20ba9a2baca --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/AbandonVoter.java @@ -0,0 +1,8 @@ +package org.matsim.contrib.drt.prebooking.abandon; + +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +public interface AbandonVoter { + boolean abandonRequest(double time, DvrpVehicle vehicle, AcceptedDrtRequest request); +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/MaximumDelayAbandonVoter.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/MaximumDelayAbandonVoter.java new file mode 100644 index 00000000000..f23c6623e22 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/abandon/MaximumDelayAbandonVoter.java @@ -0,0 +1,19 @@ +package org.matsim.contrib.drt.prebooking.abandon; + +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +public class MaximumDelayAbandonVoter implements AbandonVoter { + private final double maximumDelay; + + public MaximumDelayAbandonVoter(double maximumDelay) { + this.maximumDelay = maximumDelay; + } + + @Override + public boolean abandonRequest(double time, DvrpVehicle vehicle, AcceptedDrtRequest request) { + double requestedDepartureTime = request.getEarliestStartTime(); + double delay = time - requestedDepartureTime; + return delay > maximumDelay; + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisHandler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisHandler.java new file mode 100644 index 00000000000..a160ac5fce4 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisHandler.java @@ -0,0 +1,118 @@ +package org.matsim.contrib.drt.prebooking.analysis; + +import java.util.LinkedList; +import java.util.List; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.prebooking.PassengerRequestBookedEvent; +import org.matsim.contrib.drt.prebooking.PassengerRequestBookedEventHandler; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEvent; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEventHandler; + +public class PrebookingAnalysisHandler implements PassengerRequestBookedEventHandler, + PassengerRequestSubmittedEventHandler, PassengerRequestScheduledEventHandler, + PassengerRequestRejectedEventHandler, PassengerWaitingEventHandler { + private final String mode; + private final IdMap sequences = new IdMap<>(Request.class); + + public PrebookingAnalysisHandler(String mode) { + this.mode = mode; + } + + @Override + public void handleEvent(PassengerRequestBookedEvent event) { + sequences.put(event.getRequestId(), new Sequence(event)); + } + + @Override + public void handleEvent(PassengerRequestSubmittedEvent event) { + if (!event.getMode().equals(mode)) { + return; + } + + Sequence sequence = sequences.get(event.getRequestId()); + + if (sequence != null) { + sequence.submitted = event; + } + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + if (!event.getMode().equals(mode)) { + return; + } + + Sequence sequence = sequences.get(event.getRequestId()); + + if (sequence != null && sequence.rejected == null) { // only use first + sequence.rejected = event; + } + } + + @Override + public void handleEvent(PassengerRequestScheduledEvent event) { + if (!event.getMode().equals(mode)) { + return; + } + + Sequence sequence = sequences.get(event.getRequestId()); + + if (sequence != null) { + sequence.scheduled = event; + } + } + + @Override + public void handleEvent(PassengerWaitingEvent event) { + if (!event.getMode().equals(mode)) { + return; + } + + Sequence sequence = sequences.get(event.getRequestId()); + + if (sequence != null) { + sequence.waiting = event; + } + } + + public List getRecords() { + List records = new LinkedList<>(); + + for (Sequence sequence : sequences) { + records.add(new RequestRecord(sequence.booked.getRequestId(), sequence.booked.getPersonIds(), + sequence.submitted != null ? sequence.submitted.getTime() : null, + sequence.scheduled != null ? sequence.scheduled.getTime() : null, + sequence.rejected != null ? sequence.rejected.getTime() : null, + sequence.waiting != null ? sequence.waiting.getTime() : null, + sequence.rejected != null ? sequence.rejected.getCause() : null)); + } + + return records; + } + + public record RequestRecord(Id requestId, List> personIds, Double submissionTime, Double scheduledTime, + Double rejectedTime, Double departureTime, String rejectedReason) { + } + + private class Sequence { + final PassengerRequestBookedEvent booked; + PassengerRequestSubmittedEvent submitted; + PassengerRequestScheduledEvent scheduled; + PassengerRequestRejectedEvent rejected; + PassengerWaitingEvent waiting; + + Sequence(PassengerRequestBookedEvent booked) { + this.booked = booked; + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisListener.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisListener.java new file mode 100644 index 00000000000..f90dab2c2ce --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisListener.java @@ -0,0 +1,42 @@ +package org.matsim.contrib.drt.prebooking.analysis; + +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.controler.events.IterationEndsEvent; +import org.matsim.core.controler.events.IterationStartsEvent; +import org.matsim.core.controler.listener.IterationEndsListener; +import org.matsim.core.controler.listener.IterationStartsListener; + +public class PrebookingAnalysisListener implements IterationStartsListener, IterationEndsListener { + private final String mode; + + private final OutputDirectoryHierarchy outputHierarchy; + private final EventsManager eventsManager; + + private PrebookingAnalysisHandler handler; + + public PrebookingAnalysisListener(String mode, EventsManager eventsManager, + OutputDirectoryHierarchy outputHierarchy) { + this.mode = mode; + this.eventsManager = eventsManager; + this.outputHierarchy = outputHierarchy; + } + + @Override + public void notifyIterationStarts(IterationStartsEvent event) { + handler = new PrebookingAnalysisHandler(mode); + eventsManager.addHandler(handler); + } + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + eventsManager.removeHandler(handler); + + String outputPath = outputHierarchy.getIterationFilename(event.getIteration(), getOutputFileName()); + new PrebookingAnalysisWriter(outputPath).write(handler.getRecords()); + } + + private String getOutputFileName() { + return String.format("prebooking_%s.csv", mode); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisWriter.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisWriter.java new file mode 100644 index 00000000000..5127841f292 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingAnalysisWriter.java @@ -0,0 +1,48 @@ +package org.matsim.contrib.drt.prebooking.analysis; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import org.matsim.core.utils.io.IOUtils; + +public class PrebookingAnalysisWriter { + private final String outputPath; + + public PrebookingAnalysisWriter(String outputPath) { + this.outputPath = outputPath; + } + + public void write(List records) { + try { + BufferedWriter writer = IOUtils.getBufferedWriter(outputPath); + + writer.write(String.join(",", new String[] { // + "request_id", // + "person_id", // + "submission_time", // + "scheduled_time", // + "rejected_time", // + "departure_time", // + "rejected_reason" // + }) + "\n"); + + for (var record : records) { + writer.write(String.join(",", new String[] { // + record.requestId().toString(), // + record.personIds().stream().map(Object::toString).collect(Collectors.joining("-")), // + record.submissionTime() == null ? "" : String.valueOf(record.submissionTime()), // + record.scheduledTime() == null ? "" : String.valueOf(record.scheduledTime()), // + record.rejectedTime() == null ? "" : String.valueOf(record.rejectedTime()), // + record.departureTime() == null ? "" : String.valueOf(record.departureTime()), // + record.rejectedReason() // + }) + "\n"); + } + + writer.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingModeAnalysisModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingModeAnalysisModule.java new file mode 100644 index 00000000000..5382f928d2d --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/analysis/PrebookingModeAnalysisModule.java @@ -0,0 +1,25 @@ +package org.matsim.contrib.drt.prebooking.analysis; + +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.controler.OutputDirectoryHierarchy; + +import com.google.inject.Singleton; + +public class PrebookingModeAnalysisModule extends AbstractDvrpModeModule { + public PrebookingModeAnalysisModule(String mode) { + super(mode); + } + + @Override + public void install() { + addControlerListenerBinding().to(modalKey(PrebookingAnalysisListener.class)); + + bindModal(PrebookingAnalysisListener.class).toProvider(modalProvider(getter -> { + EventsManager eventsManager = getter.get(EventsManager.class); + OutputDirectoryHierarchy outputHierarchy = getter.get(OutputDirectoryHierarchy.class); + + return new PrebookingAnalysisListener(getMode(), eventsManager, outputHierarchy); + })).in(Singleton.class); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AdaptivePrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AdaptivePrebookingLogic.java new file mode 100644 index 00000000000..349000a5ac7 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AdaptivePrebookingLogic.java @@ -0,0 +1,118 @@ +package org.matsim.contrib.drt.prebooking.logic; + +import org.matsim.api.core.v01.events.ActivityStartEvent; +import org.matsim.api.core.v01.events.handler.ActivityStartEventHandler; +import org.matsim.api.core.v01.population.Activity; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contrib.drt.prebooking.PrebookingManager; +import org.matsim.contrib.drt.prebooking.logic.helpers.PrebookingQueue; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.events.MobsimScopeEventHandler; +import org.matsim.core.mobsim.framework.MobsimAgent; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.mobsim.qsim.agents.WithinDayAgentUtils; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; + +import com.google.common.base.Preconditions; + +/** + * This is a prebooking logic that, whenever an agent starts an activity, checks + * whether there is a DRT leg coming up before the next main (non-stage) + * activity. If so, the upcoming leg is prebooked in advance with the + * submissionSlack parameter defining how much in advance. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class AdaptivePrebookingLogic implements PrebookingLogic, ActivityStartEventHandler, MobsimScopeEventHandler { + private final QSim qsim; + private final PrebookingManager prebookingManager; + private final PrebookingQueue prebookingQueue; + private final TimeInterpretation timeInterpretation; + + private final String mode; + + private final double submissionSlack; + + private AdaptivePrebookingLogic(String mode, QSim qsim, PrebookingManager prebookingManager, + PrebookingQueue prebookingQueue, TimeInterpretation timeInterpretation, double submissionSlack) { + this.prebookingManager = prebookingManager; + this.prebookingQueue = prebookingQueue; + this.qsim = qsim; + this.mode = mode; + this.timeInterpretation = timeInterpretation; + this.submissionSlack = submissionSlack; + } + + @Override + public void handleEvent(ActivityStartEvent event) { + MobsimAgent agent = qsim.getAgents().get(event.getPersonId()); + + Plan plan = WithinDayAgentUtils.getModifiablePlan(agent); + int planElementIndex = WithinDayAgentUtils.getCurrentPlanElementIndex(agent); + + TimeTracker timeTracker = new TimeTracker(timeInterpretation); + timeTracker.setTime(event.getTime()); + + /* + * Now we starting to traverse the remaining plan to see if we find a DRT leg + * that comes after the currently started activity. If so, we prebook it with + * the configured submission slack. We start searching one we reach the next + * non-stage activity type. + */ + + for (int i = planElementIndex + 1; i < plan.getPlanElements().size(); i++) { + PlanElement element = plan.getPlanElements().get(i); + + if (element instanceof Activity) { + Activity activity = (Activity) element; + + if (!TripStructureUtils.isStageActivityType(activity.getType())) { + break; // only consider legs coming directly after the ongoing activity + } + } else if (element instanceof Leg) { + Leg leg = (Leg) element; + + if (mode.equals(leg.getMode())) { + double departureTime = timeTracker.getTime().seconds(); + + if (prebookingManager.getRequestId(leg) == null) { + // only book legs that are not already prebooked + + double submissionTime = Math.max(event.getTime(), departureTime - submissionSlack); + if (submissionTime > departureTime) { + prebookingQueue.schedule(submissionTime, agent, leg, departureTime); + } + } + } + } + + timeTracker.addElement(element); + } + } + + static public AbstractDvrpModeQSimModule createModule(DrtConfigGroup drtConfig, double subissionSlack) { + return new AbstractDvrpModeQSimModule(drtConfig.getMode()) { + @Override + protected void configureQSim() { + bindModal(AdaptivePrebookingLogic.class).toProvider(modalProvider(getter -> { + Preconditions.checkState(drtConfig.getPrebookingParams().isPresent()); + + return new AdaptivePrebookingLogic(drtConfig.getMode(), getter.get(QSim.class), + getter.getModal(PrebookingManager.class), getter.getModal(PrebookingQueue.class), + getter.get(TimeInterpretation.class), subissionSlack); + })); + addMobsimScopeEventHandlerBinding().to(modalKey(AdaptivePrebookingLogic.class)); + } + }; + } + + static public void install(Controler controller, DrtConfigGroup drtConfig, double subissionSlack) { + controller.addOverridingQSimModule(createModule(drtConfig, subissionSlack)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java new file mode 100644 index 00000000000..a48cbe50e46 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/AttributeBasedPrebookingLogic.java @@ -0,0 +1,137 @@ +package org.matsim.contrib.drt.prebooking.logic; + +import java.util.Optional; + +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator.PopulationIteratorFactory; +import org.matsim.contrib.drt.prebooking.logic.helpers.PrebookingQueue; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.router.TripStructureUtils.Trip; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; + +import com.google.common.base.Preconditions; + +/** + * This class represents a prebooking logic that will search for the + * "prebooking:submissionTime:[mode]" attribute in the origin activity of a + * trip. If a DRT leg is found in the trip, the submission time for this request + * will be read from the attribute. In order to make use of prebooked requests, + * you need to define these attributes before the start of the QSim iteration. + * + * To indicate the expected departure time (for which the vehicle is requested), + * you can also define the "prebooking:plannedDepartureTime:[mode]" attribute. + * If it is not specified, the logic will try to figure out the departure time + * by traversing the activities and legs according to the configured time + * interpretation. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class AttributeBasedPrebookingLogic implements PrebookingLogic, MobsimInitializedListener { + static private final String SUBMISSION_TIME_ATTRIBUTE_PREFIX = "prebooking:submissionTime"; + static private final String PLANNED_DEPARTURE_ATTRIBUTE_PREFIX = "prebooking:plannedDepartureTime"; + + static public String getSubmissionAttribute(String mode) { + return SUBMISSION_TIME_ATTRIBUTE_PREFIX + mode; + } + + static public String getPlannedDepartureAttribute(String mode) { + return PLANNED_DEPARTURE_ATTRIBUTE_PREFIX + mode; + } + + static public Optional getSubmissionTime(String mode, Trip trip) { + return Optional.ofNullable((Double) trip.getTripAttributes().getAttribute(getSubmissionAttribute(mode))); + } + + static public Optional getPlannedDepartureTime(String mode, Trip trip) { + return Optional.ofNullable((Double) trip.getTripAttributes().getAttribute(getPlannedDepartureAttribute(mode))); + } + + private final PrebookingQueue prebookingQueue; + private final PopulationIteratorFactory populationIteratorFactory; + private final TimeInterpretation timeInterpretation; + + private final String mode; + + private AttributeBasedPrebookingLogic(String mode, PrebookingQueue prebookingQueue, + PopulationIteratorFactory populationIteratorFactory, TimeInterpretation timeInterpretation) { + this.prebookingQueue = prebookingQueue; + this.populationIteratorFactory = populationIteratorFactory; + this.mode = mode; + this.timeInterpretation = timeInterpretation; + + } + + @Override + public void notifyMobsimInitialized(@SuppressWarnings("rawtypes") MobsimInitializedEvent e) { + PopulationIterator populationIterator = populationIteratorFactory.create(); + + while (populationIterator.hasNext()) { + var personItem = populationIterator.next(); + + TimeTracker timeTracker = new TimeTracker(timeInterpretation); + + for (Trip trip : TripStructureUtils.getTrips(personItem.plan())) { + timeTracker.addActivity(trip.getOriginActivity()); + boolean foundLeg = false; + + for (PlanElement element : trip.getTripElements()) { + if (element instanceof Leg) { + Leg leg = (Leg) element; + + if (mode.equals(leg.getMode())) { + Preconditions.checkState(!foundLeg, + "Attribute-based prebooking logic only works with one DRT leg per trip"); + foundLeg = true; + + Optional submissionTime = getSubmissionTime(mode, trip); + Optional plannedDepartureTime = getPlannedDepartureTime(mode, trip); + + if (submissionTime.isPresent()) { + if (plannedDepartureTime.isPresent()) { + Preconditions.checkState(plannedDepartureTime.get() > submissionTime.get(), + "Planned departure time must be after submission time"); + } + + prebookingQueue.schedule(submissionTime.get(), personItem.agent(), leg, + plannedDepartureTime.orElse(timeTracker.getTime().seconds())); + } + } + } + + timeTracker.addElement(element); + } + + } + } + + prebookingQueue.performInitialSubmissions(); + } + + static public AbstractDvrpModeQSimModule createModule(DrtConfigGroup drtConfig) { + return new AbstractDvrpModeQSimModule(drtConfig.getMode()) { + @Override + protected void configureQSim() { + bindModal(AttributeBasedPrebookingLogic.class).toProvider(modalProvider(getter -> { + Preconditions.checkState(drtConfig.getPrebookingParams().isPresent()); + + return new AttributeBasedPrebookingLogic(drtConfig.getMode(), + getter.getModal(PrebookingQueue.class), getter.getModal(PopulationIteratorFactory.class), + getter.get(TimeInterpretation.class)); + })); + addModalQSimComponentBinding().to(modalKey(AttributeBasedPrebookingLogic.class)); + } + }; + } + + static public void install(Controler controller, DrtConfigGroup drtConfig) { + controller.addOverridingQSimModule(createModule(drtConfig)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PersonBasedPrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PersonBasedPrebookingLogic.java new file mode 100644 index 00000000000..a7faed87853 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PersonBasedPrebookingLogic.java @@ -0,0 +1,113 @@ +package org.matsim.contrib.drt.prebooking.logic; + +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator.PopulationIteratorFactory; +import org.matsim.contrib.drt.prebooking.logic.helpers.PrebookingQueue; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; + +import com.google.common.base.Preconditions; + +/** + * This is a prebooking logic that detects a person-level attribute which + * indicates whether requests to a certain DRT mode for that person are + * prebooked. It can be installed by calling + * + * PersonBasedPrebookingLogic.install + * + * on the controller with the respective DRT mode and a value indicating the + * prebooking slack, i.e., the time between the expected departure and when the + * request is submitted. + */ +public class PersonBasedPrebookingLogic implements PrebookingLogic, MobsimInitializedListener { + static private final String ATTRIBUTE_PREFIX = "prebooking:"; + + static public String getPersonAttribute(String mode) { + return ATTRIBUTE_PREFIX + mode; + } + + static public String getPersonAttribute(DrtConfigGroup drtConfig) { + return getPersonAttribute(drtConfig.getMode()); + } + + static public boolean isPrebooked(String mode, Person person) { + Boolean isPrebooked = (Boolean) person.getAttributes().getAttribute(getPersonAttribute(mode)); + return isPrebooked == true; + } + + private final PrebookingQueue prebookingQueue; + private final PopulationIteratorFactory populationIteratorFactory; + private final TimeInterpretation timeInterpretation; + + private final String mode; + private final double submissionSlack; + + private PersonBasedPrebookingLogic(String mode, PrebookingQueue prebookingQueue, + PopulationIteratorFactory populationIteratorFactory, TimeInterpretation timeInterpretation, + double submissionSlack) { + this.prebookingQueue = prebookingQueue; + this.populationIteratorFactory = populationIteratorFactory; + this.mode = mode; + this.timeInterpretation = timeInterpretation; + this.submissionSlack = submissionSlack; + + } + + @Override + public void notifyMobsimInitialized(@SuppressWarnings("rawtypes") MobsimInitializedEvent e) { + PopulationIterator populationIterator = populationIteratorFactory.create(); + + while (populationIterator.hasNext()) { + var personItem = populationIterator.next(); + + if (isPrebooked(mode, personItem.plan().getPerson())) { + TimeTracker timeTracker = new TimeTracker(timeInterpretation); + + for (PlanElement element : personItem.plan().getPlanElements()) { + if (element instanceof Leg) { + Leg leg = (Leg) element; + + if (leg.getMode().equals(mode)) { + double earliestDepartureTime = leg.getDepartureTime().seconds(); + double submissionTime = earliestDepartureTime - submissionSlack; + + prebookingQueue.schedule(submissionTime, personItem.agent(), leg, earliestDepartureTime); + } + } + + timeTracker.addElement(element); + } + } + } + + prebookingQueue.performInitialSubmissions(); + } + + static public AbstractDvrpModeQSimModule createModule(DrtConfigGroup drtConfig, double prebookingSlack) { + return new AbstractDvrpModeQSimModule(drtConfig.getMode()) { + @Override + protected void configureQSim() { + bindModal(PersonBasedPrebookingLogic.class).toProvider(modalProvider(getter -> { + Preconditions.checkState(drtConfig.getPrebookingParams().isPresent()); + + return new PersonBasedPrebookingLogic(drtConfig.getMode(), getter.getModal(PrebookingQueue.class), + getter.getModal(PopulationIteratorFactory.class), getter.get(TimeInterpretation.class), + prebookingSlack); + })); + addModalQSimComponentBinding().to(modalKey(PersonBasedPrebookingLogic.class)); + } + }; + } + + static public void install(Controler controller, DrtConfigGroup drtConfig, double prebookingSlack) { + controller.addOverridingQSimModule(createModule(drtConfig, prebookingSlack)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PrebookingLogic.java new file mode 100644 index 00000000000..d46edeea35f --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/PrebookingLogic.java @@ -0,0 +1,11 @@ +package org.matsim.contrib.drt.prebooking.logic; + +/** + * An interface that tags a prebooking logic, but doesn't have any functionality + * itself. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public interface PrebookingLogic { + +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/ProbabilityBasedPrebookingLogic.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/ProbabilityBasedPrebookingLogic.java new file mode 100644 index 00000000000..2a62cb6b2d6 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/ProbabilityBasedPrebookingLogic.java @@ -0,0 +1,101 @@ +package org.matsim.contrib.drt.prebooking.logic; + +import java.util.Random; + +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator.PopulationIteratorFactory; +import org.matsim.contrib.drt.prebooking.logic.helpers.PrebookingQueue; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; + +import com.google.common.base.Preconditions; + +/** + * This class represents a prebooking logic that searches for DRT legs in the + * population and decides based on a predefiend probability if each trip is + * prebooked or not. Furthermore, you can configure how much in advance to the + * planned departure time the request is submitted using the submissionSlack + * parameter. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class ProbabilityBasedPrebookingLogic implements PrebookingLogic, MobsimInitializedListener { + private final PrebookingQueue prebookingQueue; + private final PopulationIteratorFactory populationIteratorFactory; + private final TimeInterpretation timeInterpretation; + private final Random random; + + private final String mode; + private final double probability; + private final double submissionSlack; + + private ProbabilityBasedPrebookingLogic(String mode, PrebookingQueue prebookingQueue, + PopulationIteratorFactory populationIteratorFactory, TimeInterpretation timeInterpretation, Random random, + double probability, double submissionSlack) { + this.prebookingQueue = prebookingQueue; + this.populationIteratorFactory = populationIteratorFactory; + this.mode = mode; + this.timeInterpretation = timeInterpretation; + this.random = random; + this.probability = probability; + this.submissionSlack = submissionSlack; + } + + @Override + public void notifyMobsimInitialized(@SuppressWarnings("rawtypes") MobsimInitializedEvent e) { + PopulationIterator populationIterator = populationIteratorFactory.create(); + + while (populationIterator.hasNext()) { + var personItem = populationIterator.next(); + + TimeTracker timeTracker = new TimeTracker(timeInterpretation); + + for (PlanElement element : personItem.plan().getPlanElements()) { + if (element instanceof Leg) { + Leg leg = (Leg) element; + + if (mode.equals(leg.getMode()) && random.nextDouble() <= probability) { + double departureTime = timeTracker.getTime().seconds(); + double submissionTime = departureTime - submissionSlack; + + prebookingQueue.schedule(submissionTime, personItem.agent(), leg, departureTime); + } + } + + timeTracker.addElement(element); + } + } + + prebookingQueue.performInitialSubmissions(); + } + + static public AbstractDvrpModeQSimModule createModule(DrtConfigGroup drtConfig, double probability, + double submissionSlack) { + return new AbstractDvrpModeQSimModule(drtConfig.getMode()) { + @Override + protected void configureQSim() { + bindModal(ProbabilityBasedPrebookingLogic.class).toProvider(modalProvider(getter -> { + Preconditions.checkState(drtConfig.getPrebookingParams().isPresent()); + + return new ProbabilityBasedPrebookingLogic(drtConfig.getMode(), + getter.getModal(PrebookingQueue.class), getter.getModal(PopulationIteratorFactory.class), + getter.get(TimeInterpretation.class), new Random(getConfig().global().getRandomSeed()), + probability, submissionSlack); + })); + addModalQSimComponentBinding().to(modalKey(ProbabilityBasedPrebookingLogic.class)); + } + }; + } + + static public void install(Controler controller, DrtConfigGroup drtConfig, double probability, + double prebookingSlack) { + controller.addOverridingQSimModule(createModule(drtConfig, probability, prebookingSlack)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PopulationIterator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PopulationIterator.java new file mode 100644 index 00000000000..faf2c1ce87c --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PopulationIterator.java @@ -0,0 +1,57 @@ +package org.matsim.contrib.drt.prebooking.logic.helpers; + +import java.util.Iterator; + +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.api.core.v01.population.Population; +import org.matsim.contrib.drt.prebooking.logic.helpers.PopulationIterator.PersonItem; +import org.matsim.core.mobsim.framework.MobsimAgent; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.mobsim.qsim.agents.HasModifiablePlan; + +/** + * This is a helper class that allows to loop through all persons that are + * active in a QSim. It is used to prebook drt legs for specific legs. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PopulationIterator implements Iterator { + private final QSim qsim; + private final Iterator internalIterator; + + private PopulationIterator(Population population, QSim qsim) { + this.qsim = qsim; + this.internalIterator = population.getPersons().values().iterator(); + } + + @Override + public boolean hasNext() { + return internalIterator.hasNext(); + } + + @Override + public PersonItem next() { + Person person = internalIterator.next(); + MobsimAgent agent = qsim.getAgents().get(person.getId()); + Plan plan = ((HasModifiablePlan) agent).getModifiablePlan(); + return new PersonItem(agent, plan); + } + + public record PersonItem(MobsimAgent agent, Plan plan) { + } + + static public class PopulationIteratorFactory { + private final Population population; + private final QSim qsim; + + public PopulationIteratorFactory(Population population, QSim qsim) { + this.population = population; + this.qsim = qsim; + } + + public PopulationIterator create() { + return new PopulationIterator(population, qsim); + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PrebookingQueue.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PrebookingQueue.java new file mode 100644 index 00000000000..788a430c069 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/logic/helpers/PrebookingQueue.java @@ -0,0 +1,96 @@ +package org.matsim.contrib.drt.prebooking.logic.helpers; + +import com.google.common.base.Preconditions; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.contrib.drt.prebooking.PrebookingManager; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; +import org.matsim.core.mobsim.framework.MobsimAgent; +import org.matsim.core.mobsim.framework.MobsimPassengerAgent; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; + +import java.util.*; + +/** + * This service helps to define a PrebookingLogic where at some point in time + * (usually at the beginning of the simulaton), it is known in advance that a + * request will happen at a specific time. Once we know that the request will be + * sent, we can use the present class to put it in a queue, making sure the + * request will be *booked* the the time we want. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PrebookingQueue implements MobsimBeforeSimStepListener { + private final PrebookingManager prebookingManager; + + private PriorityQueue queue = new PriorityQueue<>(); + private Integer sequence = 0; + + private double currentTime = Double.NEGATIVE_INFINITY; + + private final PassengerGroupIdentifier groupIdentifier; + + public PrebookingQueue(PrebookingManager prebookingManager, PassengerGroupIdentifier groupIdentifier) { + this.prebookingManager = prebookingManager; + this.groupIdentifier = groupIdentifier; + } + + @Override + public void notifyMobsimBeforeSimStep(@SuppressWarnings("rawtypes") MobsimBeforeSimStepEvent event) { + performSubmissions(event.getSimulationTime()); + } + + private void performSubmissions(double time) { + currentTime = time; + + Map, List> groups = new LinkedHashMap<>(); + while (!queue.isEmpty() && queue.peek().submissionTime <= time) { + var item = queue.poll(); + Optional> groupId = groupIdentifier.getGroupId((MobsimPassengerAgent) item.agent); + if(groupId.isEmpty()) { + prebookingManager.prebook(item.agent(), item.leg(), item.departureTime()); + } else { + groups.computeIfAbsent(groupId.get(), k -> new ArrayList<>()).add(item); + } + } + for (List group : groups.values()) { + List personsLegs = group.stream().map(entry -> new PrebookingManager.PersonLeg(entry.agent, entry.leg)).toList(); + prebookingManager.prebook(personsLegs, group.get(0).departureTime); + } + } + + /** + * May be called by a submission logic to directly perform submission after the + * MobsimInitializedEvent, otherwise this is called automatically per time step + * to see if there are requests queued that need to be submitted. + */ + public void performInitialSubmissions() { + performSubmissions(Double.NEGATIVE_INFINITY); + } + + public void schedule(double submissionTime, MobsimAgent agent, Leg leg, double departureTime) { + Preconditions.checkArgument(submissionTime > currentTime, "Can only submit future requests"); + + synchronized (queue) { // synchronizing for queue and sequence + queue.add(new ScheduledSubmission(submissionTime, agent, leg, departureTime, sequence++)); + } + } + + private record ScheduledSubmission(double submissionTime, MobsimAgent agent, Leg leg, double departureTime, + int sequence) implements Comparable { + @Override + public int compareTo(ScheduledSubmission o) { + // sort by submissionTime, but otherwise keep the order of submission + int comparison = Double.compare(submissionTime, o.submissionTime); + + if (comparison != 0) { + return comparison; + } + + // comparing by sequence, because a PriorityQueue is *not* preserving the order + // of two elements with the same comparison value + return Integer.compare(sequence, o.sequence); + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/ComplexRequestUnscheduler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/ComplexRequestUnscheduler.java new file mode 100644 index 00000000000..4fb0cae5339 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/ComplexRequestUnscheduler.java @@ -0,0 +1,319 @@ +package org.matsim.contrib.drt.prebooking.unscheduler; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.optimizer.Waypoint; +import org.matsim.contrib.drt.schedule.DrtDriveTask; +import org.matsim.contrib.drt.schedule.DrtStayTask; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.drt.schedule.DrtTaskBaseType; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleLookup; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.path.VrpPaths; +import org.matsim.contrib.dvrp.schedule.DriveTask; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.schedule.Schedules; +import org.matsim.contrib.dvrp.schedule.StayTask; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.schedule.Task.TaskStatus; +import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; +import org.matsim.contrib.dvrp.util.LinkTimePair; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.TravelTime; + +import com.google.common.base.Verify; + +/** + * This RequestUnscheduler searches for a request in a vehicle's schedule and + * removes the request from the relevant stop tasks. Furthermore, the stops are + * removed if they don't carry any other pickups or dropoffs. Accordingly, the + * schedule will also be rerouted. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class ComplexRequestUnscheduler implements RequestUnscheduler { + private final DvrpVehicleLookup vehicleLookup; + private final VehicleEntry.EntryFactory vehicleEntryFactory; + + private final DrtTaskFactory taskFactory; + + private final LeastCostPathCalculator router; + private final TravelTime travelTime; + private final ScheduleTimingUpdater timingUpdater; + + private final boolean scheduleWaitBeforeDrive; + + public ComplexRequestUnscheduler(DvrpVehicleLookup vehicleLookup, VehicleEntry.EntryFactory vehicleEntryFactory, + DrtTaskFactory taskFactory, LeastCostPathCalculator router, TravelTime travelTime, + ScheduleTimingUpdater timingUpdater, boolean scheduleWaitBeforeDrive) { + this.vehicleLookup = vehicleLookup; + this.vehicleEntryFactory = vehicleEntryFactory; + this.taskFactory = taskFactory; + this.travelTime = travelTime; + this.router = router; + this.timingUpdater = timingUpdater; + this.scheduleWaitBeforeDrive = scheduleWaitBeforeDrive; + } + + @Override + public void unscheduleRequest(double now, Id vehicleId, Id requestId) { + DvrpVehicle vehicle = vehicleLookup.lookupVehicle(vehicleId); + VehicleEntry vEntry = vehicleEntryFactory.create(vehicle, now); + + Waypoint.Stop pickupStop = null; + Waypoint.Stop dropoffStop = null; + + DrtStopTask pickupStopTask = null; + DrtStopTask dropoffStopTask = null; + + for (Waypoint.Stop stop : vEntry.stops) { + if (stop.task.getPickupRequests().containsKey(requestId)) { + Verify.verify(pickupStop == null); + Verify.verify(pickupStopTask == null); + + pickupStop = stop; + pickupStopTask = stop.task; + } + + if (stop.task.getDropoffRequests().containsKey(requestId)) { + Verify.verify(dropoffStop == null); + Verify.verify(dropoffStopTask == null); + + dropoffStop = stop; + dropoffStopTask = stop.task; + } + } + + Verify.verifyNotNull(pickupStopTask, "Could not find request that I'm supposed to unschedule"); + Verify.verifyNotNull(dropoffStopTask, "Could not find request that I'm supposed to unschedule"); + Verify.verifyNotNull(pickupStop); + Verify.verifyNotNull(dropoffStop); + + // remove request from stop, this we do in any case + pickupStopTask.removePickupRequest(requestId); + dropoffStopTask.removeDropoffRequest(requestId); + + // remove pickup + // - either we didn't find a stop (because task is running), then we have + // removed the pickup and the StopAction will handle the situation + // - or we found a stop, then it is not started yet and we can remove it + + boolean removePickup = pickupStopTask.getPickupRequests().size() == 0 + && pickupStopTask.getDropoffRequests().size() == 0; + boolean removeDropoff = dropoffStopTask.getPickupRequests().size() == 0 + && dropoffStopTask.getDropoffRequests().size() == 0; + + Replacement pickupReplacement = removePickup ? findReplacement(vEntry, pickupStop) : null; + Replacement dropoffReplacement = removeDropoff ? findReplacement(vEntry, dropoffStop) : null; + + if (pickupReplacement != null && dropoffReplacement != null) { + if (pickupReplacement.endTask.getTaskIdx() >= dropoffReplacement.startTask.getTaskIdx()) { + // we have an overlap + pickupReplacement = new Replacement(pickupReplacement.startTask, dropoffReplacement.endTask, + vehicle.getSchedule()); + dropoffReplacement = null; + } + } + + if (pickupReplacement != null) { + unschedule(now, vEntry, pickupReplacement); + } + + if (dropoffReplacement != null) { + unschedule(now, vEntry, dropoffReplacement); + } + } + + private Replacement findReplacement(VehicleEntry vEntry, Waypoint.Stop stop) { + int stopIndex = vEntry.stops.indexOf(stop); + + final Task startTask; + if (stopIndex == 0) { + startTask = vEntry.vehicle.getSchedule().getCurrentTask(); + } else { + startTask = vEntry.stops.get(stopIndex - 1).task; + } + + final Task endTask; + if (stopIndex == vEntry.stops.size() - 1) { + endTask = Schedules.getLastTask(vEntry.vehicle.getSchedule()); + } else { + endTask = vEntry.stops.get(stopIndex + 1).task; + } + + return new Replacement(startTask, endTask, vEntry.vehicle.getSchedule()); + } + + private void unschedule(double now, VehicleEntry vEntry, Replacement replacement) { + Schedule schedule = vEntry.vehicle.getSchedule(); + + if (replacement.startTask instanceof DrtStayTask) { + replacement.startTask.setEndTime(now); + } + + // special case: we remove everything until the end (and replace the stay task) + boolean removeUntilEnd = replacement.endTask == Schedules.getLastTask(schedule); + if (removeUntilEnd) { + Verify.verify(replacement.endTask instanceof DrtStayTask); + final Link stayLink; + + if (replacement.startTask instanceof StayTask) { + stayLink = ((StayTask) replacement.startTask).getLink(); + } else { + Verify.verify(replacement.startTask.getStatus().equals(TaskStatus.STARTED)); + DriveTask driveTask = (DriveTask) replacement.startTask; + + OnlineDriveTaskTracker tracker = (OnlineDriveTaskTracker) driveTask.getTaskTracker(); + tracker.divertPath(VrpPaths.createZeroLengthPathForDiversion(tracker.getDiversionPoint())); + + stayLink = driveTask.getPath().getToLink(); + } + + double initialEndTime = replacement.endTask.getEndTime(); + + while (!(replacement.startTask == Schedules.getLastTask(schedule))) { + schedule.removeLastTask(); + } + + schedule.addTask(taskFactory.createStayTask(vEntry.vehicle, replacement.startTask.getEndTime(), + Math.max(replacement.startTask.getEndTime(), initialEndTime), stayLink)); + + return; // done + } + + // remove everything between the two indicated tasks + while (replacement.startTask.getTaskIdx() + 1 != replacement.endTask.getTaskIdx()) { + Task removeTask = schedule.getTasks().get(replacement.startTask.getTaskIdx() + 1); + schedule.removeTask(removeTask); + } + + // if destination is not the schedule end, it must be another stop + Verify.verify(replacement.endTask instanceof DrtStopTask); + Link endLink = ((StayTask) replacement.endTask).getLink(); + double endArrivalTime = replacement.endTask.getBeginTime(); + + final Task lastInsertedTask; + if (replacement.startTask instanceof DriveTask) { // special case: start task is driving + Verify.verify(replacement.startTask.getStatus().equals(TaskStatus.STARTED)); + + DriveTask driveTask = (DriveTask) replacement.startTask; + OnlineDriveTaskTracker tracker = (OnlineDriveTaskTracker) driveTask.getTaskTracker(); + LinkTimePair diversion = tracker.getDiversionPoint(); + + VrpPathWithTravelData vrpPath = VrpPaths.calcAndCreatePathForDiversion(diversion, endLink, router, + travelTime); + + if (vrpPath.getArrivalTime() < endArrivalTime && scheduleWaitBeforeDrive) { + tracker.divertPath(VrpPaths.createZeroLengthPathForDiversion(diversion)); + lastInsertedTask = insertDriveWithWait(vEntry.vehicle, replacement.startTask, vrpPath, endArrivalTime); + } else { + tracker.divertPath(vrpPath); + lastInsertedTask = insertWait(vEntry.vehicle, replacement.startTask, endArrivalTime); + } + } else { // normal case + StayTask startStayTask = (StayTask) replacement.startTask; + Link startLink = startStayTask.getLink(); + + if (startLink == endLink) { // no need to move, maybe just wait + if (startStayTask.getEndTime() < endArrivalTime) { + lastInsertedTask = insertWait(vEntry.vehicle, startStayTask, endArrivalTime); + } else { + lastInsertedTask = startStayTask; // nothing inserted + } + } else { + VrpPathWithTravelData vrpPath = VrpPaths.calcAndCreatePath(startLink, endLink, + startStayTask.getEndTime(), router, travelTime); + + lastInsertedTask = insertDriveWithWait(vEntry.vehicle, startStayTask, vrpPath, endArrivalTime); + } + } + + timingUpdater.updateTimingsStartingFromTaskIdx(vEntry.vehicle, lastInsertedTask.getTaskIdx() + 1, + lastInsertedTask.getEndTime()); + } + + /* + * Copy & paste from DefaultRequestInsertionScheduler + */ + private Task insertWait(DvrpVehicle vehicle, Task departureTask, double earliestNextStartTime) { + Schedule schedule = vehicle.getSchedule(); + + final Link waitLink; + if (departureTask instanceof StayTask) { + waitLink = ((StayTask) departureTask).getLink(); + } else if (departureTask instanceof DriveTask) { + waitLink = ((DriveTask) departureTask).getPath().getToLink(); + } else { + throw new IllegalStateException(); + } + + if (departureTask.getEndTime() < earliestNextStartTime) { + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, departureTask.getEndTime(), + earliestNextStartTime, waitLink); + schedule.addTask(departureTask.getTaskIdx() + 1, waitTask); + return waitTask; + } + + return departureTask; + } + + /* + * Copy & paste from DefaultRequestInsertionScheduler + */ + private Task insertDriveWithWait(DvrpVehicle vehicle, Task departureTask, VrpPathWithTravelData path, + double latestArrivalTime) { + Schedule schedule = vehicle.getSchedule(); + + Task leadingTask = departureTask; + + if (scheduleWaitBeforeDrive) { + double driveDepartureTime = latestArrivalTime - path.getTravelTime(); + + if (driveDepartureTime > departureTask.getEndTime()) { + // makes sense to insert a wait task before departure + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, departureTask.getEndTime(), + driveDepartureTime, path.getFromLink()); + schedule.addTask(departureTask.getTaskIdx() + 1, waitTask); + + path = path.withDepartureTime(driveDepartureTime); + leadingTask = waitTask; + } + } + + Task driveTask = taskFactory.createDriveTask(vehicle, path, DrtDriveTask.TYPE); + schedule.addTask(leadingTask.getTaskIdx() + 1, driveTask); + + if (driveTask.getEndTime() < latestArrivalTime) { + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, driveTask.getEndTime(), latestArrivalTime, + path.getToLink()); + schedule.addTask(driveTask.getTaskIdx() + 1, waitTask); + return waitTask; + } else { + return driveTask; + } + } + + private class Replacement { + final Task startTask; + final Task endTask; + + Replacement(Task startTask, Task endTask, Schedule schedule) { + boolean startIsOngoing = startTask.getStatus().equals(TaskStatus.STARTED); + boolean startIsStopTask = DrtTaskBaseType.STOP.isBaseTypeOf(startTask); + + Verify.verify(startIsOngoing || startIsStopTask); + this.startTask = startTask; + + boolean endIsLastStay = endTask instanceof DrtStayTask && Schedules.getLastTask(schedule) == endTask; + boolean endIsStopTask = DrtTaskBaseType.STOP.isBaseTypeOf(endTask); + + Verify.verify(endIsLastStay || endIsStopTask); + this.endTask = endTask; + } + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/RequestUnscheduler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/RequestUnscheduler.java new file mode 100644 index 00000000000..fde9b138e92 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/RequestUnscheduler.java @@ -0,0 +1,9 @@ +package org.matsim.contrib.drt.prebooking.unscheduler; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; + +public interface RequestUnscheduler { + void unscheduleRequest(double now, Id vehicleId, Id requestId); +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/SimpleRequestUnscheduler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/SimpleRequestUnscheduler.java new file mode 100644 index 00000000000..bc6f2f0fbcc --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/unscheduler/SimpleRequestUnscheduler.java @@ -0,0 +1,60 @@ +package org.matsim.contrib.drt.prebooking.unscheduler; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleLookup; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Task; + +import com.google.common.base.Verify; + +/** + * This RequestUnscheduler searches for a request in a vehicle's schedule and + * removes the request from the relevant stop tasks. No other changes (wrt to + * rerouting the vehicle) are applied to the schedule. + * + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class SimpleRequestUnscheduler implements RequestUnscheduler { + private final DvrpVehicleLookup vehicleLookup; + + public SimpleRequestUnscheduler(DvrpVehicleLookup vehicleLookup) { + this.vehicleLookup = vehicleLookup; + } + + @Override + public void unscheduleRequest(double now, Id vehicleId, Id requestId) { + DvrpVehicle vehicle = vehicleLookup.lookupVehicle(vehicleId); + Schedule schedule = vehicle.getSchedule(); + + DrtStopTask pickupTask = null; + DrtStopTask dropoffTask = null; + + int currentIndex = schedule.getCurrentTask().getTaskIdx(); + for (; currentIndex < schedule.getTaskCount() && dropoffTask == null; currentIndex++) { + Task currentTask = schedule.getTasks().get(currentIndex); + + if (currentTask instanceof DrtStopTask) { + DrtStopTask stopTask = (DrtStopTask) currentTask; + + if (stopTask.getPickupRequests().keySet().contains(requestId)) { + Verify.verify(pickupTask == null); + pickupTask = stopTask; + } + + if (stopTask.getDropoffRequests().keySet().contains(requestId)) { + Verify.verify(dropoffTask == null); + dropoffTask = stopTask; + } + } + } + + Verify.verifyNotNull(pickupTask); + Verify.verifyNotNull(dropoffTask); + + pickupTask.removePickupRequest(requestId); + dropoffTask.removeDropoffRequest(requestId); + } +} \ No newline at end of file diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifier.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifier.java index 549a4761a13..6fb846726ab 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifier.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifier.java @@ -31,7 +31,7 @@ import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.router.MainModeIdentifier; import org.matsim.core.router.MainModeIdentifierImpl; import org.matsim.core.router.TripRouter; @@ -49,7 +49,7 @@ public MultiModeDrtMainModeIdentifier(MultiModeDrtConfigGroup drtCfg) { stageActivityTypeToDrtMode = drtCfg.getModalElements() .stream() .map(DrtConfigGroup::getMode) - .collect(Collectors.toMap(PlanCalcScoreConfigGroup::createStageActivityType, s -> s)); + .collect(Collectors.toMap(ScoringConfigGroup::createStageActivityType, s -> s)); // #deleteBeforeRelease : only used to retrofit plans created since the merge of fallback routing module (sep'-dec'19) fallbackModeToDrtMode = drtCfg.getModalElements() diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java index 43c2cff26fb..03b9c551970 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigGroup.java @@ -38,13 +38,14 @@ import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchParams; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingParams; import org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.MinCostFlowRebalancingStrategyParams; +import org.matsim.contrib.drt.prebooking.PrebookingParams; import org.matsim.contrib.drt.speedup.DrtSpeedUpParams; import org.matsim.contrib.dvrp.router.DvrpModeRoutingNetworkModule; import org.matsim.contrib.dvrp.run.Modal; import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import com.google.common.base.Preconditions; import com.google.common.base.Verify; @@ -130,6 +131,15 @@ public static DrtConfigGroup getSingleModeDrtConfig(Config config) { @Comment("Idle vehicles return to the nearest of all start links. See: DvrpVehicle.getStartLink()") public boolean idleVehiclesReturnToDepots = false; + @Parameter + @Comment("Specifies the duration (seconds) a vehicle needs to be idle in order to get send back to the depot." + + "Please be aware, that returnToDepotEvaluationInterval describes the minimal time a vehicle will be idle before it gets send back to depot.") + public double returnToDepotTimeout = 60; + + @Parameter + @Comment("Specifies the time interval (seconds) a vehicle gets evaluated to be send back to depot.") + public double returnToDepotEvaluationInterval = 60; + public enum OperationalScheme { stopbased, door2door, serviceAreaBased } @@ -182,9 +192,6 @@ public enum OperationalScheme { @Comment("Store planned unshared drt route as a link sequence") public boolean storeUnsharedPath = false; // If true, the planned unshared path is stored and exported in plans - @PositiveOrZero - public double advanceRequestPlanningHorizon = 0; // beta-feature; planning horizon for advance (prebooked) requests - @NotNull private DrtInsertionSearchParams drtInsertionSearchParams; @@ -200,6 +207,9 @@ public enum OperationalScheme { @Nullable private DrtSpeedUpParams drtSpeedUpParams; + @Nullable + private PrebookingParams prebookingParams; + @Nullable private DrtRequestInsertionRetryParams drtRequestInsertionRetryParams; @@ -240,6 +250,11 @@ private void initSingletonParameterSets() { addDefinition(DrtRequestInsertionRetryParams.SET_NAME, DrtRequestInsertionRetryParams::new, () -> drtRequestInsertionRetryParams, params -> drtRequestInsertionRetryParams = (DrtRequestInsertionRetryParams)params); + + //prebooking (optional) + addDefinition(PrebookingParams.SET_NAME, PrebookingParams::new, + () -> prebookingParams, + params -> prebookingParams = (PrebookingParams)params); } @Override @@ -273,6 +288,11 @@ protected void checkConsistency(Config config) { + " in order to speed up the DRT route update during the replanning phase."); } + if (this.idleVehiclesReturnToDepots && this.returnToDepotTimeout < this.returnToDepotEvaluationInterval) { + log.warn("idleVehiclesReturnToDepots is active and returnToDepotTimeout < returnToDepotEvaluationInterval. " + + "Vehicles will be send back to depot after {} seconds",returnToDepotEvaluationInterval); + } + Verify.verify(getParameterSets(MinCostFlowRebalancingStrategyParams.SET_NAME).size() <= 1, "More than one rebalancing parameter sets is specified"); @@ -310,8 +330,12 @@ public Optional getDrtRequestInsertionRetryParam return Optional.ofNullable(drtRequestInsertionRetryParams); } + public Optional getPrebookingParams() { + return Optional.ofNullable(prebookingParams); + } + /** - * Convenience method that brings syntax closer to syntax in, e.g., {@link PlansCalcRouteConfigGroup} or {@link PlanCalcScoreConfigGroup} + * Convenience method that brings syntax closer to syntax in, e.g., {@link RoutingConfigGroup} or {@link ScoringConfigGroup} */ public final void addDrtInsertionSearchParams(final DrtInsertionSearchParams pars) { addParameterSet(pars); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigs.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigs.java index 92d29a97d42..dccfb2d7449 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigs.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtConfigs.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; /** * @author Michal Maciejewski (michalm) @@ -32,22 +32,22 @@ public class DrtConfigs { private static final Logger LOGGER = LogManager.getLogger(DrtControlerCreator.class); public static void adjustMultiModeDrtConfig(MultiModeDrtConfigGroup multiModeDrtCfg, - PlanCalcScoreConfigGroup planCalcScoreCfg, PlansCalcRouteConfigGroup plansCalcRouteCfg) { + ScoringConfigGroup planCalcScoreCfg, RoutingConfigGroup plansCalcRouteCfg) { for (DrtConfigGroup drtCfg : multiModeDrtCfg.getModalElements()) { DrtConfigs.adjustDrtConfig(drtCfg, planCalcScoreCfg, plansCalcRouteCfg); } } - public static void adjustDrtConfig(DrtConfigGroup drtCfg, PlanCalcScoreConfigGroup planCalcScoreCfg, - PlansCalcRouteConfigGroup plansCalcRouteCfg) { - String drtStageActivityType = PlanCalcScoreConfigGroup.createStageActivityType(drtCfg.getMode()); + public static void adjustDrtConfig(DrtConfigGroup drtCfg, ScoringConfigGroup planCalcScoreCfg, + RoutingConfigGroup plansCalcRouteCfg) { + String drtStageActivityType = ScoringConfigGroup.createStageActivityType(drtCfg.getMode()); if (planCalcScoreCfg.getActivityParams(drtStageActivityType) == null) { addDrtStageActivityParams(planCalcScoreCfg, drtStageActivityType); } } - private static void addDrtStageActivityParams(PlanCalcScoreConfigGroup planCalcScoreCfg, String stageActivityType) { - PlanCalcScoreConfigGroup.ActivityParams params = new PlanCalcScoreConfigGroup.ActivityParams(stageActivityType); + private static void addDrtStageActivityParams(ScoringConfigGroup planCalcScoreCfg, String stageActivityType) { + ScoringConfigGroup.ActivityParams params = new ScoringConfigGroup.ActivityParams(stageActivityType); params.setTypicalDuration(1); params.setScoringThisActivityAtAll(false); planCalcScoreCfg.getScoringParametersPerSubpopulation().values().forEach(k -> k.addActivityParams(params)); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java index 7c28080f46f..ab438acc805 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java @@ -61,7 +61,7 @@ public static Scenario createScenarioWithDrtRouteFactory(Config config) { */ public static Controler createControler(Config config, boolean otfvis) { MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing()); Scenario scenario = createScenarioWithDrtRouteFactory(config); ScenarioUtils.loadScenario(scenario); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeModule.java index 6176da047c8..a0cb1fc007c 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeModule.java @@ -20,13 +20,16 @@ package org.matsim.contrib.drt.run; +import com.google.inject.Key; +import com.google.inject.Singleton; +import com.google.inject.name.Names; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; import org.matsim.contrib.drt.fare.DrtFareHandler; import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingModule; +import org.matsim.contrib.drt.prebooking.analysis.PrebookingModeAnalysisModule; import org.matsim.contrib.drt.speedup.DrtSpeedUp; -import org.matsim.contrib.drt.stops.DefaultStopTimeCalculator; -import org.matsim.contrib.drt.stops.StopTimeCalculator; +import org.matsim.contrib.drt.stops.*; import org.matsim.contrib.dvrp.fleet.FleetModule; import org.matsim.contrib.dvrp.fleet.FleetSpecification; import org.matsim.contrib.dvrp.router.DvrpModeRoutingNetworkModule; @@ -39,10 +42,6 @@ import org.matsim.core.router.costcalculators.TravelDisutilityFactory; import org.matsim.core.router.util.TravelTime; -import com.google.inject.Key; -import com.google.inject.Singleton; -import com.google.inject.name.Names; - /** * @author michalm (Michal Maciejewski) */ @@ -77,17 +76,32 @@ public void install() { drtCfg.getDrtSpeedUpParams().ifPresent(drtSpeedUpParams -> { bindModal(DrtSpeedUp.class).toProvider(modalProvider( - getter -> new DrtSpeedUp(getMode(), drtSpeedUpParams, getConfig().controler(), + getter -> new DrtSpeedUp(getMode(), drtSpeedUpParams, getConfig().controller(), getter.get(Network.class), getter.getModal(FleetSpecification.class), getter.getModal(DrtEventSequenceCollector.class)))).asEagerSingleton(); addControlerListenerBinding().to(modalKey(DrtSpeedUp.class)); }); - + + bindModal(PassengerStopDurationProvider.class).toProvider(modalProvider(getter -> { + return StaticPassengerStopDurationProvider.of(drtCfg.stopDuration, 0.0); + })); + bindModal(DefaultStopTimeCalculator.class).toProvider(modalProvider(getter -> { return new DefaultStopTimeCalculator(drtCfg.stopDuration); })).in(Singleton.class); - - bindModal(StopTimeCalculator.class).to(modalKey(DefaultStopTimeCalculator.class)); + + if (drtCfg.getPrebookingParams().isEmpty()) { + bindModal(StopTimeCalculator.class).toProvider(modalProvider(getter -> { + return new DefaultStopTimeCalculator(drtCfg.stopDuration); + })).in(Singleton.class); + } else { + bindModal(StopTimeCalculator.class).toProvider(modalProvider(getter -> { + PassengerStopDurationProvider provider = getter.getModal(PassengerStopDurationProvider.class); + return new MinimumStopDurationAdapter(new PrebookingStopTimeCalculator(provider), drtCfg.stopDuration); + })); + + install(new PrebookingModeAnalysisModule(getMode())); + } install(new AdaptiveTravelTimeMatrixModule(drtCfg.mode)); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeQSimModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeQSimModule.java index ffbe7f67537..526c75d8020 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeQSimModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeQSimModule.java @@ -20,21 +20,29 @@ package org.matsim.contrib.drt.run; -import com.google.inject.Inject; -import com.google.inject.Provider; import org.matsim.contrib.drt.optimizer.DrtModeOptimizerQSimModule; import org.matsim.contrib.drt.passenger.DrtRequestCreator; +import org.matsim.contrib.drt.prebooking.PrebookingManager; +import org.matsim.contrib.drt.prebooking.PrebookingModeQSimModule; import org.matsim.contrib.drt.speedup.DrtSpeedUp; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.dvrp.passenger.AdvanceRequestProvider; import org.matsim.contrib.dvrp.passenger.DefaultPassengerRequestValidator; import org.matsim.contrib.dvrp.passenger.PassengerEngineQSimModule; +import org.matsim.contrib.dvrp.passenger.PassengerHandler; import org.matsim.contrib.dvrp.passenger.PassengerRequestCreator; import org.matsim.contrib.dvrp.passenger.PassengerRequestValidator; import org.matsim.contrib.dvrp.passenger.TeleportingPassengerEngine.TeleportedRouteCalculator; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; import org.matsim.contrib.dvrp.vrpagent.VrpAgentSourceQSimModule; +import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.qsim.AbstractQSimModule; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + /** * @author Michal Maciejewski (michalm) */ @@ -55,7 +63,7 @@ public DrtModeQSimModule(DrtConfigGroup drtCfg, AbstractQSimModule optimizerQSim @Override protected void configureQSim() { boolean teleportDrtUsers = drtCfg.getDrtSpeedUpParams().isPresent() && DrtSpeedUp.isTeleportDrtUsers( - drtCfg.getDrtSpeedUpParams().get(), getConfig().controler(), getIterationNumber()); + drtCfg.getDrtSpeedUpParams().get(), getConfig().controller(), getIterationNumber()); if (teleportDrtUsers) { install(new PassengerEngineQSimModule(getMode(), PassengerEngineQSimModule.PassengerEngineType.TELEPORTING)); @@ -68,6 +76,13 @@ protected void configureQSim() { install(optimizerQSimModule); } + if (drtCfg.getPrebookingParams().isPresent()) { + install(new PrebookingModeQSimModule(getMode(), drtCfg.getPrebookingParams().get())); + bindModal(AdvanceRequestProvider.class).to(modalKey(PrebookingManager.class)); + } else { + bindModal(AdvanceRequestProvider.class).toInstance(AdvanceRequestProvider.NONE); + } + bindModal(PassengerRequestValidator.class).to(DefaultPassengerRequestValidator.class).asEagerSingleton(); bindModal(PassengerRequestCreator.class).toProvider(new Provider() { @@ -79,5 +94,14 @@ public DrtRequestCreator get() { return new DrtRequestCreator(getMode(), events); } }).asEagerSingleton(); + + // this is not the actual selection which DynActionCreator is used, see + // DrtModeOptimizerQSimModule + bindModal(DrtActionCreator.class) + .toProvider(modalProvider(getter -> new DrtActionCreator(getter.getModal(PassengerHandler.class), + getter.getModal(VrpLegFactory.class)))) + .in(Singleton.class); // Not an eager binding, as taxi contrib doesn't need this implementation, but + // would search for VrpLegFactory which is provided in the + // DrtModeOptimizerModule if bound eagerly } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExample.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExample.java index 53da0c974db..8452181b4c2 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExample.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExample.java @@ -41,7 +41,7 @@ public class RunMultiModeDrtExample { public static void run(URL configUrl, boolean otfvis, int lastIteration) { Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); Controler controler = DrtControlerCreator.createControler(config, otfvis); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExample.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExample.java index 9ca1f9f3452..3ce549d1ac7 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExample.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExample.java @@ -35,8 +35,8 @@ public class RunOneSharedTaxiExample { public static void run(URL configUrl, boolean otfvis, int lastIteration) { Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); - config.controler().setWriteEventsInterval(lastIteration); + config.controller().setLastIteration(lastIteration); + config.controller().setWriteEventsInterval(lastIteration); DrtControlerCreator.createControler(config, otfvis).run(); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DefaultDrtStopTask.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DefaultDrtStopTask.java index 21cb658a010..6efeb3fff96 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DefaultDrtStopTask.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DefaultDrtStopTask.java @@ -84,4 +84,14 @@ public String toString() { .add("super", super.toString()) .toString(); } + + @Override + public void removePickupRequest(Id requestId) { + pickupRequests.remove(requestId); + } + + @Override + public void removeDropoffRequest(Id requestId) { + dropoffRequests.remove(requestId); + } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtStopTask.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtStopTask.java index f4e25dd79fd..3c2b5dd8351 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtStopTask.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtStopTask.java @@ -42,4 +42,8 @@ public interface DrtStopTask extends StayTask { void addDropoffRequest(AcceptedDrtRequest request); void addPickupRequest(AcceptedDrtRequest request); + + void removePickupRequest(Id requestId); + + void removeDropoffRequest(Id requestId); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactory.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactory.java index b7ee95be265..389094b222a 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactory.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactory.java @@ -21,6 +21,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; /** * @author michalm @@ -31,4 +32,6 @@ public interface DrtTaskFactory { DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link); DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link); + + DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactoryImpl.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactoryImpl.java index adb65f2d780..de227a74da4 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactoryImpl.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/schedule/DrtTaskFactoryImpl.java @@ -21,6 +21,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; /** * @author michalm @@ -40,4 +41,9 @@ public DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { return new DrtStayTask(beginTime, endTime, link); } + + @Override + public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return createStayTask(vehicle, beginTime, endTime ,link); + } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/DefaultRequestInsertionScheduler.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/DefaultRequestInsertionScheduler.java index 5f40c9a80f6..a8551b6ab9b 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/DefaultRequestInsertionScheduler.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/DefaultRequestInsertionScheduler.java @@ -22,32 +22,29 @@ import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.DRIVE; import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; -import java.util.Collections; import java.util.List; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.drt.optimizer.Waypoint; -import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; import org.matsim.contrib.drt.optimizer.insertion.InsertionWithDetourData; import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; -import org.matsim.contrib.drt.schedule.*; import org.matsim.contrib.drt.schedule.DrtDriveTask; import org.matsim.contrib.drt.schedule.DrtStayTask; import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.drt.schedule.DrtTaskBaseType; import org.matsim.contrib.drt.schedule.DrtTaskFactory; -import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; import org.matsim.contrib.drt.stops.StopTimeCalculator; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; import org.matsim.contrib.dvrp.path.VrpPaths; +import org.matsim.contrib.dvrp.schedule.DriveTask; import org.matsim.contrib.dvrp.schedule.Schedule; import org.matsim.contrib.dvrp.schedule.Schedule.ScheduleStatus; import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; import org.matsim.contrib.dvrp.schedule.StayTask; import org.matsim.contrib.dvrp.schedule.Task; -import org.matsim.contrib.dvrp.schedule.Task.TaskStatus; import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; import org.matsim.contrib.dvrp.util.LinkTimePair; import org.matsim.core.mobsim.framework.MobsimTimer; @@ -65,23 +62,25 @@ public class DefaultRequestInsertionScheduler implements RequestInsertionSchedul private final TravelTime travelTime; private final ScheduleTimingUpdater scheduleTimingUpdater; private final DrtTaskFactory taskFactory; - private StopTimeCalculator stopTimeCalculator; + private final StopTimeCalculator stopTimeCalculator; + private final boolean scheduleWaitBeforeDrive; public DefaultRequestInsertionScheduler(Fleet fleet, MobsimTimer timer, TravelTime travelTime, ScheduleTimingUpdater scheduleTimingUpdater, DrtTaskFactory taskFactory, - StopTimeCalculator stopTimeCalculator) { + StopTimeCalculator stopTimeCalculator, boolean scheduleWaitBeforeDrive) { this.timer = timer; this.travelTime = travelTime; this.scheduleTimingUpdater = scheduleTimingUpdater; this.taskFactory = taskFactory; this.stopTimeCalculator = stopTimeCalculator; + this.scheduleWaitBeforeDrive = scheduleWaitBeforeDrive; initSchedules(fleet); } private void initSchedules(Fleet fleet) { for (DvrpVehicle veh : fleet.getVehicles().values()) { veh.getSchedule() - .addTask(taskFactory.createStayTask(veh, veh.getServiceBeginTime(), veh.getServiceEndTime(), + .addTask(taskFactory.createInitialTask(veh, veh.getServiceBeginTime(), veh.getServiceEndTime(), veh.getStartLink())); } } @@ -95,18 +94,21 @@ public PickupDropoffTaskPair scheduleRequest(AcceptedDrtRequest request, Inserti var dropoffTask = insertDropoff(request, insertion, pickupTask); verifyTimes("Inconsistent dropoff arrival time", insertion.detourTimeInfo.dropoffDetourInfo.arrivalTime, dropoffTask.getBeginTime()); - + verifyTaskContinuity(insertion); + verifyConstraints(insertion); + verifyStructure(insertion.insertion.vehicleEntry.vehicle.getSchedule()); + return new PickupDropoffTaskPair(pickupTask, dropoffTask); } - + private void verifyTaskContinuity(InsertionWithDetourData insertion) { /* * During insertion of tasks the common sanity checks that happen when appending * to the schedule (next start time = previous end time) are not evaluated. This * method verifies that the timing remains intact after insertion. */ - + Schedule schedule = insertion.insertion.vehicleEntry.vehicle.getSchedule(); for (int i = 1; i < schedule.getTaskCount(); i++) { Task first = schedule.getTasks().get(i - 1); @@ -115,6 +117,50 @@ private void verifyTaskContinuity(InsertionWithDetourData insertion) { } } + private final boolean verifyConstraints = false; + + private void verifyConstraints(InsertionWithDetourData insertion) { + /* + * Verifies that no request constraints are violated after scheduling. This + * check is only valid when simulating under free-flow conditions. + */ + if (verifyConstraints) { + Schedule schedule = insertion.insertion.vehicleEntry.vehicle.getSchedule(); + + for (Task task : schedule.getTasks()) { + if (task instanceof DrtStopTask) { + DrtStopTask stopTask = (DrtStopTask) task; + + for (AcceptedDrtRequest request : stopTask.getPickupRequests().values()) { + Verify.verify(stopTask.getEndTime() <= request.getLatestStartTime()); + } + + for (AcceptedDrtRequest request : stopTask.getDropoffRequests().values()) { + Verify.verify(stopTask.getBeginTime() <= request.getLatestArrivalTime()); + } + } + } + } + } + + private void verifyStructure(Schedule schedule) { + boolean previousDrive = false; + + int startIndex = schedule.getStatus().equals(ScheduleStatus.STARTED) ? schedule.getCurrentTask().getTaskIdx() + : 0; + + for (int index = startIndex; index < schedule.getTaskCount(); index++) { + Task task = schedule.getTasks().get(index); + + if (task instanceof DriveTask) { + Verify.verify(!previousDrive); + previousDrive = true; + } else { + previousDrive = false; + } + } + } + private void verifyTimes(String messageStart, double timeFromInsertionData, double timeFromScheduler) { // The source of discrepancies is the first link travel time (as it should be taken into consideration // when a vehicle enters the traffic (a new drive task), but not when a vehicle is diverted (an ongoing drive task) @@ -145,26 +191,35 @@ private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetour beforePickupTask = currentTask; VrpPathWithTravelData vrpPath = VrpPaths.createPath(vehicleEntry.start.link, request.getFromLink(), vehicleEntry.start.time, detourData.detourToPickup, travelTime); - ((OnlineDriveTaskTracker)beforePickupTask.getTaskTracker()).divertPath(vrpPath); + + if (vrpPath.getArrivalTime() < request.getEarliestStartTime() && scheduleWaitBeforeDrive) { + // prebooking case: we need to wait right now + ((OnlineDriveTaskTracker)beforePickupTask.getTaskTracker()).divertPath(VrpPaths.createZeroLengthPathForDiversion(diversion)); + beforePickupTask = insertDriveWithWait(vehicleEntry.vehicle, currentTask, vrpPath, request.getEarliestStartTime()); + } else { + ((OnlineDriveTaskTracker)beforePickupTask.getTaskTracker()).divertPath(vrpPath); + // prebooking: may want to wait after continuing to drive + beforePickupTask = insertWait(vehicleEntry.vehicle, beforePickupTask, request.getEarliestStartTime()); + } } else { // too late for diversion if (request.getFromLink() != vehicleEntry.start.link) { // add a new drive task VrpPathWithTravelData vrpPath = VrpPaths.createPath(vehicleEntry.start.link, request.getFromLink(), vehicleEntry.start.time, detourData.detourToPickup, travelTime); - beforePickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(currentTask.getTaskIdx() + 1, beforePickupTask); - } else { // no need for a new drive task - beforePickupTask = currentTask; + // prebooking: may want to wait before or after driving + beforePickupTask = insertDriveWithWait(vehicleEntry.vehicle, currentTask, vrpPath, request.getEarliestStartTime()); + } else { // no need for a new drive task, but may want to wait until start of stop + beforePickupTask = insertWait(vehicleEntry.vehicle, currentTask, dropoffIdx); } } } else { // insert pickup after an existing stop/stay task - DrtStayTask stayTask = null; + StayTask stayTask = null; DrtStopTask stopTask = null; if (pickupIdx == 0) { if (scheduleStatus == ScheduleStatus.PLANNED) {// PLANNED schedule - stayTask = (DrtStayTask)schedule.getTasks().get(0); + stayTask = (StayTask)schedule.getTasks().get(0); stayTask.setEndTime(stayTask.getBeginTime());// could get later removed with ScheduleTimingUpdater } else if (STAY.isBaseTypeOf(currentTask)) { - stayTask = (DrtStayTask)currentTask; // ongoing stay task + stayTask = (StayTask)currentTask; // ongoing stay task if (stayTask.getEndTime() > now) { // stop stay task; a new stop/drive task can be inserted now stayTask.setEndTime(now); } @@ -175,30 +230,23 @@ private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetour stopTask = stops.get(pickupIdx - 1).task; // future stop task } - if (stopTask != null && request.getFromLink() == stopTask.getLink()) { // no detour; no new stop task + boolean canMergePickup = stopTask != null && request.getFromLink() == stopTask.getLink() + && stopTask.getEndTime() >= request.getEarliestStartTime(); + + if (canMergePickup) { // no detour; no new stop task // add pickup request to stop task stopTask.addPickupRequest(request); - + // potentially extend task stopTask.setEndTime(stopTimeCalculator.updateEndTimeForPickup(vehicleEntry.vehicle, stopTask, now, request.getRequest())); - /// ADDED - //// TODO this is copied, but has not been updated !!!!!!!!!!!!!!! // add drive from pickup if (pickupIdx == dropoffIdx) { // remove drive i->i+1 (if there is one) if (pickupIdx < stops.size()) {// there is at least one following stop DrtStopTask nextStopTask = stops.get(pickupIdx).task; - if (stopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx()) {// there must a drive task in - // between - throw new RuntimeException(); - } - if (stopTask.getTaskIdx() + 2 == nextStopTask.getTaskIdx()) {// there must a drive task in - // between - int driveTaskIdx = stopTask.getTaskIdx() + 1; - schedule.removeTask(schedule.getTasks().get(driveTaskIdx)); - } + removeBetween(schedule, stopTask, nextStopTask); } Link toLink = request.getToLink(); // pickup->dropoff @@ -206,7 +254,7 @@ private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetour VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getFromLink(), toLink, stopTask.getEndTime(), detourData.detourFromPickup, travelTime); Task driveFromPickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, - DrtDriveTask.TYPE); + DrtDriveTask.TYPE); // immediate drive to dropoff schedule.addTask(stopTask.getTaskIdx() + 1, driveFromPickupTask); // update timings @@ -226,37 +274,29 @@ private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetour // remove drive i->i+1 (if there is one) if (pickupIdx < stops.size()) {// there is at least one following stop DrtStopTask nextStopTask = stops.get(pickupIdx).task; - - // check: if there is at most one drive task in between - if (stayOrStopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx() // - && stayTask != null && stayTask.getTaskIdx() + 1 != nextStopTask.getTaskIdx()) { - throw new RuntimeException(); - } - if (stayOrStopTask.getTaskIdx() + 2 == nextStopTask.getTaskIdx()) { - // removing the drive task that is in between - int driveTaskIdx = stayOrStopTask.getTaskIdx() + 1; - schedule.removeTask(schedule.getTasks().get(driveTaskIdx)); - } + removeBetween(schedule, stayOrStopTask, nextStopTask); } - if (stayTask != null && request.getFromLink() == stayTask.getLink()) { + if (request.getFromLink() == stayOrStopTask.getLink()) { // the bus stays where it is - beforePickupTask = stayTask; + beforePickupTask = stayOrStopTask; + + // prebooking: but we may want to wait a bit if next stop is in a while + beforePickupTask = insertWait(vehicleEntry.vehicle, beforePickupTask, request.getEarliestStartTime()); } else {// add drive task to pickup location // insert drive i->pickup VrpPathWithTravelData vrpPath = VrpPaths.createPath(stayOrStopTask.getLink(), request.getFromLink(), stayOrStopTask.getEndTime(), detourData.detourToPickup, travelTime); - beforePickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(stayOrStopTask.getTaskIdx() + 1, beforePickupTask); + // we may want to wait before or after driving + beforePickupTask = insertDriveWithWait(vehicleEntry.vehicle, stayOrStopTask, vrpPath, request.getEarliestStartTime()); } } } // insert pickup stop task - double startTime = beforePickupTask.getEndTime(); int taskIdx = beforePickupTask.getTaskIdx() + 1; - double stopEndTime = stopTimeCalculator.initEndTimeForPickup(vehicleEntry.vehicle, startTime, request.getRequest()); - DrtStopTask pickupStopTask = taskFactory.createStopTask(vehicleEntry.vehicle, startTime, + double stopEndTime = stopTimeCalculator.initEndTimeForPickup(vehicleEntry.vehicle, beforePickupTask.getEndTime(), request.getRequest()); + DrtStopTask pickupStopTask = taskFactory.createStopTask(vehicleEntry.vehicle, beforePickupTask.getEndTime(), stopEndTime, request.getFromLink()); schedule.addTask(taskIdx, pickupStopTask); pickupStopTask.addPickupRequest(request); @@ -265,15 +305,29 @@ private DrtStopTask insertPickup(AcceptedDrtRequest request, InsertionWithDetour Link toLink = pickupIdx == dropoffIdx ? request.getToLink() // pickup->dropoff : stops.get(pickupIdx).task.getLink(); // pickup->i+1 - VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getFromLink(), toLink, pickupStopTask.getEndTime(), - detourData.detourFromPickup, travelTime); - Task driveFromPickupTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(taskIdx + 1, driveFromPickupTask); + double nextBeginTime = pickupIdx == dropoffIdx ? // + pickupStopTask.getEndTime() : // asap + stops.get(pickupIdx).task.getBeginTime(); // as planned + + if (request.getFromLink() == toLink) { + // prebooking case when we are already at the stop location, but next stop task happens in the future + Task afterPickupTask = insertWait(vehicleEntry.vehicle, pickupStopTask, nextBeginTime); + + scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, afterPickupTask.getTaskIdx() + 1, + afterPickupTask.getEndTime()); + } else { + VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getFromLink(), toLink, pickupStopTask.getEndTime(), + detourData.detourFromPickup, travelTime); + + // may want to wait now or before next stop task + Task afterPickupTask = insertDriveWithWait(vehicleEntry.vehicle, pickupStopTask, vrpPath, nextBeginTime); + + // update timings + // TODO should be enough to update the timeline only till dropoffIdx... + scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, afterPickupTask.getTaskIdx() + 1, + afterPickupTask.getEndTime()); + } - // update timings - // TODO should be enough to update the timeline only till dropoffIdx... - scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, taskIdx + 2, - driveFromPickupTask.getEndTime()); return pickupStopTask; } @@ -288,7 +342,7 @@ private DrtStopTask insertDropoff(AcceptedDrtRequest request, InsertionWithDetou int dropoffIdx = insertion.dropoff.index; var detourData = insertionWithDetourData.detourData; - Task driveToDropoffTask; + final Task driveToDropoffTask; if (pickupIdx == dropoffIdx) { // no drive to dropoff int pickupTaskIdx = pickupTask.getTaskIdx(); driveToDropoffTask = schedule.getTasks().get(pickupTaskIdx + 1); @@ -310,16 +364,13 @@ private DrtStopTask insertDropoff(AcceptedDrtRequest request, InsertionWithDetou // remove drive j->j+1 (if j is not the last stop) if (dropoffIdx < stops.size()) { DrtStopTask nextStopTask = stops.get(dropoffIdx).task; - if (stopTask.getTaskIdx() + 2 != nextStopTask.getTaskIdx()) { - throw new IllegalStateException(); - } - int driveTaskIdx = stopTask.getTaskIdx() + 1; - schedule.removeTask(schedule.getTasks().get(driveTaskIdx)); + removeBetween(schedule, stopTask, nextStopTask); } // insert drive i->dropoff VrpPathWithTravelData vrpPath = VrpPaths.createPath(stopTask.getLink(), request.getToLink(), stopTask.getEndTime(), detourData.detourToDropoff, travelTime); + // direct drive to dropoff (no waiting) driveToDropoffTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); schedule.addTask(stopTask.getTaskIdx() + 1, driveToDropoffTask); } @@ -353,13 +404,107 @@ private DrtStopTask insertDropoff(AcceptedDrtRequest request, InsertionWithDetou VrpPathWithTravelData vrpPath = VrpPaths.createPath(request.getToLink(), toLink, dropoffStopTask.getEndTime(), detourData.detourFromDropoff, travelTime); - Task driveFromDropoffTask = taskFactory.createDriveTask(vehicleEntry.vehicle, vrpPath, DrtDriveTask.TYPE); - schedule.addTask(taskIdx + 1, driveFromDropoffTask); - // update timings - scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, taskIdx + 2, - driveFromDropoffTask.getEndTime()); + if (toLink == request.getToLink()) { + // prebooking case: we stay, but may add some wait time until the next stop + Task afterDropoffTask = insertWait(vehicleEntry.vehicle, dropoffStopTask, + stops.get(dropoffIdx).task.getBeginTime()); + + scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, + afterDropoffTask.getTaskIdx() + 1, afterDropoffTask.getEndTime()); + } else { + // may want to wait here or after driving before starting next stop + Task afterDropoffTask = insertDriveWithWait(vehicleEntry.vehicle, dropoffStopTask, vrpPath, + stops.get(dropoffIdx).task.getBeginTime()); + + scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(vehicleEntry.vehicle, + afterDropoffTask.getTaskIdx() + 1, afterDropoffTask.getEndTime()); + } } return dropoffStopTask; } + + /** + * Removes drive and wait tasks between the startTask and the endTask + */ + private void removeBetween(Schedule schedule, Task startTask, Task endTask) { + Verify.verify(endTask.getTaskIdx() >= startTask.getTaskIdx()); + Verify.verify(endTask.getTaskIdx() <= startTask.getTaskIdx() + 3); + + int waitCount = 0; + int driveCount = 0; + + int removeCount = endTask.getTaskIdx() - startTask.getTaskIdx() - 1; + + for (int k = 0; k < removeCount; k++) { + Task task = schedule.getTasks().get(startTask.getTaskIdx() + 1); + + if (DrtTaskBaseType.DRIVE.isBaseTypeOf(task.getTaskType())) { + driveCount++; + } else if (DrtStayTask.TYPE.equals(task.getTaskType())) { + waitCount++; + } else { + throw new IllegalStateException("Invalid schedule structure: expected WAIT or DRIVE task"); + } + + schedule.removeTask(task); + } + + Verify.verify(waitCount <= 1); + Verify.verify(driveCount <= 1); + } + + private Task insertWait(DvrpVehicle vehicle, Task departureTask, double earliestNextStartTime) { + Schedule schedule = vehicle.getSchedule(); + + final Link waitLink; + if (departureTask instanceof StayTask) { + waitLink = ((StayTask) departureTask).getLink(); + } else if (departureTask instanceof DriveTask) { + waitLink = ((DriveTask) departureTask).getPath().getToLink(); + } else { + throw new IllegalStateException(); + } + + if (departureTask.getEndTime() < earliestNextStartTime) { + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, departureTask.getEndTime(), + earliestNextStartTime, waitLink); + schedule.addTask(departureTask.getTaskIdx() + 1, waitTask); + return waitTask; + } + + return departureTask; + } + + private Task insertDriveWithWait(DvrpVehicle vehicle, Task departureTask, VrpPathWithTravelData path, double latestArrivalTime) { + Schedule schedule = vehicle.getSchedule(); + + Task leadingTask = departureTask; + + if (scheduleWaitBeforeDrive) { + double driveDepartureTime = latestArrivalTime - path.getTravelTime(); + + if (driveDepartureTime > departureTask.getEndTime()) { + // makes sense to insert a wait task before departure + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, departureTask.getEndTime(), + driveDepartureTime, path.getFromLink()); + schedule.addTask(departureTask.getTaskIdx() + 1, waitTask); + + path = path.withDepartureTime(driveDepartureTime); + leadingTask = waitTask; + } + } + + Task driveTask = taskFactory.createDriveTask(vehicle, path, DrtDriveTask.TYPE); + schedule.addTask(leadingTask.getTaskIdx() + 1, driveTask); + + if (driveTask.getEndTime() < latestArrivalTime) { + DrtStayTask waitTask = taskFactory.createStayTask(vehicle, driveTask.getEndTime(), latestArrivalTime, + path.getToLink()); + schedule.addTask(driveTask.getTaskIdx() + 1, waitTask); + return waitTask; + } else { + return driveTask; + } + } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/EmptyVehicleRelocator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/EmptyVehicleRelocator.java index 57567dd5634..98a1994e268 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/EmptyVehicleRelocator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/scheduler/EmptyVehicleRelocator.java @@ -41,6 +41,7 @@ */ public class EmptyVehicleRelocator { public static final DrtTaskType RELOCATE_VEHICLE_TASK_TYPE = new DrtTaskType("RELOCATE", DRIVE); + public static final DrtTaskType RELOCATE_VEHICLE_TO_DEPOT_TASK_TYPE = new DrtTaskType("RELOCATE_TO_DEPOT", DRIVE); private final TravelTime travelTime; private final MobsimTimer timer; @@ -55,7 +56,7 @@ public EmptyVehicleRelocator(Network network, TravelTime travelTime, TravelDisut router = new SpeedyALTFactory().createPathCalculator(network, travelDisutility, travelTime); } - public void relocateVehicle(DvrpVehicle vehicle, Link link) { + public void relocateVehicle(DvrpVehicle vehicle, Link link, DrtTaskType relocationTaskType) { DrtStayTask currentTask = (DrtStayTask)vehicle.getSchedule().getCurrentTask(); Link currentLink = currentTask.getLink(); @@ -63,12 +64,12 @@ public void relocateVehicle(DvrpVehicle vehicle, Link link) { VrpPathWithTravelData path = VrpPaths.calcAndCreatePath(currentLink, link, timer.getTimeOfDay(), router, travelTime); if (path.getArrivalTime() < vehicle.getServiceEndTime()) { - relocateVehicleImpl(vehicle, path); + relocateVehicleImpl(vehicle, path, relocationTaskType); } } } - private void relocateVehicleImpl(DvrpVehicle vehicle, VrpPathWithTravelData vrpPath) { + private void relocateVehicleImpl(DvrpVehicle vehicle, VrpPathWithTravelData vrpPath, DrtTaskType relocationTaskType) { Schedule schedule = vehicle.getSchedule(); DrtStayTask stayTask = (DrtStayTask)schedule.getCurrentTask(); if (stayTask.getTaskIdx() != schedule.getTaskCount() - 1) { @@ -76,7 +77,7 @@ private void relocateVehicleImpl(DvrpVehicle vehicle, VrpPathWithTravelData vrpP } stayTask.setEndTime(vrpPath.getDepartureTime()); // finish STAY - schedule.addTask(taskFactory.createDriveTask(vehicle, vrpPath, RELOCATE_VEHICLE_TASK_TYPE)); // add RELOCATE + schedule.addTask(taskFactory.createDriveTask(vehicle, vrpPath, relocationTaskType)); // add RELOCATE // append STAY schedule.addTask(taskFactory.createStayTask(vehicle, vrpPath.getArrivalTime(), vehicle.getServiceEndTime(), vrpPath.getToLink())); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsControlerListener.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsControlerListener.java new file mode 100644 index 00000000000..a7a70f9e8ad --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsControlerListener.java @@ -0,0 +1,145 @@ +package org.matsim.contrib.drt.sharingmetrics; + +import com.google.inject.Inject; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartUtils; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer; +import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.core.config.Config; +import org.matsim.core.controler.MatsimServices; +import org.matsim.core.controler.events.IterationEndsEvent; +import org.matsim.core.controler.listener.IterationEndsListener; +import org.matsim.core.utils.io.IOUtils; + +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author nkuehnel / MOIA + */ +public class SharingMetricsControlerListener implements IterationEndsListener { + private final MatsimServices matsimServices; + + private final DrtConfigGroup drtConfigGroup; + private final SharingMetricsTracker sharingFactorTracker; + + private boolean headerWritten = false; + + private final String runId; + + private final String delimiter; + + private static final String notAvailableString = "NA"; + + + @Inject + public SharingMetricsControlerListener(Config config, + DrtConfigGroup drtConfigGroup, + SharingMetricsTracker sharingFactorTracker, + MatsimServices matsimServices) { + this.drtConfigGroup = drtConfigGroup; + this.sharingFactorTracker = sharingFactorTracker; + this.matsimServices = matsimServices; + runId = Optional.ofNullable(config.controller().getRunId()).orElse(notAvailableString); + this.delimiter = config.global().getDefaultDelimiter(); + + } + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + int createGraphsInterval = event.getServices().getConfig().controller().getCreateGraphsInterval(); + boolean createGraphs = createGraphsInterval >0 && event.getIteration() % createGraphsInterval == 0; + + Map, Double> sharingFactors = sharingFactorTracker.getSharingFactors(); + Map, Boolean> poolingRates = sharingFactorTracker.getPoolingRates(); + + writeAndPlotSharingMetrics( + sharingFactors, + poolingRates, + filename(event, "sharingFactors", ".png"), + filename(event, "poolingRates", ".png"), + filename(event, "sharingMetrics", ".csv"), + createGraphs); + + double nPooled = poolingRates.values().stream().filter(b -> b).count(); + double nTotal = poolingRates.values().size(); + double meanPoolingRate = nPooled / nTotal; + double meanSharingFactor = sharingFactors.values().stream().mapToDouble(d -> d).average().orElse(Double.NaN); + + writeIterationPoolingStats(meanPoolingRate + delimiter + meanSharingFactor + delimiter + nPooled +delimiter + nTotal, event.getIteration()); + } + + private void writeAndPlotSharingMetrics(Map, Double> sharingFactorByRequest, + Map, Boolean> rates, + String sharingFactors, + String poolingRates, + String csvFile, + boolean createGraphs) { + try (var bw = IOUtils.getBufferedWriter(csvFile)) { + bw.append(line("Request", "SharingFactor", "Pooled")); + + for (Map.Entry, Double> sharingFactorEntry : sharingFactorByRequest.entrySet()) { + bw.append(line(sharingFactorEntry.getKey(), sharingFactorEntry.getValue(),rates.get(sharingFactorEntry.getKey()))); + } + bw.flush(); + + if (createGraphs) { + final DefaultBoxAndWhiskerCategoryDataset sharingFactorDataset + = new DefaultBoxAndWhiskerCategoryDataset(); + + final DefaultBoxAndWhiskerCategoryDataset poolingRateDataset + = new DefaultBoxAndWhiskerCategoryDataset(); + + sharingFactorDataset.add(sharingFactorByRequest.values().stream().toList(), "", ""); + poolingRateDataset.add(rates.values().stream().toList(), "", ""); + + JFreeChart chartRides = ChartFactory.createBoxAndWhiskerChart("Sharing factor", "", "Factor", sharingFactorDataset, false); + JFreeChart chartPooling = ChartFactory.createBoxAndWhiskerChart("Pooling rate", "", "Rate", poolingRateDataset, false); + + ((BoxAndWhiskerRenderer) chartRides.getCategoryPlot().getRenderer()).setMeanVisible(false); + ((BoxAndWhiskerRenderer) chartPooling.getCategoryPlot().getRenderer()).setMeanVisible(false); + ChartUtils.writeChartAsPNG(new FileOutputStream(sharingFactors), chartRides, 1500, 1500); + ChartUtils.writeChartAsPNG(new FileOutputStream(poolingRates), chartPooling, 1500, 1500); + } + } catch ( + IOException e) { + throw new RuntimeException(e); + } + } + + private String filename(IterationEndsEvent event, String prefix, String extension) { + return matsimServices.getControlerIO() + .getIterationFilename(event.getIteration(), prefix + "_" + drtConfigGroup.getMode() + extension); + } + + private String line(Object... cells) { + return Arrays.stream(cells).map(Object::toString).collect(Collectors.joining(delimiter, "", "\n")); + } + + + private void writeIterationPoolingStats(String summarizePooling, int it) { + try (var bw = getAppendingBufferedWriter("drt_sharing_metrics", ".csv")) { + if (!headerWritten) { + headerWritten = true; + bw.write(line("runId", "iteration", "poolingRate", "sharingFactor", "nPooled", "nTotal")); + } + bw.write(runId + delimiter + it + delimiter + summarizePooling); + bw.newLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private BufferedWriter getAppendingBufferedWriter(String prefix, String extension) { + return IOUtils.getAppendingBufferedWriter(matsimServices.getControlerIO().getOutputFilename(prefix + "_" + drtConfigGroup.getMode() + extension)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsModule.java new file mode 100644 index 00000000000..4e1c4c31b09 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsModule.java @@ -0,0 +1,33 @@ +package org.matsim.contrib.drt.sharingmetrics; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.core.controler.MatsimServices; + +/** + * @author nkuehnel / MOIA + */ +public class SharingMetricsModule extends AbstractDvrpModeModule { + + private final DrtConfigGroup drtConfigGroup; + + public SharingMetricsModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.getMode()); + this.drtConfigGroup = drtConfigGroup; + } + + @Override + public void install() { + bindModal(SharingMetricsTracker.class).toProvider(modalProvider(getter -> + new SharingMetricsTracker())).asEagerSingleton(); + addEventHandlerBinding().to(modalKey(SharingMetricsTracker.class)); + bindModal(SharingMetricsControlerListener.class).toProvider(modalProvider(getter -> + new SharingMetricsControlerListener(getConfig(), drtConfigGroup, + getter.getModal(SharingMetricsTracker.class), + getter.get(MatsimServices.class)) + )); + addControlerListenerBinding().to(modalKey(SharingMetricsControlerListener.class)); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsTracker.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsTracker.java new file mode 100644 index 00000000000..47e8c415059 --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/sharingmetrics/SharingMetricsTracker.java @@ -0,0 +1,140 @@ +package org.matsim.contrib.drt.sharingmetrics; + +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.population.Person; +import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; +import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEventHandler; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEvent; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEvent; +import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEventHandler; +import org.matsim.core.gbl.Gbl; +import org.matsim.core.mobsim.framework.events.MobsimBeforeCleanupEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeCleanupListener; + +import java.util.*; + +/** + * @author nkuehnel / MOIA + */ +public class SharingMetricsTracker implements DrtRequestSubmittedEventHandler, PassengerPickedUpEventHandler, PassengerDroppedOffEventHandler, MobsimBeforeCleanupListener { + + private final static Logger logger = LogManager.getLogger(SharingMetricsTracker.class); + + + record Segment(double start, int occupancy) { + } + + private final Map, List>> occupancyByVehicle = new HashMap<>(); + + private final Map, List> segments = new HashMap<>(); + + private final Map, List>> knownGroups = new HashMap<>(); + + private final Map, Double> sharingFactors = new HashMap<>(); + private final Map, Boolean> poolingRate = new HashMap<>(); + + + public SharingMetricsTracker() { + } + + @Override + public void handleEvent(DrtRequestSubmittedEvent event) { + knownGroups.put(event.getRequestId(), new ArrayList<>(event.getPersonIds())); + } + + @Override + public void handleEvent(PassengerDroppedOffEvent event) { + + List> passengers = knownGroups.get(event.getRequestId()); + Gbl.assertIf(passengers.contains(event.getPersonId())); + passengers.remove(event.getPersonId()); + + if (passengers.isEmpty()) { + // all passengers of the group have been dropped off + knownGroups.remove(event.getRequestId()); + + List> occupancy = occupancyByVehicle.get(event.getVehicleId()); + occupancy.remove(event.getRequestId()); + for (Id request : occupancy) { + if(segments.containsKey(request)) { + segments.get(request).add(new Segment(event.getTime(), occupancy.size())); + } else { + logger.warn("Missing segment info for request " + request.toString()); + return; + } + } + + List finishedSegments = segments.remove(event.getRequestId()); + + double total = 0; + double portion = 0; + + boolean pooled = false; + + Segment last = finishedSegments.get(0); + if (last.occupancy > 1) { + pooled = true; + } + for (int i = 1; i < finishedSegments.size(); i++) { + Segment next = finishedSegments.get(i); + double duration = next.start - last.start; + total += duration; + portion += duration / last.occupancy; + last = next; + if (last.occupancy > 1) { + pooled = true; + } + } + + double duration = event.getTime() - last.start; + total += duration; + portion += duration / last.occupancy; + + double sharingFactor = total / portion; + sharingFactors.put(event.getRequestId(), sharingFactor); + poolingRate.put(event.getRequestId(), pooled); + } + } + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + List> occupancy = occupancyByVehicle.computeIfAbsent(event.getVehicleId(), vehicleId -> new ArrayList<>()); + if (occupancy.contains(event.getRequestId())) { + if (knownGroups.get(event.getRequestId()).size() > 1) { + //group request, skip for additional persons + return; + } else { + throw new RuntimeException("Single rider request picked up twice!"); + } + } else { + occupancy.add(event.getRequestId()); + occupancy.forEach( + request -> segments + .computeIfAbsent(request, requestId -> new ArrayList<>()) + .add(new Segment(event.getTime(), occupancy.size())) + ); + } + } + + @Override + public void notifyMobsimBeforeCleanup(MobsimBeforeCleanupEvent e) { + occupancyByVehicle.clear(); + segments.clear(); + poolingRate.clear(); + sharingFactors.clear(); + knownGroups.clear(); + } + + public Map, Double> getSharingFactors() { + return Collections.unmodifiableMap(sharingFactors); + } + + public Map, Boolean> getPoolingRates() { + return Collections.unmodifiableMap(poolingRate); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtSpeedUp.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtSpeedUp.java index 13da140a338..5ad8dd776af 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtSpeedUp.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtSpeedUp.java @@ -27,14 +27,16 @@ import org.apache.commons.math3.stat.regression.SimpleRegression; 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.network.Link; import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.common.util.DistanceUtils; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; import org.matsim.contrib.drt.speedup.DrtSpeedUpParams.WaitingTimeUpdateDuringSpeedUp; import org.matsim.contrib.dvrp.fleet.FleetSpecification; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.controler.events.IterationStartsEvent; import org.matsim.core.controler.listener.IterationEndsListener; @@ -49,7 +51,7 @@ public final class DrtSpeedUp implements IterationStartsListener, IterationEndsListener { private static final Logger log = LogManager.getLogger(DrtSpeedUp.class); - public static boolean isTeleportDrtUsers(DrtSpeedUpParams drtSpeedUpParams, ControlerConfigGroup controlerConfig, + public static boolean isTeleportDrtUsers(DrtSpeedUpParams drtSpeedUpParams, ControllerConfigGroup controlerConfig, int iteration) { int lastIteration = controlerConfig.getLastIteration(); if (iteration < drtSpeedUpParams.fractionOfIterationsSwitchOn * lastIteration @@ -63,7 +65,7 @@ public static boolean isTeleportDrtUsers(DrtSpeedUpParams drtSpeedUpParams, Cont private final String mode; private final DrtSpeedUpParams drtSpeedUpParams; - private final ControlerConfigGroup controlerConfig; + private final ControllerConfigGroup controlerConfig; private final Network network; private final FleetSpecification fleetSpecification; private final DrtEventSequenceCollector drtEventSequenceCollector; @@ -76,7 +78,7 @@ public static boolean isTeleportDrtUsers(DrtSpeedUpParams drtSpeedUpParams, Cont private double currentAvgWaitingTime; private double currentAvgInVehicleBeelineSpeed; - public DrtSpeedUp(String mode, DrtSpeedUpParams drtSpeedUpParams, ControlerConfigGroup controlerConfig, + public DrtSpeedUp(String mode, DrtSpeedUpParams drtSpeedUpParams, ControllerConfigGroup controlerConfig, Network network, FleetSpecification fleetSpecification, DrtEventSequenceCollector drtEventSequenceCollector) { this.mode = mode; @@ -192,18 +194,24 @@ private SimulatedTripStats computeSimulatedTripStats() { continue;//skip incomplete sequences } DrtRequestSubmittedEvent submittedEvent = sequence.getSubmitted(); - Link depLink = network.getLinks().get(submittedEvent.getFromLinkId()); Link arrLink = network.getLinks().get(submittedEvent.getToLinkId()); double beelineDistance = DistanceUtils.calculateDistance(depLink.getToNode(), arrLink.getToNode()); - double pickupTime = sequence.getPickedUp().get().getTime(); - double waitTime = pickupTime - sequence.getSubmitted().getTime(); - double rideTime = sequence.getDroppedOff().get().getTime() - pickupTime; - - //TODO I would map unshared_ride_time to rideTime -- should be more precise - meanInVehicleBeelineSpeed.increment(beelineDistance / rideTime); - meanWaitTime.increment(waitTime); + for (Id personId : submittedEvent.getPersonIds()) { + if(sequence.getPersonEvents().containsKey(personId)) { + DrtEventSequenceCollector.EventSequence.PersonEvents personEvents = sequence.getPersonEvents().get(personId); + if(personEvents.getPickedUp().isPresent() && personEvents.getDroppedOff().isPresent()) { + double pickupTime = personEvents.getPickedUp().get().getTime(); + double waitTime = pickupTime - sequence.getSubmitted().getTime(); + double rideTime = personEvents.getDroppedOff().get().getTime() - pickupTime; + + //TODO I would map unshared_ride_time to rideTime -- should be more precise + meanInVehicleBeelineSpeed.increment(beelineDistance / rideTime); + meanWaitTime.increment(waitTime); + } + } + } } int count = (int)meanWaitTime.getN(); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java index 7935a2403e8..eca53f0c0d7 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java @@ -40,6 +40,12 @@ public class DrtTeleportedRouteCalculator implements TeleportedRouteCalculator { this.averageInVehicleBeelineSpeed = averageInVehicleBeelineSpeed; } + // TODO: from discussion from michal and rakow + // speedup is currently using very simple and not exchangeable estimators + // it could be possible to integrate the drt estimators used by the informed mode-choice + // this router should probably not use the beeline distance but the direct travel route + // speed-up would still be significant (oct'23) + @Override public Route calculateRoute(PassengerRequest request) { Link startLink = request.getFromLink(); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/vrpagent/DrtActionCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/vrpagent/DrtActionCreator.java index 1d57080e521..bb87604c123 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/vrpagent/DrtActionCreator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/vrpagent/DrtActionCreator.java @@ -25,15 +25,12 @@ import org.matsim.contrib.drt.schedule.DrtStopTask; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.passenger.PassengerHandler; -import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.schedule.Task; -import org.matsim.contrib.dvrp.tracker.OnlineTrackerListener; import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory; import org.matsim.contrib.dynagent.DynAction; import org.matsim.contrib.dynagent.DynAgent; import org.matsim.contrib.dynagent.IdleDynActivity; -import org.matsim.core.mobsim.framework.MobsimTimer; /** * @author michalm @@ -44,11 +41,6 @@ public class DrtActionCreator implements VrpAgentLogic.DynActionCreator { private final PassengerHandler passengerHandler; private final VrpLegFactory legFactory; - public DrtActionCreator(PassengerHandler passengerHandler, MobsimTimer timer, DvrpConfigGroup dvrpCfg) { - this(passengerHandler, v -> VrpLegFactory.createWithOnlineTracker(dvrpCfg.mobsimMode, v, - OnlineTrackerListener.NO_LISTENER, timer)); - } - public DrtActionCreator(PassengerHandler passengerHandler, VrpLegFactory legFactory) { this.passengerHandler = passengerHandler; this.legFactory = legFactory; diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java index 110d6bc9852..0d73adba5c6 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtGridUtilsTest.java @@ -4,7 +4,7 @@ import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.prep.PreparedGeometry; @@ -18,7 +18,7 @@ public class DrtGridUtilsTest { @Test - public void test() { + void test() { Network network = createNetwork(); Map grid = DrtGridUtils.createGridFromNetwork(network, 100); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java index af5b0be555e..a49cc10a3d0 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalSystemTest.java @@ -21,11 +21,11 @@ package org.matsim.contrib.drt.analysis.zonal; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.matsim.contrib.drt.analysis.zonal.DrtGridUtilsTest.createNetwork; import static org.matsim.contrib.drt.analysis.zonal.DrtZonalSystem.createFromPreparedGeometries; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Polygon; @@ -44,21 +44,21 @@ public class DrtZonalSystemTest { @Test - public void test_cellSize100() { + void test_cellSize100() { DrtZonalSystem drtZonalSystem = createFromPreparedGeometries(createNetwork(), DrtGridUtils.createGridFromNetwork(createNetwork(), 100)); assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).getId()).isEqualTo("10"); } @Test - public void test_cellSize700() { + void test_cellSize700() { DrtZonalSystem drtZonalSystem = createFromPreparedGeometries(createNetwork(), DrtGridUtils.createGridFromNetwork(createNetwork(), 700)); assertThat(drtZonalSystem.getZoneForLinkId(Id.createLinkId("ab")).getId()).isEqualTo("2"); } @Test - public void test_gridWithinServiceArea(){ + void test_gridWithinServiceArea(){ Coordinate min = new Coordinate(-500, 500); Coordinate max = new Coordinate(1500, 1500); List serviceArea = createServiceArea(min,max); @@ -74,7 +74,7 @@ public void test_gridWithinServiceArea(){ } @Test - public void test_noZonesWithoutLinks(){ + void test_noZonesWithoutLinks(){ Coordinate min = new Coordinate(1500, 1500); Coordinate max = new Coordinate(2500, 2500); List serviceArea = createServiceArea(min,max); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java index 3251579a09e..fa38b72749b 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/analysis/zonal/RandomDrtZoneTargetLinkSelectorTest.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.function.IntUnaryOperator; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.testcases.fakes.FakeLink; @@ -44,7 +44,7 @@ public class RandomDrtZoneTargetLinkSelectorTest { private final Link link3 = new FakeLink(Id.createLinkId("3")); @Test - public void testSelectTargetLink_fourLinks() { + void testSelectTargetLink_fourLinks() { DrtZone zone = DrtZone.createDummyZone("zone", List.of(link0, link1, link2, link3), null); //fake random sequence diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/config/ConfigBehaviorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/config/ConfigBehaviorTest.java index ff70b6e4808..003b183046c 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/config/ConfigBehaviorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/config/ConfigBehaviorTest.java @@ -2,9 +2,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; @@ -16,11 +16,11 @@ public class ConfigBehaviorTest{ private static final Logger log = LogManager.getLogger(ConfigBehaviorTest.class ); - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; - @Test - public final void testMaterializeAfterReadParameterSets() { + @Test + final void testMaterializeAfterReadParameterSets() { { // generate a test config that sets two values away from their defaults, and write it to file: Config config = ConfigUtils.createConfig(); @@ -46,13 +46,13 @@ public final void testMaterializeAfterReadParameterSets() { MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule( config, MultiModeDrtConfigGroup.class ); // this should have two config groups here, but does not: - Assert.assertEquals( 2, multiModeDrtConfigGroup.getModalElements().size() ); + Assertions.assertEquals( 2, multiModeDrtConfigGroup.getModalElements().size() ); // check if you are getting back the values from the config file: for( DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements() ){ log.info( drtConfigGroup.getMode() ); if ( ! ( drtConfigGroup.getMode().equals( "drt20" ) || drtConfigGroup.getMode().equals( "drt20000" ) ) ) { - Assert.fail(); + Assertions.fail(); } } @@ -60,8 +60,8 @@ public final void testMaterializeAfterReadParameterSets() { } } - @Test - public final void testMaterializeAfterReadStandardParams() { + @Test + final void testMaterializeAfterReadStandardParams() { { // generate a test config that sets two values away from their defaults, and write it to file: Config config = ConfigUtils.createConfig(); @@ -79,8 +79,8 @@ public final void testMaterializeAfterReadStandardParams() { DvrpConfigGroup dvrpConfig = ConfigUtils.addOrGetModule( config, DvrpConfigGroup.class ); // check if you are getting back the values from the config file: - Assert.assertEquals( 1.23, dvrpConfig.travelTimeEstimationAlpha, Double.MIN_VALUE ); - Assert.assertEquals( 4.56, dvrpConfig.travelTimeEstimationBeta, Double.MIN_VALUE ); + Assertions.assertEquals( 1.23, dvrpConfig.travelTimeEstimationAlpha, Double.MIN_VALUE ); + Assertions.assertEquals( 4.56, dvrpConfig.travelTimeEstimationBeta, Double.MIN_VALUE ); } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/fare/DrtFareHandlerTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/fare/DrtFareHandlerTest.java index 490eea446df..35e41f5d018 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/fare/DrtFareHandlerTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/fare/DrtFareHandlerTest.java @@ -21,8 +21,8 @@ package org.matsim.contrib.drt.fare; import org.apache.commons.lang3.mutable.MutableDouble; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.PersonMoneyEvent; import org.matsim.api.core.v01.events.handler.PersonMoneyEventHandler; @@ -31,6 +31,8 @@ import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEvent; import org.matsim.core.events.ParallelEventsManager; +import java.util.List; + /** * @author jbischoff */ @@ -40,7 +42,7 @@ public class DrtFareHandlerTest { * Test method for {@link DrtFareHandler}. */ @Test - public void testDrtFareHandler() { + void testDrtFareHandler() { String mode = "mode_0"; DrtFareParams fareParams = new DrtFareParams(); fareParams.baseFare = 1; @@ -69,19 +71,19 @@ public void reset(int iteration) { var personId = Id.createPersonId("p1"); { var requestId = Id.create(0, Request.class); - events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId, personId, Id.createLinkId("12"), - Id.createLinkId("23"), 240, 1000, 0.0, 0.0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId, List.of(personId), Id.createLinkId("12"), + Id.createLinkId("23"), 240, 1000, 0.0, 0.0, 0.0)); events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId, personId, null)); events.flush(); //fare: 1 (daily fee) + 1 (distance()+ 1 basefare + 1 (time) - Assert.assertEquals(-4.0, fare.getValue(), 0); + Assertions.assertEquals(-4.0, fare.getValue(), 0); } { // test minFarePerTrip var requestId = Id.create(1, Request.class); - events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId, personId, Id.createLinkId("45"), - Id.createLinkId("56"), 24, 100, 0.0, 0.0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId, List.of(personId), Id.createLinkId("45"), + Id.createLinkId("56"), 24, 100, 0.0, 0.0, 0.0)); events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId, personId, null)); events.finishProcessing(); @@ -89,7 +91,7 @@ public void reset(int iteration) { * fare new trip: 0 (daily fee already paid) + 0.1 (distance)+ 1 basefare + 0.1 (time) = 1.2 < minFarePerTrip = 1.5 * --> new total fare: 4 (previous trip) + 1.5 (minFarePerTrip for new trip) = 5.5 */ - Assert.assertEquals(-5.5, fare.getValue(), 0); + Assertions.assertEquals(-5.5, fare.getValue(), 0); } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/DrtRequestInsertionRetryQueueTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/DrtRequestInsertionRetryQueueTest.java index 208e652d1dc..8989aa90855 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/DrtRequestInsertionRetryQueueTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/DrtRequestInsertionRetryQueueTest.java @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.dvrp.optimizer.Request; @@ -43,21 +43,21 @@ public class DrtRequestInsertionRetryQueueTest { .build(); @Test - public void maxRequestAgeZero_noRetry() { + void maxRequestAgeZero_noRetry() { var queue = new DrtRequestInsertionRetryQueue(params(10, 0)); assertThat(queue.tryAddFailedRequest(request, SUBMISSION_TIME)).isFalse(); assertThat(queue.getRequestsToRetryNow(9999)).isEmpty(); } @Test - public void requestMaxAgeExceeded_noRetry() { + void requestMaxAgeExceeded_noRetry() { var queue = new DrtRequestInsertionRetryQueue(params(2, 10)); assertThat(queue.tryAddFailedRequest(request, SUBMISSION_TIME + 10)).isFalse(); assertThat(queue.getRequestsToRetryNow(9999)).isEmpty(); } @Test - public void requestMaxAgeNotExceeded_retry() { + void requestMaxAgeNotExceeded_retry() { var queue = new DrtRequestInsertionRetryQueue(params(2, 10)); assertThat(queue.tryAddFailedRequest(request, SUBMISSION_TIME)).isTrue(); @@ -77,7 +77,7 @@ public void requestMaxAgeNotExceeded_retry() { } @Test - public void requestMaxAgeNotExceeded_lateRetry() { + void requestMaxAgeNotExceeded_lateRetry() { var queue = new DrtRequestInsertionRetryQueue(params(2, 10)); assertThat(queue.tryAddFailedRequest(request, SUBMISSION_TIME)).isTrue(); @@ -91,7 +91,7 @@ public void requestMaxAgeNotExceeded_lateRetry() { } @Test - public void queueOrderMaintained() { + void queueOrderMaintained() { var queue = new DrtRequestInsertionRetryQueue(params(2, 10)); assertThat(queue.tryAddFailedRequest(DrtRequest.newBuilder(request).id(Id.create("a", Request.class)).build(), SUBMISSION_TIME)).isTrue(); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImplTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImplTest.java index 79bde9d12c8..e74e3334a71 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImplTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/VehicleDataEntryFactoryImplTest.java @@ -22,11 +22,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.matsim.contrib.drt.optimizer.VehicleDataEntryFactoryImpl.computeSlackTimes; -import static org.matsim.contrib.drt.optimizer.Waypoint.Stop; -import org.junit.Test; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.optimizer.Waypoint.Stop; import org.matsim.contrib.drt.schedule.DefaultDrtStopTask; import org.matsim.contrib.drt.schedule.DrtStayTask; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; @@ -47,48 +50,77 @@ public class VehicleDataEntryFactoryImplTest { private final Stop stop1 = stop(300, 340, 400, 430); @Test - public void computeSlackTimes_withStops() { + void computeSlackTimes_withStops() { + final List precedingStayTimes = Arrays.asList(0.0, 0.0); + //final stay task not started - vehicle slack time is 50 - assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] { stop0, stop1 }, null)).containsExactly(20, 20, 30, 50); + assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(20, 20, 30, 50); //final stay task not started - vehicle slack time is 25 and limits the slack times at stop1 - assertThat(computeSlackTimes(vehicle(500, 475), 100, new Stop[] { stop0, stop1 }, null)).containsExactly(20, 20, 25, 25); + assertThat(computeSlackTimes(vehicle(500, 475), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(20, 20, 25, 25); //final stay task not started - vehicle slack time is 10 and limits the slack times at all stops - assertThat(computeSlackTimes(vehicle(500, 490), 100, new Stop[] { stop0, stop1 }, null)).containsExactly(10, 10, 10, 10); + assertThat(computeSlackTimes(vehicle(500, 490), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(10, 10, 10, 10); } @Test - public void computeSlackTimes_withoutStops() { + void computeSlackTimes_withoutStops() { + final List precedingStayTimes = Arrays.asList(); + //final stay task not started yet - vehicle slack time is 10 - assertThat(computeSlackTimes(vehicle(500, 490), 485, new Stop[] {}, null)).containsExactly(10, 10); + assertThat(computeSlackTimes(vehicle(500, 490), 485, new Stop[] {}, null, precedingStayTimes)).containsExactly(10, 10); //final stay task just started - vehicle slack time is 10 - assertThat(computeSlackTimes(vehicle(500, 490), 490, new Stop[] {}, null)).containsExactly(10, 10); + assertThat(computeSlackTimes(vehicle(500, 490), 490, new Stop[] {}, null, precedingStayTimes)).containsExactly(10, 10); //final stay task half completed - vehicle slack time is 5 - assertThat(computeSlackTimes(vehicle(500, 490), 495, new Stop[] {}, null)).containsExactly(5, 5); + assertThat(computeSlackTimes(vehicle(500, 490), 495, new Stop[] {}, null, precedingStayTimes)).containsExactly(5, 5); //final stay task just completed - vehicle slack time is 0 - assertThat(computeSlackTimes(vehicle(500, 490), 500, new Stop[] {}, null)).containsExactly(0, 0); + assertThat(computeSlackTimes(vehicle(500, 490), 500, new Stop[] {}, null, precedingStayTimes)).containsExactly(0, 0); //final stay task started, but delayed - vehicle slack time is 0 - assertThat(computeSlackTimes(vehicle(500, 510), 510, new Stop[] {}, null)).containsExactly(0, 0); + assertThat(computeSlackTimes(vehicle(500, 510), 510, new Stop[] {}, null, precedingStayTimes)).containsExactly(0, 0); //final stay task planned after vehicle end time - vehicle slack time is 0s - assertThat(computeSlackTimes(vehicle(500, 510), 300, new Stop[] {}, null)).containsExactly(0, 0); + assertThat(computeSlackTimes(vehicle(500, 510), 300, new Stop[] {}, null, precedingStayTimes)).containsExactly(0, 0); } - + @Test - public void computeSlackTimes_withStart() { + void computeSlackTimes_withStart() { + final List noPrecedingStayTimes = Arrays.asList(); + final List onePrecedingStayTime = Arrays.asList(0.0); + //start without stop - assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] {}, stop0)).containsExactly(30, 50); + assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] {}, stop0, noPrecedingStayTimes)).containsExactly(30, 50); //start without stop - assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] {}, stop1)).containsExactly(30, 50); + assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] {}, stop1, noPrecedingStayTimes)).containsExactly(30, 50); //start with stop - assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] { stop1 }, stop0)).containsExactly(30, 30, 50); + assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] { stop1 }, stop0, onePrecedingStayTime)).containsExactly(30, 30, 50); + } + + @Test + void computeSlackTimes_withPrecedingStayTimes() { + final List precedingStayTimes = Arrays.asList( // + 0.0, // + 33.0 // second stop is a prebooked pickup, so slack for insertion after first stop is longer + ); + + // note that these examples are naively adapted from computeSlackTimes_withStops + // in practice the slack would never pass the service end time slack (ie the + // last value in the list) if the preceding insertions were done correctly and + // there was no congestion + + //final stay task not started - vehicle slack time is 50 + assertThat(computeSlackTimes(vehicle(500, 450), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(20, 20, 63, 50); + + //final stay task not started - vehicle slack time is 25 and limits the slack times at stop1 + assertThat(computeSlackTimes(vehicle(500, 475), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(20, 20, 58, 25); + + //final stay task not started - vehicle slack time is 10 and limits the slack times at all stops + assertThat(computeSlackTimes(vehicle(500, 490), 100, new Stop[] { stop0, stop1 }, null, precedingStayTimes)).containsExactly(20, 20, 43, 10); } private Stop stop(double beginTime, double latestArrivalTime, double endTime, double latestDepartureTime) { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/BestInsertionFinderTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/BestInsertionFinderTest.java index 14b8c359ec5..bf42ede62a7 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/BestInsertionFinderTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/BestInsertionFinderTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; import java.util.Optional; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.drt.passenger.DrtRequest; @@ -48,19 +48,19 @@ public class BestInsertionFinderTest { private final BestInsertionFinder bestInsertionFinder = new BestInsertionFinder(insertionCostCalculator); @Test - public void noInsertions_empty() { + void noInsertions_empty() { assertThat(findBestInsertion()).isEmpty(); } @Test - public void noFeasibleInsertions_empty() { + void noFeasibleInsertions_empty() { when(insertionCostCalculator.calculate(eq(request), any(), any())).thenReturn(INFEASIBLE_SOLUTION_COST); assertThat(findBestInsertion(insertion("v1", 0, 0), insertion("v1", 0, 1))).isEmpty(); } @Test - public void oneFeasibleInsertion_oneInfeasibleInsertion_chooseFeasible() { + void oneFeasibleInsertion_oneInfeasibleInsertion_chooseFeasible() { var feasibleInsertion = insertion("v1", 0, 0); whenInsertionThenCost(feasibleInsertion, 12345); @@ -72,7 +72,7 @@ public void oneFeasibleInsertion_oneInfeasibleInsertion_chooseFeasible() { } @Test - public void twoFeasibleInsertions_chooseBetter() { + void twoFeasibleInsertions_chooseBetter() { var insertion1 = insertion("v1", 0, 0); whenInsertionThenCost(insertion1, 123); @@ -84,7 +84,7 @@ public void twoFeasibleInsertions_chooseBetter() { } @Test - public void twoEqualInsertions_chooseLowerVehicleId() { + void twoEqualInsertions_chooseLowerVehicleId() { var insertion1 = insertion("v1", 0, 0); whenInsertionThenCost(insertion1, 123); @@ -96,7 +96,7 @@ public void twoEqualInsertions_chooseLowerVehicleId() { } @Test - public void twoEqualInsertions_sameVehicle_chooseLowerPickupIdx() { + void twoEqualInsertions_sameVehicle_chooseLowerPickupIdx() { var insertion1 = insertion("v1", 0, 1); whenInsertionThenCost(insertion1, 123); @@ -108,7 +108,7 @@ public void twoEqualInsertions_sameVehicle_chooseLowerPickupIdx() { } @Test - public void twoEqualInsertions_sameVehicle_samePickupIdx_chooseLowerDropoffIdx() { + void twoEqualInsertions_sameVehicle_samePickupIdx_chooseLowerDropoffIdx() { var insertion1 = insertion("v1", 0, 0); whenInsertionThenCost(insertion1, 123); @@ -132,7 +132,7 @@ private void whenInsertionThenCost(InsertionWithDetourData insertion, double cos private InsertionWithDetourData insertion(String vehicleId, int pickupIdx, int dropoffIdx) { var vehicle = mock(DvrpVehicle.class); when(vehicle.getId()).thenReturn(Id.create(vehicleId, DvrpVehicle.class)); - var vehicleEntry = new VehicleEntry(vehicle, null, null, null, 0); + var vehicleEntry = new VehicleEntry(vehicle, null, null, null, null, 0); var pickupInsertion = new InsertionGenerator.InsertionPoint(pickupIdx, null, null, null); var dropoffInsertion = new InsertionGenerator.InsertionPoint(dropoffIdx, null, null, null); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/CostCalculationStrategyTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/CostCalculationStrategyTest.java index 569f4e7d708..cc52e2a3dbf 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/CostCalculationStrategyTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/CostCalculationStrategyTest.java @@ -27,7 +27,7 @@ import static org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DropoffDetourInfo; import static org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.PickupDetourInfo; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DetourTimeInfo; import org.matsim.contrib.drt.passenger.DrtRequest; @@ -36,20 +36,20 @@ */ public class CostCalculationStrategyTest { @Test - public void RejectSoftConstraintViolations_tooLongWaitTime() { + void RejectSoftConstraintViolations_tooLongWaitTime() { assertRejectSoftConstraintViolations(10, 9999, new DetourTimeInfo(new PickupDetourInfo(11, 0), new DropoffDetourInfo(22, 0)), INFEASIBLE_SOLUTION_COST); } @Test - public void RejectSoftConstraintViolations_tooLongTravelTime() { + void RejectSoftConstraintViolations_tooLongTravelTime() { assertRejectSoftConstraintViolations(9999, 10, new DetourTimeInfo(new PickupDetourInfo(0, 0), new DropoffDetourInfo(11, 0)), INFEASIBLE_SOLUTION_COST); } @Test - public void RejectSoftConstraintViolations_allConstraintSatisfied() { + void RejectSoftConstraintViolations_allConstraintSatisfied() { assertRejectSoftConstraintViolations(9999, 9999, new DetourTimeInfo(new PickupDetourInfo(11, 33), new DropoffDetourInfo(22, 44)), 33 + 44); } @@ -65,21 +65,21 @@ private void assertRejectSoftConstraintViolations(double latestStartTime, double } @Test - public void DiscourageSoftConstraintViolations_tooLongWaitTime() { + void DiscourageSoftConstraintViolations_tooLongWaitTime() { assertDiscourageSoftConstraintViolations(10, 9999, new DetourTimeInfo(new PickupDetourInfo(11, 0), new DropoffDetourInfo(22, 0)), MAX_WAIT_TIME_VIOLATION_PENALTY); } @Test - public void DiscourageSoftConstraintViolations_tooLongTravelTime() { + void DiscourageSoftConstraintViolations_tooLongTravelTime() { assertDiscourageSoftConstraintViolations(9999, 10, new DetourTimeInfo(new PickupDetourInfo(0, 0), new DropoffDetourInfo(11, 0)), MAX_TRAVEL_TIME_VIOLATION_PENALTY); } @Test - public void DiscourageSoftConstraintViolations_allConstraintSatisfied() { + void DiscourageSoftConstraintViolations_allConstraintSatisfied() { assertDiscourageSoftConstraintViolations(9999, 9999, new DetourTimeInfo(new PickupDetourInfo(11, 33), new DropoffDetourInfo(22, 44)), 33 + 44); } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserterTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserterTest.java index dcdc662f335..58637acaddc 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserterTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DefaultUnplannedRequestInserterTest.java @@ -23,16 +23,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.matsim.contrib.drt.optimizer.insertion.DefaultUnplannedRequestInserter.NO_INSERTION_FOUND_CAUSE; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; +import java.util.*; import org.apache.commons.lang3.mutable.MutableInt; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.network.Link; @@ -45,6 +47,7 @@ import org.matsim.contrib.drt.schedule.DefaultDrtStopTask; import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler; import org.matsim.contrib.drt.scheduler.RequestInsertionScheduler.PickupDropoffTaskPair; +import org.matsim.contrib.drt.stops.StaticPassengerStopDurationProvider; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.optimizer.Request; @@ -67,11 +70,11 @@ public class DefaultUnplannedRequestInserterTest { private final EventsManager eventsManager = mock(EventsManager.class); - @Rule - public final ForkJoinPoolTestRule rule = new ForkJoinPoolTestRule(); + @RegisterExtension + public final ForkJoinPoolExtension forkJoinPoolExtension = new ForkJoinPoolExtension(); @Test - public void nothingToSchedule() { + void nothingToSchedule() { var fleet = fleet(vehicle("1")); var unplannedRequests = requests(); double now = 15; @@ -86,7 +89,7 @@ public void nothingToSchedule() { } @Test - public void notScheduled_rejected() { + void notScheduled_rejected() { var fleet = fleet();//no vehicles -> impossible to schedule var unplannedRequests = requests(request1); double now = 15; @@ -114,12 +117,12 @@ public void notScheduled_rejected() { PassengerRequestRejectedEvent.class); verify(eventsManager, times(1)).processEvent(captor.capture()); assertThat(captor.getValue()).isEqualToComparingFieldByField( - new PassengerRequestRejectedEvent(now, mode, request1.getId(), request1.getPassengerId(), + new PassengerRequestRejectedEvent(now, mode, request1.getId(), request1.getPassengerIds(), NO_INSERTION_FOUND_CAUSE)); } @Test - public void notScheduled_addedToRetry() { + void notScheduled_addedToRetry() { var fleet = fleet();//no vehicles -> impossible to schedule var unplannedRequests = requests(request1); double now = 15; @@ -156,7 +159,7 @@ public void notScheduled_addedToRetry() { } @Test - public void firstRetryOldRequest_thenHandleNewRequest() { + void firstRetryOldRequest_thenHandleNewRequest() { var fleet = fleet();//no vehicles -> impossible to schedule var unplannedRequests = requests(request1); double now = 15; @@ -191,13 +194,13 @@ public void firstRetryOldRequest_thenHandleNewRequest() { } @Test - public void acceptedRequest() { + void acceptedRequest() { var vehicle1 = vehicle("1"); var fleet = fleet(vehicle1); var unplannedRequests = requests(request1); double now = 15; - var vehicle1Entry = new VehicleEntry(vehicle1, null, null, null, 0); + var vehicle1Entry = new VehicleEntry(vehicle1, null, null, null, null, 0); var createEntryCounter = new MutableInt(); VehicleEntry.EntryFactory entryFactory = (vehicle, currentTime) -> { //make sure the right arguments are passed @@ -243,7 +246,7 @@ public void acceptedRequest() { PassengerRequestScheduledEvent.class); verify(eventsManager, times(1)).processEvent(captor.capture()); assertThat(captor.getValue()).isEqualToComparingFieldByField( - new PassengerRequestScheduledEvent(now, mode, request1.getId(), request1.getPassengerId(), + new PassengerRequestScheduledEvent(now, mode, request1.getId(), request1.getPassengerIds(), vehicle1.getId(), pickupEndTime, dropoffBeginTime)); //vehicle entry was created twice: @@ -271,7 +274,7 @@ private DvrpVehicle vehicle(String vehicleId) { private DrtRequest request(String id, String fromLinkId, String toLinkId) { return DrtRequest.newBuilder() .id(Id.create(id, Request.class)) - .passengerId(Id.createPersonId(id)) + .passengerIds(List.of(Id.createPersonId(id))) .fromLink(link(fromLinkId)) .toLink(link(toLinkId)) .mode(mode) @@ -283,7 +286,7 @@ private DefaultUnplannedRequestInserter newInserter(Fleet fleet, double now, DrtInsertionSearch insertionSearch, RequestInsertionScheduler insertionScheduler) { return new DefaultUnplannedRequestInserter(mode, fleet, () -> now, eventsManager, insertionScheduler, vehicleEntryFactory, insertionRetryQueue, insertionSearch, DrtOfferAcceptor.DEFAULT_ACCEPTOR, - rule.forkJoinPool); + forkJoinPoolExtension.forkJoinPool, StaticPassengerStopDurationProvider.of(10.0, 0.0)); } private Link link(String id) { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DetourTimeEstimatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DetourTimeEstimatorTest.java index 85caff1ca6c..d11094a9fd1 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DetourTimeEstimatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DetourTimeEstimatorTest.java @@ -25,7 +25,7 @@ import static org.mockito.Mockito.when; import org.assertj.core.api.Assertions; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contrib.dvrp.trafficmonitoring.QSimFreeSpeedTravelTime; import org.matsim.contrib.zone.skims.TravelTimeMatrix; import org.matsim.testcases.fakes.FakeLink; @@ -37,14 +37,14 @@ public class DetourTimeEstimatorTest { @Test - public void freeSpeedZonalTimeEstimator_fromLinkToLinkSame() { + void freeSpeedZonalTimeEstimator_fromLinkToLinkSame() { var link = new FakeLink(null); var estimator = DetourTimeEstimator.createMatrixBasedEstimator(1, null, null); Assertions.assertThat(estimator.estimateTime(link, link, 345)).isZero(); } @Test - public void freeSpeedZonalTimeEstimator_fromLinkToLinkDifferent() { + void freeSpeedZonalTimeEstimator_fromLinkToLinkDifferent() { var linkA = new FakeLink(null, null, new FakeNode(null)); var linkB = new FakeLink(null, new FakeNode(null), null); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java index 236d2889a6a..76b6f176cde 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/DrtPoolingParameterTest.java @@ -3,10 +3,9 @@ import java.net.URL; import java.util.*; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.*; @@ -53,7 +52,7 @@ */ public class DrtPoolingParameterTest { - @Rule + @RegisterExtension public final MatsimTestUtils utils = new MatsimTestUtils(); @@ -65,9 +64,9 @@ public class DrtPoolingParameterTest { * With a low maxWaitTime of 100s, no DRT vehicle should have time to any agents. */ @Test - public void testMaxWaitTimeNoVehicles() { + void testMaxWaitTimeNoVehicles() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(50, 10.0, 10000.); - Assert.assertEquals("There should be no vehicle used", 0, handler.getVehRequestCount().size()); + Assertions.assertEquals(0, handler.getVehRequestCount().size(), "There should be no vehicle used"); } @@ -77,20 +76,20 @@ public void testMaxWaitTimeNoVehicles() { * too far away to reach those agents. */ @Test - public void testMaxWaitTimeTwoVehiclesForTwoAgents() { + void testMaxWaitTimeTwoVehiclesForTwoAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(121, 10.0, 10000.); - Assert.assertEquals("There should two vehicle used", 2, handler.getVehRequestCount().size()); + Assertions.assertEquals(2, handler.getVehRequestCount().size(), "There should two vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); Id drt_veh_1_2 = Id.create("drt_veh_1_2", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly once", 1, - handler.getVehRequestCount().get(drt_veh_1_1), 0); - Assert.assertTrue("drt_veh_1_2 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_2)); - Assert.assertEquals("drt_veh_1_2 should be requested exactly once", 1, - handler.getVehRequestCount().get(drt_veh_1_2), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(1, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly once"); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_2), + "drt_veh_1_2 should be requested in general"); + Assertions.assertEquals(1, + handler.getVehRequestCount().get(drt_veh_1_2), 0, "drt_veh_1_2 should be requested exactly once"); } @@ -98,20 +97,20 @@ public void testMaxWaitTimeTwoVehiclesForTwoAgents() { * With a maxWaitTime of 250s, both drt vehicles should have time to each pick up two passengers. */ @Test - public void testMaxWaitTimeTwoVehiclesForFourAgents() { + void testMaxWaitTimeTwoVehiclesForFourAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(250, 10.0, 10000.); - Assert.assertEquals("There should two vehicle used", 2, handler.getVehRequestCount().size()); + Assertions.assertEquals(2, handler.getVehRequestCount().size(), "There should two vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); Id drt_veh_1_2 = Id.create("drt_veh_1_2", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly twice", 2, - handler.getVehRequestCount().get(drt_veh_1_1), 0); - Assert.assertTrue("drt_veh_1_2 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_2)); - Assert.assertEquals("drt_veh_1_2 should be requested exactly twice", 2, - handler.getVehRequestCount().get(drt_veh_1_2), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(2, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly twice"); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_2), + "drt_veh_1_2 should be requested in general"); + Assertions.assertEquals(2, + handler.getVehRequestCount().get(drt_veh_1_2), 0, "drt_veh_1_2 should be requested exactly twice"); } @@ -119,32 +118,32 @@ public void testMaxWaitTimeTwoVehiclesForFourAgents() { * With a high maxWaitTime of 500s, a single DRT vehicle should be able to pick up all four agents. */ @Test - public void testMaxWaitTimeOneVehicleForFourAgents() { + void testMaxWaitTimeOneVehicleForFourAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(500, 10.0, 10000.); System.out.println(handler.getVehRequestCount()); - Assert.assertEquals("There should only be one vehicle used", 1, handler.getVehRequestCount().size()); + Assertions.assertEquals(1, handler.getVehRequestCount().size(), "There should only be one vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly four times", 4, - handler.getVehRequestCount().get(drt_veh_1_1), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(4, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly four times"); } /* - The following tests vary the maxTravelTimeBeta parameter. maxTravelTimeAlpha is fixed to 1.0, while maxWaitTime is - fixed to a high value: 5000s. + e following tests vary the maxTravelTimeBeta parameter. maxTravelTimeAlpha is fixed to 1.0, while maxWaitTime is + ixed to a high value: 5000s. */ /** * With a low Beta of 0s, no DRT vehicles should be assigned to the agents. */ @Test - public void testBetaNoVehicles() { + void testBetaNoVehicles() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(5000, 1.0, 0.); - Assert.assertEquals("There should only be zero vehicles used", 0, handler.getVehRequestCount().size()); + Assertions.assertEquals(0, handler.getVehRequestCount().size(), "There should only be zero vehicles used"); } @@ -153,20 +152,20 @@ public void testBetaNoVehicles() { * the remaining two agents will be left stranded */ @Test - public void testBetaTwoVehiclesForTwoAgents() { + void testBetaTwoVehiclesForTwoAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(5000, 1.0, 150); - Assert.assertEquals("There should two vehicle used", 2, handler.getVehRequestCount().size()); + Assertions.assertEquals(2, handler.getVehRequestCount().size(), "There should two vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); Id drt_veh_1_2 = Id.create("drt_veh_1_2", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly once", 1, - handler.getVehRequestCount().get(drt_veh_1_1), 0); - Assert.assertTrue("drt_veh_1_2 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_2)); - Assert.assertEquals("drt_veh_1_2 should be requested exactly once", 1, - handler.getVehRequestCount().get(drt_veh_1_2), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(1, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly once"); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_2), + "drt_veh_1_2 should be requested in general"); + Assertions.assertEquals(1, + handler.getVehRequestCount().get(drt_veh_1_2), 0, "drt_veh_1_2 should be requested exactly once"); } @@ -174,35 +173,35 @@ public void testBetaTwoVehiclesForTwoAgents() { * With a Beta value of 250s, two DRT vehicles should have enough time to pick up two passengers each. */ @Test - public void testBetaTwoVehiclesForFourAgents() { + void testBetaTwoVehiclesForFourAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(5000, 1.0, 250); - Assert.assertEquals("There should two vehicle used", 2, handler.getVehRequestCount().size()); + Assertions.assertEquals(2, handler.getVehRequestCount().size(), "There should two vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); Id drt_veh_1_2 = Id.create("drt_veh_1_2", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly twice", 2, - handler.getVehRequestCount().get(drt_veh_1_1), 0); - Assert.assertTrue("drt_veh_1_2 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_2)); - Assert.assertEquals("drt_veh_1_2 should be requested exactly twice", 2, - handler.getVehRequestCount().get(drt_veh_1_2), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(2, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly twice"); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_2), + "drt_veh_1_2 should be requested in general"); + Assertions.assertEquals(2, + handler.getVehRequestCount().get(drt_veh_1_2), 0, "drt_veh_1_2 should be requested exactly twice"); } /** * With a high Beta of 400s, one DRT vehicle should be used to pick up all four agents */ @Test - public void testBetaOneVehicleForFourAgents() { + void testBetaOneVehicleForFourAgents() { PersonEnterDrtVehicleEventHandler handler = setupAndRunScenario(5000, 1.0, 400); - Assert.assertEquals("There should only be one vehicle used", 1, handler.getVehRequestCount().size()); + Assertions.assertEquals(1, handler.getVehRequestCount().size(), "There should only be one vehicle used"); Id drt_veh_1_1 = Id.create("drt_veh_1_1", DvrpVehicle.class); - Assert.assertTrue("drt_veh_1_1 should be requested in general", - handler.getVehRequestCount().containsKey(drt_veh_1_1)); - Assert.assertEquals("drt_veh_1_1 should be requested exactly four times", 4, - handler.getVehRequestCount().get(drt_veh_1_1), 0); + Assertions.assertTrue(handler.getVehRequestCount().containsKey(drt_veh_1_1), + "drt_veh_1_1 should be requested in general"); + Assertions.assertEquals(4, + handler.getVehRequestCount().get(drt_veh_1_1), 0, "drt_veh_1_1 should be requested exactly four times"); } @@ -213,9 +212,9 @@ private PersonEnterDrtVehicleEventHandler setupAndRunScenario(double maxWaitTime new OTFVisConfigGroup()); config.plans().setInputFile(null); - config.controler() + config.controller() .setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); MultiModeDrtConfigGroup mm = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); mm.getModalElements().forEach(x -> { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolTestRule.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolExtension.java similarity index 78% rename from contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolTestRule.java rename to contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolExtension.java index 548decd28b6..e6f204bdf58 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolTestRule.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/ForkJoinPoolExtension.java @@ -22,27 +22,17 @@ import java.util.concurrent.ForkJoinPool; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; /** * @author Michal Maciejewski (michalm) */ -public class ForkJoinPoolTestRule implements TestRule { +public class ForkJoinPoolExtension implements AfterEachCallback { public final ForkJoinPool forkJoinPool = new ForkJoinPool(1); @Override - public Statement apply(Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - base.evaluate(); - } finally { - forkJoinPool.shutdown(); - } - } - }; + public void afterEach(ExtensionContext extensionContext) throws Exception { + forkJoinPool.shutdown(); } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionCostCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionCostCalculatorTest.java index f9c25dd60cf..0d617d9fc9f 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionCostCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionCostCalculatorTest.java @@ -24,7 +24,7 @@ import static org.matsim.contrib.drt.optimizer.insertion.InsertionCostCalculator.INFEASIBLE_SOLUTION_COST; import static org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -41,7 +41,7 @@ public class InsertionCostCalculatorTest { private final DrtRequest drtRequest = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).build(); @Test - public void testCalculate() { + void testCalculate() { VehicleEntry entry = entry(new double[] { 20, 20, 50 }); var insertion = insertion(entry, 0, 1); @@ -71,7 +71,7 @@ private void assertCalculate(Insertion insertion, DetourTimeInfo detourTimeInfo, } private VehicleEntry entry(double[] slackTimes) { - return new VehicleEntry(null, null, null, slackTimes, 0); + return new VehicleEntry(null, null, null, slackTimes, null, 0); } private Link link(String id) { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorTest.java index 16e708701fd..756682854b0 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorTest.java @@ -22,9 +22,9 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Collections; import java.util.List; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -36,7 +36,6 @@ import org.matsim.contrib.drt.optimizer.insertion.InsertionWithDetourData.InsertionDetourData; import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.drt.schedule.DefaultDrtStopTask; -import org.matsim.contrib.drt.stops.DefaultPassengerStopDurationProvider; import org.matsim.contrib.drt.stops.DefaultStopTimeCalculator; import org.matsim.contrib.dvrp.path.OneToManyPathSearch.PathData; import org.matsim.contrib.dvrp.schedule.Task; @@ -57,7 +56,7 @@ public class InsertionDetourTimeCalculatorTest { private final DrtRequest drtRequest = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).build(); @Test - public void detourTimeLoss_start_pickup_dropoff() { + void detourTimeLoss_start_pickup_dropoff() { Waypoint.Start start = start(null, 10, link("start")); VehicleEntry entry = entry(start); var detour = detourData(100., 15., Double.NaN, 0.); @@ -74,7 +73,7 @@ public void detourTimeLoss_start_pickup_dropoff() { } @Test - public void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { + void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { //similar to detourTmeLoss_start_pickup_dropoff(), but the pickup is appended to the ongoing STOP task // sh 03/08/23: Changed this test, according to VehicleDataEntryFactoryImpl the start time should be end time of stop task Waypoint.Start start = start(new DefaultDrtStopTask(20, 20 + STOP_DURATION, fromLink), 20 + STOP_DURATION, fromLink); @@ -91,7 +90,7 @@ public void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { } @Test - public void detourTimeLoss_start_pickup_dropoff_stop() { + void detourTimeLoss_start_pickup_dropoff_stop() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); VehicleEntry entry = entry(start, stop0); @@ -109,7 +108,7 @@ public void detourTimeLoss_start_pickup_dropoff_stop() { } @Test - public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { + void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); VehicleEntry entry = entry(start, stop0); @@ -127,7 +126,7 @@ public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { } @Test - public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { + void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -148,7 +147,7 @@ public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { } @Test - public void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAppended_stop() { + void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAppended_stop() { Waypoint.Start start = start(null, 5, fromLink);//not a STOP -> pickup cannot be appended Waypoint.Stop stop0 = stop(10, toLink); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -165,7 +164,7 @@ public void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAp } @Test - public void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoffAppended() { + void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoffAppended() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, fromLink); Waypoint.Stop stop1 = stop(200, toLink); @@ -182,7 +181,7 @@ public void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoff } @Test - public void replacedDriveTimeEstimator() { + void replacedDriveTimeEstimator() { Waypoint.Start start = start(null, 0, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -234,7 +233,8 @@ private Waypoint.Stop stop(double beginTime, Link link) { } private VehicleEntry entry(Waypoint.Start start, Waypoint.Stop... stops) { - return new VehicleEntry(null, start, ImmutableList.copyOf(stops), null, 0); + List precedingStayTimes = Collections.nCopies(stops.length, 0.0); + return new VehicleEntry(null, start, ImmutableList.copyOf(stops), null, precedingStayTimes, 0); } private InsertionDetourData detourData(double toPickupTT, double fromPickupTT, double toDropoffTT, diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorWithVariableDurationTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorWithVariableDurationTest.java index 8f9b037a7dc..fcfa03962bd 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorWithVariableDurationTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionDetourTimeCalculatorWithVariableDurationTest.java @@ -20,9 +20,11 @@ package org.matsim.contrib.drt.optimizer.insertion; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableTable; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -42,9 +44,8 @@ import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.testcases.fakes.FakeLink; -import java.util.Collections; - -import static org.assertj.core.api.Assertions.assertThat; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableTable; /** * @author Michal Maciejewski (michalm) @@ -89,7 +90,7 @@ public double calcDropoffDuration(DvrpVehicle vehicle, DrtRequest request) { new CumulativeStopTimeCalculator(STOP_DURATION_PROVIDER); @Test - public void detourTimeLoss_start_pickup_dropoff() { + void detourTimeLoss_start_pickup_dropoff() { Waypoint.Start start = start(null, 10, link("start")); VehicleEntry entry = entry(start); var detour = new Detour(100., 15., 0., 0.); @@ -107,7 +108,7 @@ public void detourTimeLoss_start_pickup_dropoff() { } @Test - public void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { + void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { //similar to detourTmeLoss_start_pickup_dropoff(), but the pickup is appended to the ongoing STOP task DrtStopTask stopTask = new DefaultDrtStopTask(20, 20 + STOP_DURATION_INITIAL, fromLink); stopTask.addDropoffRequest(AcceptedDrtRequest.createFromOriginalRequest(drtRequestInitial)); @@ -127,7 +128,7 @@ public void detourTimeLoss_ongoingStopAsStart_pickup_dropoff() { } @Test - public void detourTimeLoss_start_pickup_dropoff_stop() { + void detourTimeLoss_start_pickup_dropoff_stop() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); VehicleEntry entry = entry(start, stop0); @@ -144,7 +145,7 @@ public void detourTimeLoss_start_pickup_dropoff_stop() { } @Test - public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { + void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); VehicleEntry entry = entry(start, stop0); @@ -161,7 +162,7 @@ public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff() { } @Test - public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { + void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -179,7 +180,7 @@ public void calculatePickupDetourTimeLoss_start_pickup_stop_dropoff_stop() { } @Test - public void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAppended_stop() { + void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAppended_stop() { Waypoint.Start start = start(null, 5, fromLink);//not a STOP -> pickup cannot be appended Waypoint.Stop stop0 = stop(10, toLink); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -197,7 +198,7 @@ public void calculatePickupDetourTimeLoss_start_pickupNotAppended_stop_dropoffAp } @Test - public void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoffAppended() { + void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoffAppended() { Waypoint.Start start = start(null, 5, link("start")); Waypoint.Stop stop0 = stop(10, fromLink); Waypoint.Stop stop1 = stop(200, toLink); @@ -215,7 +216,7 @@ public void calculatePickupDetourTimeLoss_start_stop_pickupAppended_stop_dropoff } @Test - public void replacedDriveTimeEstimator() { + void replacedDriveTimeEstimator() { Waypoint.Start start = start(null, 0, link("start")); Waypoint.Stop stop0 = stop(10, link("stop0")); Waypoint.Stop stop1 = stop(200, link("stop1")); @@ -274,7 +275,8 @@ private Waypoint.Stop stop(double beginTime, Link link) { } private VehicleEntry entry(Waypoint.Start start, Waypoint.Stop... stops) { - return new VehicleEntry(null, start, ImmutableList.copyOf(stops), null, 0); + List precedingStayTimes = Collections.nCopies(stops.length, 0.0); + return new VehicleEntry(null, start, ImmutableList.copyOf(stops), null, precedingStayTimes, 0); } private InsertionWithDetourData insertion(VehicleEntry entry, int pickupIdx, int dropoffIdx, diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGeneratorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGeneratorTest.java index 4509e5f90ad..5a44c12c118 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGeneratorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/InsertionGeneratorTest.java @@ -20,13 +20,10 @@ package org.matsim.contrib.drt.optimizer.insertion; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -35,9 +32,9 @@ import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.DropoffDetourInfo; import org.matsim.contrib.drt.optimizer.insertion.InsertionDetourTimeCalculator.PickupDetourInfo; import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; import org.matsim.contrib.drt.passenger.DrtRequest; import org.matsim.contrib.drt.schedule.DefaultDrtStopTask; -import org.matsim.contrib.drt.stops.DefaultPassengerStopDurationProvider; import org.matsim.contrib.drt.stops.DefaultStopTimeCalculator; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.fleet.DvrpVehicleImpl; @@ -45,8 +42,12 @@ import org.matsim.contrib.dvrp.fleet.ImmutableDvrpVehicleSpecification; import org.matsim.testcases.fakes.FakeLink; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Michal Maciejewski (michalm) @@ -64,7 +65,23 @@ public class InsertionGeneratorTest { private final Link fromLink = link("from"); private final Link toLink = link("to"); - private final DrtRequest drtRequest = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).build(); + private final DrtRequest drtRequest = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).passengerIds(List.of(Id.createPersonId("person"))).build(); + + private final DrtRequest drtRequest2Pax = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).passengerIds( + List.of( + Id.createPersonId("person1"), + Id.createPersonId("person2") + )).build(); + + private final DrtRequest drtRequest5Pax = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).passengerIds( + List.of( + Id.createPersonId("person1"), + Id.createPersonId("person2"), + Id.createPersonId("person3"), + Id.createPersonId("person4"), + Id.createPersonId("person5") + )).build(); + private final DrtRequest prebookedRequest = DrtRequest.newBuilder().fromLink(fromLink).toLink(toLink).earliestStartTime(100).build(); private final Link depotLink = link("depot"); private final DvrpVehicleSpecification vehicleSpecification = ImmutableDvrpVehicleSpecification.newBuilder() @@ -77,7 +94,7 @@ public class InsertionGeneratorTest { private final DvrpVehicle vehicle = new DvrpVehicleImpl(vehicleSpecification, depotLink); @Test - public void startEmpty_noStops() { + void startEmpty_noStops() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //no stops => must be empty VehicleEntry entry = entry(start); @@ -93,7 +110,7 @@ public void startEmpty_noStops() { } @Test - public void startNotFull_oneStop() { + void startNotFull_oneStop() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 1); // 1 pax aboard Waypoint.Stop stop0 = stop(start.time + TIME_REPLACED_DRIVE, link("stop0"), 0);//drop off 1 pax VehicleEntry entry = entry(start, stop0); @@ -126,7 +143,7 @@ public void startNotFull_oneStop() { } @Test - public void startFull_oneStop() { + void startFull_oneStop() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, CAPACITY); //full Waypoint.Stop stop0 = stop(start.time + TIME_REPLACED_DRIVE, link("stop0"), 0);//drop off 4 pax VehicleEntry entry = entry(start, stop0); @@ -143,7 +160,7 @@ public void startFull_oneStop() { } @Test - public void startEmpty_twoStops_notFullBetweenStops() { + void startEmpty_twoStops_notFullBetweenStops() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty Waypoint.Stop stop0 = stop(start.time + TIME_REPLACED_DRIVE, link("stop0"), 1);//pick up 1 pax Waypoint.Stop stop1 = stop(stop0.getDepartureTime() + TIME_REPLACED_DRIVE, link("stop1"), 0);//drop off 1 pax @@ -201,7 +218,7 @@ public void startEmpty_twoStops_notFullBetweenStops() { } @Test - public void startEmpty_twoStops_notFullBetweenStops_tightSlackTimes() { + void startEmpty_twoStops_notFullBetweenStops_tightSlackTimes() { //same as startEmpty_twoStops_notFullBetweenStops() but with different slack times Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty Waypoint.Stop stop0 = stop(start.time + TIME_REPLACED_DRIVE, link("stop0"), 1);//pick up 1 pax @@ -210,7 +227,10 @@ public void startEmpty_twoStops_notFullBetweenStops_tightSlackTimes() { double[] slackTimes = { 0, 0, // impossible insertions: 00, 01, 02 (pickup at 0 is not possible) 500, // additional impossible insertions: 11 (too long total detour); however 12 is possible 1000 }; // 22 is possible - VehicleEntry entry = new VehicleEntry(vehicle, start, ImmutableList.of(stop0, stop1), slackTimes, 0); + + List precedingStayTimes = Arrays.asList(0.0, 0.0); + + VehicleEntry entry = new VehicleEntry(vehicle, start, ImmutableList.of(stop0, stop1), slackTimes, precedingStayTimes, 0); var insertions = new ArrayList(); {//12 @@ -232,7 +252,7 @@ public void startEmpty_twoStops_notFullBetweenStops_tightSlackTimes() { } @Test - public void startEmpty_twoStops_fullBetweenStops() { + void startEmpty_twoStops_fullBetweenStops() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty Waypoint.Stop stop0 = stop(0, link("stop0"), CAPACITY);//pick up 4 pax (full) Waypoint.Stop stop1 = stop(0, link("stop1"), 0);//drop off 4 pax @@ -246,7 +266,7 @@ public void startEmpty_twoStops_fullBetweenStops() { } @Test - public void startFull_twoStops_notFullBetweenStops() { + void startFull_twoStops_notFullBetweenStops() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, CAPACITY); //full Waypoint.Stop stop0 = stop(0, link("stop0"), 2);//drop off 2 pax Waypoint.Stop stop1 = stop(0, link("stop1"), 0);//drop off 2 pax @@ -261,7 +281,7 @@ public void startFull_twoStops_notFullBetweenStops() { } @Test - public void startFull_twoStops_fullBetweenStops() { + void startFull_twoStops_fullBetweenStops() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, CAPACITY); //full Waypoint.Stop stop0 = stop(0, link("stop0"), CAPACITY);//drop off 1 pax, pickup 1 pax (full) Waypoint.Stop stop1 = stop(0, link("stop1"), 0);//drop off 4 pax @@ -274,7 +294,7 @@ public void startFull_twoStops_fullBetweenStops() { } @Test - public void startNotFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { + void startNotFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 1); //empty Waypoint.Stop stop0 = stop(0, link("stop0"), 0);// dropoff 1 pax Waypoint.Stop stop1 = stop(0, link("stop1"), CAPACITY);// pickup 4 pax @@ -292,7 +312,7 @@ public void startNotFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { } @Test - public void startFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { + void startFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, CAPACITY); //full Waypoint.Stop stop0 = stop(0, link("stop0"), 0);// dropoff 4 pax Waypoint.Stop stop1 = stop(0, link("stop1"), CAPACITY);// pickup 4 pax @@ -308,7 +328,7 @@ public void startFull_threeStops_emptyBetweenStops01_fullBetweenStops12() { } @Test - public void noDetourForPickup_noDuplicatedInsertions() { + void noDetourForPickup_noDuplicatedInsertions() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 1); // 1 pax Waypoint.Stop stop0 = stop(0, fromLink, 0);//dropoff 1 pax VehicleEntry entry = entry(start, stop0); @@ -319,7 +339,7 @@ public void noDetourForPickup_noDuplicatedInsertions() { } @Test - public void noDetourForDropoff_noDuplicatedInsertions() { + void noDetourForDropoff_noDuplicatedInsertions() { Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 1); // 1 pax Waypoint.Stop stop0 = stop(0, toLink, 0);//dropoff 1 pax VehicleEntry entry = entry(start, stop0); @@ -331,7 +351,7 @@ public void noDetourForDropoff_noDuplicatedInsertions() { } @Test - public void noDetourForDropoff_vehicleOutgoingFullAfterDropoff_insertionPossible() { + void noDetourForDropoff_vehicleOutgoingFullAfterDropoff_insertionPossible() { // a special case where we allow inserting the dropoff after a stop despite outgoingOccupancy == maxCapacity // this is only because the the dropoff happens exactly at (not after) the stop Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 1); // 1 pax @@ -345,6 +365,111 @@ public void noDetourForDropoff_vehicleOutgoingFullAfterDropoff_insertionPossible new Insertion(drtRequest, entry, 2, 2)); } + @Test + void startEmpty_prebookedRequest() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); + VehicleEntry entry = entry(start); + assertInsertionsOnly(prebookedRequest, entry, + new Insertion(prebookedRequest, entry, 0, 0)); + } + + @Test + void startEmpty_onlineRequest_beforeAlreadyPrebookedOtherRequest() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); + Waypoint.Stop stop0 = stop(200, fromLink, 1); + Waypoint.Stop stop1 = stop(400, link("stop"), 0); + VehicleEntry entry = entry(start, stop0, stop1); + assertInsertionsOnly(drtRequest, entry, + new Insertion(drtRequest, entry, 0, 0), + new Insertion(drtRequest, entry, 0, 1), + new Insertion(drtRequest, entry, 0, 2), + new Insertion(drtRequest, entry, 1, 1), + new Insertion(drtRequest, entry, 1, 2), + new Insertion(drtRequest, entry, 2, 2) + ); + } + + @Test + void startEmpty_prebookedRequest_inMiddleOfAlreadyPrebookedOtherRequest() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); + Waypoint.Stop stop0 = stop(50, fromLink, 1); + Waypoint.Stop stop1 = stop(300, link("stop"), 0); + VehicleEntry entry = entry(start, stop0, stop1); + assertInsertionsOnly(prebookedRequest, entry, + new Insertion(prebookedRequest, entry, 1, 1), + new Insertion(prebookedRequest, entry, 1, 2), + new Insertion(prebookedRequest, entry, 2, 2)); + } + + @Test + void startEmpty_prebookedRequest_afterAlreadyPrebookedOtherRequest() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); + Waypoint.Stop stop0 = stop(20, fromLink, 1); + Waypoint.Stop stop1 = stop(70, link("stop"), 0); + VehicleEntry entry = entry(start, stop0, stop1); + assertInsertionsOnly(prebookedRequest, entry, + new Insertion(prebookedRequest, entry, 2, 2)); + } + + + @Test + void startEmpty_smallGroup() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty + VehicleEntry entry = entry(start); + assertInsertionsOnly(drtRequest2Pax, entry, + //pickup after start + new Insertion(drtRequest2Pax, entry, 0, 0)); + } + + @Test + void startEmpty_groupExceedsCapacity() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty + VehicleEntry entry = entry(start); + assertInsertionsOnly(drtRequest5Pax, entry + //no insertion possible + ); + } + + @Test + void startEmpty_twoStops_groupExceedsCapacityAtFirstStop() { + Waypoint.Start start = new Waypoint.Start(null, link("start"), 0, 0); //empty + Waypoint.Stop stop0 = stop(0, toLink, 3);//dropoff 1 pax + Waypoint.Stop stop1 = stop(0, link("stop1"), 0);//dropoff 1 pax + VehicleEntry entry = entry(start, stop0, stop1); + assertInsertionsOnly(drtRequest2Pax, entry, + //pickup after start: + new Insertion(drtRequest2Pax, entry, 0, 1), + //pickup after stop 1 + new Insertion(drtRequest2Pax, entry, 2, 2) + ); + } + + @Test + void testWaypointOccupancyChange() { + int occupancy = 0; + AcceptedDrtRequest acceptedReq5Pax = AcceptedDrtRequest.createFromOriginalRequest(drtRequest5Pax); + AcceptedDrtRequest acceptedReq2Pax = AcceptedDrtRequest.createFromOriginalRequest(drtRequest2Pax); + + Waypoint.Stop stop2 = stop(0, link("stop2"), occupancy); + //dropoff 5 pax + stop2.task.addDropoffRequest(acceptedReq5Pax); + occupancy -= stop2.getOccupancyChange(); + Assertions.assertEquals(5, occupancy); + + Waypoint.Stop stop1 = stop(0, link("stop1"), occupancy); + //dropoff 2 pax, pickup 5 + stop1.task.addDropoffRequest(acceptedReq2Pax); + stop1.task.addPickupRequest(acceptedReq5Pax); + occupancy -= stop1.getOccupancyChange(); + Assertions.assertEquals(2, occupancy); + + + Waypoint.Stop stop0 = stop(0, link("stop0"), occupancy); + stop0.task.addPickupRequest(acceptedReq2Pax); + occupancy -= stop0.getOccupancyChange(); + Assertions.assertEquals(0, occupancy); + } + private Link link(String id) { return new FakeLink(Id.createLinkId(id)); } @@ -401,6 +526,7 @@ private Waypoint.Stop stop(double beginTime, Link link, int outgoingOccupancy) { private VehicleEntry entry(Waypoint.Start start, Waypoint.Stop... stops) { var slackTimes = new double[stops.length + 2]; Arrays.fill(slackTimes, Double.POSITIVE_INFINITY); - return new VehicleEntry(vehicle, start, ImmutableList.copyOf(stops), slackTimes, 0); + List precedingStayTimes = Collections.nCopies(stops.length, 0.0); + return new VehicleEntry(vehicle, start, ImmutableList.copyOf(stops), slackTimes, precedingStayTimes, 0); } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/DetourPathDataCacheTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/DetourPathDataCacheTest.java index 283f69b0cf3..fcc8928de9c 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/DetourPathDataCacheTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/DetourPathDataCacheTest.java @@ -24,8 +24,7 @@ import static org.mockito.Mockito.mock; import java.util.Arrays; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.drt.optimizer.VehicleEntry; @@ -86,32 +85,32 @@ public class DetourPathDataCacheTest { pathToDropoffMap, pathFromDropoffMap, ZERO_DETOUR); @Test - public void insertion_0_0() { + void insertion_0_0() { assertInsertion(0, 0, start_pickup, pickup_dropoff, null, dropoff_stop0); } @Test - public void insertion_0_1() { + void insertion_0_1() { assertInsertion(0, 1, start_pickup, pickup_stop0, stop0_dropoff, dropoff_stop1); } @Test - public void insertion_0_2() { + void insertion_0_2() { assertInsertion(0, 2, start_pickup, pickup_stop0, stop1_dropoff, ZERO_DETOUR); } @Test - public void insertion_1_1() { + void insertion_1_1() { assertInsertion(1, 1, stop0_pickup, pickup_dropoff, null, dropoff_stop1); } @Test - public void insertion_1_2() { + void insertion_1_2() { assertInsertion(1, 2, stop0_pickup, pickup_stop1, stop1_dropoff, ZERO_DETOUR); } @Test - public void insertion_2_2() { + void insertion_2_2() { assertInsertion(2, 2, stop1_pickup, pickup_dropoff, null, ZERO_DETOUR); } @@ -132,7 +131,7 @@ private Link link(String id) { private VehicleEntry entry(Link startLink, Link... stopLinks) { return new VehicleEntry(null, new Waypoint.Start(null, startLink, 0, 0), - Arrays.stream(stopLinks).map(this::stop).collect(ImmutableList.toImmutableList()), null, 0); + Arrays.stream(stopLinks).map(this::stop).collect(ImmutableList.toImmutableList()), null, null, 0); } private Waypoint.Stop stop(Link link) { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/ExtensiveInsertionProviderTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/ExtensiveInsertionProviderTest.java index 3e94e70dfd5..c6dc35ebdf6 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/ExtensiveInsertionProviderTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/ExtensiveInsertionProviderTest.java @@ -29,8 +29,8 @@ import java.util.List; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.drt.optimizer.Waypoint; import org.matsim.contrib.drt.optimizer.insertion.*; @@ -43,25 +43,25 @@ * @author Michal Maciejewski (michalm) */ public class ExtensiveInsertionProviderTest { - @Rule - public final ForkJoinPoolTestRule rule = new ForkJoinPoolTestRule(); + @RegisterExtension + public final ForkJoinPoolExtension rule = new ForkJoinPoolExtension(); @Test - public void getInsertions_noInsertionsGenerated() { + void getInsertions_noInsertionsGenerated() { var insertionProvider = new ExtensiveInsertionProvider(null, null, new InsertionGenerator(new DefaultStopTimeCalculator(120), null), rule.forkJoinPool); assertThat(insertionProvider.getInsertions(null, List.of())).isEmpty(); } @Test - public void getInsertions_twoAtEndInsertionsGenerated_zeroNearestInsertionsAtEndLimit() { + void getInsertions_twoAtEndInsertionsGenerated_zeroNearestInsertionsAtEndLimit() { //the infeasible solution gets discarded in the first stage //the feasible solution gets discarded in the second stage (KNearestInsertionsAtEndFilter) getInsertions_twoInsertionsGenerated(0); } @Test - public void getInsertions_twoAtEndInsertionsGenerated_tenNearestInsertionsAtEndLimit() { + void getInsertions_twoAtEndInsertionsGenerated_tenNearestInsertionsAtEndLimit() { //the infeasible solution gets discarded in the first stage //the feasible solution is NOT discarded in the second stage (KNearestInsertionsAtEndFilter) getInsertions_twoInsertionsGenerated(10); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/KNearestInsertionsAtEndFilterTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/KNearestInsertionsAtEndFilterTest.java index e971c5a312e..02a92a9588b 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/KNearestInsertionsAtEndFilterTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/KNearestInsertionsAtEndFilterTest.java @@ -25,8 +25,7 @@ import static org.mockito.Mockito.when; import java.util.List; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.drt.optimizer.Waypoint; @@ -46,7 +45,7 @@ public class KNearestInsertionsAtEndFilterTest { @Test - public void k0_atEndInsertionsNotReturned() { + void k0_atEndInsertionsNotReturned() { var vehicleEntry = vehicleEntry("v1", start(0), stop(100)); var insertion = insertion(vehicleEntry, 1, 10); var filteredInsertions = KNearestInsertionsAtEndFilter.filterInsertionsAtEnd(0, List.of(insertion)); @@ -54,13 +53,13 @@ public void k0_atEndInsertionsNotReturned() { } @Test - public void noInsertions_emptyList() { + void noInsertions_emptyList() { var filteredInsertions = filterOneInsertionAtEnd(); assertThat(filteredInsertions).isEmpty(); } @Test - public void noAtEndInsertions_allReturned() { + void noAtEndInsertions_allReturned() { var vehicleEntry = vehicleEntry("v1", start(0), stop(100)); var insertion1 = insertion(vehicleEntry, 0, 11); var insertion2 = insertion(vehicleEntry, 0, 22); @@ -70,7 +69,7 @@ public void noAtEndInsertions_allReturned() { } @Test - public void onlyAtEndInsertions_theEarliestReturned() { + void onlyAtEndInsertions_theEarliestReturned() { var vehicleEntry1 = vehicleEntry("v1", start(0), stop(100)); var insertion1 = insertion(vehicleEntry1, 1, 110); @@ -83,7 +82,7 @@ public void onlyAtEndInsertions_theEarliestReturned() { } @Test - public void onlyAtEndInsertions_equalArrivalTime_useVehicleIdAsTieBreaker() { + void onlyAtEndInsertions_equalArrivalTime_useVehicleIdAsTieBreaker() { var vehicleEntry1 = vehicleEntry("v1", start(0), stop(100)); var insertion1 = insertion(vehicleEntry1, 1, 110); @@ -96,7 +95,7 @@ public void onlyAtEndInsertions_equalArrivalTime_useVehicleIdAsTieBreaker() { } @Test - public void mixedTypeInsertions_bothReturned() { + void mixedTypeInsertions_bothReturned() { var vehicleEntry = vehicleEntry("v1", start(0), stop(100)); var insertionAfterStart = insertion(vehicleEntry, 0, 11); var insertionAtEnd = insertion(vehicleEntry, 1, 10); @@ -124,7 +123,7 @@ private Waypoint.Stop stop(double endTime) { private VehicleEntry vehicleEntry(String id, Waypoint.Start start, Waypoint.Stop... stops) { var vehicle = mock(DvrpVehicle.class); when(vehicle.getId()).thenReturn(Id.create(id, DvrpVehicle.class)); - return new VehicleEntry(vehicle, start, ImmutableList.copyOf(stops), null, 0); + return new VehicleEntry(vehicle, start, ImmutableList.copyOf(stops), null, null, 0); } private List filterOneInsertionAtEnd(InsertionWithDetourData... insertions) { diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/MultiInsertionDetourPathCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/MultiInsertionDetourPathCalculatorTest.java index 83ad6959ffe..b11903b01df 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/MultiInsertionDetourPathCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/extensive/MultiInsertionDetourPathCalculatorTest.java @@ -31,8 +31,8 @@ import java.util.List; import java.util.Map; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Node; @@ -70,13 +70,13 @@ public class MultiInsertionDetourPathCalculatorTest { private final MultiInsertionDetourPathCalculator detourPathCalculator = new MultiInsertionDetourPathCalculator( pathSearch, pathSearch, pathSearch, pathSearch, 1); - @After + @AfterEach public void after() { detourPathCalculator.notifyMobsimBeforeCleanup(null); } @Test - public void calculatePaths() { + void calculatePaths() { var pathToPickup = mockCalcPathData(pickupLink, beforePickupLink, request.getEarliestStartTime(), false, 11); var pathFromPickup = mockCalcPathData(pickupLink, afterPickupLink, request.getEarliestStartTime(), true, 22); var pathToDropoff = mockCalcPathData(dropoffLink, beforeDropoffLink, request.getLatestArrivalTime(), false, 33); @@ -96,7 +96,7 @@ public void calculatePaths() { } @Test - public void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { + void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { //compute only 2 paths (instead of 4) var pathToPickup = mockCalcPathData(pickupLink, beforePickupLink, request.getEarliestStartTime(), false, 11); var pathFromPickup = mockCalcPathData(pickupLink, dropoffLink, request.getEarliestStartTime(), true, 22); @@ -117,7 +117,7 @@ public void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { } @Test - public void calculatePaths_noDetours() { + void calculatePaths_noDetours() { // OneToManyPathSearch.calcPathDataMap() returns a map that contains entries for all toLinks // (unless the stop criterion terminates computations earlier) // If fromLink is in toLinks than PathData.EMPTY is mapped for such a link diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SelectiveInsertionProviderTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SelectiveInsertionProviderTest.java index a88df5ac539..d6ed2a51d7b 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SelectiveInsertionProviderTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SelectiveInsertionProviderTest.java @@ -31,11 +31,11 @@ import java.util.Optional; import java.util.Set; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contrib.drt.optimizer.VehicleEntry; import org.matsim.contrib.drt.optimizer.insertion.BestInsertionFinder; -import org.matsim.contrib.drt.optimizer.insertion.ForkJoinPoolTestRule; +import org.matsim.contrib.drt.optimizer.insertion.ForkJoinPoolExtension; import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator; import org.matsim.contrib.drt.optimizer.insertion.InsertionGenerator.Insertion; import org.matsim.contrib.drt.optimizer.insertion.InsertionWithDetourData; @@ -47,8 +47,8 @@ * @author Michal Maciejewski (michalm) */ public class SelectiveInsertionProviderTest { - @Rule - public final ForkJoinPoolTestRule rule = new ForkJoinPoolTestRule(); + @RegisterExtension + public final ForkJoinPoolExtension rule = new ForkJoinPoolExtension(); private final BestInsertionFinder initialInsertionFinder = mock(BestInsertionFinder.class); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SingleInsertionDetourPathCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SingleInsertionDetourPathCalculatorTest.java index 95d69fe11c4..19897df2149 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SingleInsertionDetourPathCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/insertion/selective/SingleInsertionDetourPathCalculatorTest.java @@ -30,8 +30,8 @@ import java.util.List; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Node; @@ -74,13 +74,13 @@ public class SingleInsertionDetourPathCalculatorTest { private final SingleInsertionDetourPathCalculator detourPathCalculator = new SingleInsertionDetourPathCalculator( null, new FreeSpeedTravelTime(), null, 1, (network, travelCosts, travelTimes) -> pathCalculator); - @After + @AfterEach public void after() { detourPathCalculator.notifyMobsimBeforeCleanup(null); } @Test - public void calculatePaths() { + void calculatePaths() { var pathToPickup = mockCalcLeastCostPath(beforePickupLink, pickupLink, request.getEarliestStartTime(), 11); var pathFromPickup = mockCalcLeastCostPath(pickupLink, afterPickupLink, request.getEarliestStartTime(), 22); var pathToDropoff = mockCalcLeastCostPath(beforeDropoffLink, dropoffLink, request.getLatestArrivalTime(), 33); @@ -99,7 +99,7 @@ public void calculatePaths() { } @Test - public void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { + void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { //compute only 2 paths (instead of 4) var pathToPickup = mockCalcLeastCostPath(beforePickupLink, pickupLink, request.getEarliestStartTime(), 11); var pathFromPickup = mockCalcLeastCostPath(pickupLink, dropoffLink, request.getEarliestStartTime(), 22); @@ -120,7 +120,7 @@ public void calculatePaths_dropoffAfterPickup_dropoffAtEnd() { } @Test - public void calculatePaths_noDetours() { + void calculatePaths_noDetours() { var pickup = insertionPoint(waypoint(pickupLink), waypoint(pickupLink)); var dropoff = insertionPoint(waypoint(dropoffLink), waypoint(dropoffLink)); var insertion = new Insertion(null, pickup, dropoff); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java index 7a155267da4..954959480ba 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/demandestimator/PreviousIterationDrtDemandEstimatorTest.java @@ -24,7 +24,7 @@ import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -51,7 +51,7 @@ public class PreviousIterationDrtDemandEstimatorTest { private final DrtZonalSystem zonalSystem = new DrtZonalSystem(List.of(zone1, zone2)); @Test - public void noDepartures() { + void noDepartures() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); //no events in previous iterations @@ -66,7 +66,7 @@ public void noDepartures() { } @Test - public void drtDepartures() { + void drtDepartures() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); //time bin 0-1800 @@ -101,7 +101,7 @@ public void drtDepartures() { } @Test - public void nonDrtDepartures() { + void nonDrtDepartures() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); estimator.handleEvent(departureEvent(100, link1, "mode X")); @@ -113,7 +113,7 @@ public void nonDrtDepartures() { } @Test - public void currentCountsAreCopiedToPreviousAfterReset() { + void currentCountsAreCopiedToPreviousAfterReset() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); estimator.handleEvent(departureEvent(100, link1, TransportMode.drt)); @@ -129,7 +129,7 @@ public void currentCountsAreCopiedToPreviousAfterReset() { } @Test - public void timeBinsAreRespected() { + void timeBinsAreRespected() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); estimator.handleEvent(departureEvent(100, link1, TransportMode.drt)); @@ -147,7 +147,7 @@ public void timeBinsAreRespected() { } @Test - public void noTimeLimitIsImposed() { + void noTimeLimitIsImposed() { PreviousIterationDrtDemandEstimator estimator = createEstimator(); estimator.handleEvent(departureEvent(10000000, link1, TransportMode.drt)); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java index b37ef0d10f1..4f51cb334a5 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehicleDensityTargetCalculatorTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.function.ToDoubleFunction; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.drt.analysis.zonal.DrtGridUtils; @@ -57,21 +57,21 @@ public class EqualVehicleDensityTargetCalculatorTest { DrtGridUtils.createGridFromNetwork(network, 500.)); @Test - public void calculate_oneVehiclePerZone() { + void calculate_oneVehiclePerZone() { var targetFunction = new EqualVehicleDensityTargetCalculator(zonalSystem, createFleetSpecification(8)).calculate(0, Map.of()); zonalSystem.getZones().keySet().forEach(id -> assertTarget(targetFunction, zonalSystem, id, 1)); } @Test - public void calculate_lessVehiclesThanZones() { + void calculate_lessVehiclesThanZones() { var targetFunction = new EqualVehicleDensityTargetCalculator(zonalSystem, createFleetSpecification(7)).calculate(0, Map.of()); zonalSystem.getZones().keySet().forEach(id -> assertTarget(targetFunction, zonalSystem, id, 7. / 8)); } @Test - public void calculate_moreVehiclesThanZones() { + void calculate_moreVehiclesThanZones() { var targetFunction = new EqualVehicleDensityTargetCalculator(zonalSystem, createFleetSpecification(9)).calculate(0, Map.of()); zonalSystem.getZones().keySet().forEach(id -> assertTarget(targetFunction, zonalSystem, id, 9. / 8)); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java index e27e9850b96..7d1044fcd6e 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/optimizer/rebalancing/targetcalculator/EqualVehiclesToPopulationRatioTargetCalculatorTest.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.function.ToDoubleFunction; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; @@ -66,7 +66,7 @@ public class EqualVehiclesToPopulationRatioTargetCalculatorTest { private final PopulationFactory factory = population.getFactory(); @Test - public void testCalculate_oneVehiclePerZone() { + void testCalculate_oneVehiclePerZone() { initPopulation(Map.of("2", 1, "4", 1, "8", 1)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(8)).calculate(0, Map.of()); @@ -82,7 +82,7 @@ public void testCalculate_oneVehiclePerZone() { } @Test - public void testCalculate_twoVehiclesPerZone() { + void testCalculate_twoVehiclesPerZone() { initPopulation(Map.of("2", 1, "4", 1, "8", 1)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); @@ -98,7 +98,7 @@ public void testCalculate_twoVehiclesPerZone() { } @Test - public void testCalculate_noPopulation() { + void testCalculate_noPopulation() { initPopulation(Map.of()); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); @@ -114,7 +114,7 @@ public void testCalculate_noPopulation() { } @Test - public void testCalculate_unevenDistributionOfActivitiesInPopulatedZones() { + void testCalculate_unevenDistributionOfActivitiesInPopulatedZones() { initPopulation(Map.of("2", 2, "4", 4, "8", 8)); var targetFunction = new EqualVehiclesToPopulationRatioTargetCalculator(zonalSystem, population, createFleetSpecification(16)).calculate(0, Map.of()); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/AbandonAndCancelTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/AbandonAndCancelTest.java new file mode 100644 index 00000000000..61241d7c293 --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/AbandonAndCancelTest.java @@ -0,0 +1,268 @@ +package org.matsim.contrib.drt.prebooking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.contrib.drt.prebooking.PrebookingTestEnvironment.RequestInfo; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.framework.PlanAgent; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.testcases.MatsimTestUtils; + +/** + * @author Sebastian Hörl (sebhoerl) / IRT SystemX + */ +public class AbandonAndCancelTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void noAbandonTest() { + /* + * One person requests to depart at 2000 and also is there at 2000. Another + * person asks also to depart at 2000, but only arrives at 4000, i.e. the person + * has 1000s delay. The vehicle should wait accordingly. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .addRequest("personOk", 0, 0, 5, 5, 2000.0, 0.0, 2000.0) // + .addRequest("personLate", 0, 0, 5, 5, 4000.0, 0.0, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + PrebookingTest.installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personOk"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2061.0, requestInfo.pickupTime, 1e-3); + assertEquals(4271.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personLate"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(4060.0, requestInfo.pickupTime, 1e-3); + assertEquals(4271.0, requestInfo.dropoffTime, 1e-3); + } + } + + @Test + void abandonTest() { + /* + * One person requests to depart at 2000 and also is there at 2000. Another + * person asks also to depart at 2000, but only arrives at 4000, i.e. the person + * has 1000s delay. + * + * We configure that the vehicle should leave without the passenger if it waits + * longer than 500s. The late request will be rejected! + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .addRequest("personOk", 0, 0, 5, 5, 2000.0, 0.0, 2000.0) // + .addRequest("personLate", 0, 0, 5, 5, 4000.0, 0.0, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + PrebookingParams parameters = PrebookingTest.installPrebooking(controller); + parameters.maximumPassengerDelay = 500.0; + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personOk"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2061.0, requestInfo.pickupTime, 1e-3); + assertEquals(2713.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personLate"); + assertEquals(0.0, requestInfo.submissionTimes.get(0), 1e-3); + // agent tries a non-prebooked request upon arrival + assertEquals(4000.0, requestInfo.submissionTimes.get(1), 1e-3); + assertTrue(requestInfo.rejected); + } + } + + @Test + void abandonThenImmediateTest() { + /* + * One person requests to depart at 2000 and also is there at 2000. Another + * person asks also to depart at 2000, but only arrives at 4000, i.e. the person + * has 1000s delay. + * + * We configure that the vehicle should leave without the passenger if it waits + * longer than 500s. The person will, however, send a new request when arriving + * at the departure point and get an immediate vehicle. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .addVehicle("vehicle2", 1, 1) // + .addRequest("personOk", 0, 0, 5, 5, 2000.0, 0.0, 2000.0) // + .addRequest("personLate", 0, 0, 5, 5, 4000.0, 0.0, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + PrebookingParams parameters = PrebookingTest.installPrebooking(controller); + parameters.maximumPassengerDelay = 500.0; + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personOk"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2061.0, requestInfo.pickupTime, 1e-3); + assertEquals(2713.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personLate"); + assertEquals(0.0, requestInfo.submissionTimes.get(0), 1e-3); + // agent tries a non-prebooked request upon arrival + assertEquals(4000.0, requestInfo.submissionTimes.get(1), 1e-3); + assertEquals(4146.0, requestInfo.pickupTime, 1e-3); + assertEquals(4357.0, requestInfo.dropoffTime, 1e-3); + assertTrue(requestInfo.rejected); + } + } + + @Test + void cancelEarlyTest() { + /* + * One person requests to depart at 2000 and also is there at 2000. Another + * person asks also to depart at 2000, but only arrives at 4000, i.e. the person + * has 1000s delay. + * + * In this test we manually cancel the second request at 500.0 (so before + * departure of any agent). + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .addRequest("personOk", 0, 0, 5, 5, 2000.0, 0.0, 2000.0) // + .addRequest("personLate", 0, 0, 5, 5, 4000.0, 0.0, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + PrebookingTest.installPrebooking(controller); + + controller.addOverridingQSimModule(new AbstractDvrpModeQSimModule("drt") { + @Override + protected void configureQSim() { + addModalQSimComponentBinding().toProvider(modalProvider(getter -> { + PrebookingManager prebookingManager = getter.getModal(PrebookingManager.class); + QSim qsim = getter.get(QSim.class); + + return new MobsimBeforeSimStepListener() { + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + if (e.getSimulationTime() == 500.0) { + PlanAgent planAgent = (PlanAgent) qsim.getAgents() + .get(Id.createPersonId("personLate")); + + Leg leg = TripStructureUtils.getLegs(planAgent.getCurrentPlan()).get(1); + + prebookingManager.cancel(leg); + } + } + }; + })); + } + }); + + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personOk"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2061.0, requestInfo.pickupTime, 1e-3); + assertEquals(2272.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personLate"); + assertEquals(0.0, requestInfo.submissionTimes.get(0), 1e-3); + // agent tries a non-prebooked request upon arrival + assertEquals(4000.0, requestInfo.submissionTimes.get(1), 1e-3); + assertTrue(requestInfo.rejected); + } + } + + @Test + void cancelLateTest() { + /* + * One person requests to depart at 2000 and also is there at 2000. Another + * person asks also to depart at 2000, but only arrives at 4000, i.e. the person + * has 1000s delay. + * + * In this test we manually cancel the second request at 3000.0 (so after + * departure of the first agent). + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .addRequest("personOk", 0, 0, 5, 5, 2000.0, 0.0, 2000.0) // + .addRequest("personLate", 0, 0, 5, 5, 4000.0, 0.0, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + PrebookingTest.installPrebooking(controller); + + controller.addOverridingQSimModule(new AbstractDvrpModeQSimModule("drt") { + @Override + protected void configureQSim() { + addModalQSimComponentBinding().toProvider(modalProvider(getter -> { + PrebookingManager prebookingManager = getter.getModal(PrebookingManager.class); + QSim qsim = getter.get(QSim.class); + + return new MobsimBeforeSimStepListener() { + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + if (e.getSimulationTime() == 3000.0) { + PlanAgent planAgent = (PlanAgent) qsim.getAgents() + .get(Id.createPersonId("personLate")); + + Leg leg = TripStructureUtils.getLegs(planAgent.getCurrentPlan()).get(1); + + prebookingManager.cancel(leg); + } + } + }; + })); + } + }); + + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personOk"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2061.0, requestInfo.pickupTime, 1e-3); + assertEquals(3212.0, requestInfo.dropoffTime, 1e-3); // still waited quite a bit + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("personLate"); + assertEquals(0.0, requestInfo.submissionTimes.get(0), 1e-3); + // agent tries a non-prebooked request upon arrival + assertEquals(4000.0, requestInfo.submissionTimes.get(1), 1e-3); + assertTrue(requestInfo.rejected); + } + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/ComplexUnschedulerTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/ComplexUnschedulerTest.java new file mode 100644 index 00000000000..93a59a769bd --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/ComplexUnschedulerTest.java @@ -0,0 +1,688 @@ +package org.matsim.contrib.drt.prebooking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.NetworkFactory; +import org.matsim.api.core.v01.network.Node; +import org.matsim.contrib.drt.optimizer.VehicleDataEntryFactoryImpl; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.passenger.AcceptedDrtRequest; +import org.matsim.contrib.drt.prebooking.unscheduler.ComplexRequestUnscheduler; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.schedule.DefaultDrtStopTask; +import org.matsim.contrib.drt.schedule.DrtDriveTask; +import org.matsim.contrib.drt.schedule.DrtStayTask; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.schedule.DrtTaskFactoryImpl; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleImpl; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleLookup; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleSpecification; +import org.matsim.contrib.dvrp.fleet.ImmutableDvrpVehicleSpecification; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.path.DivertedVrpPath; +import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.path.VrpPaths; +import org.matsim.contrib.dvrp.schedule.DriveTask; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.schedule.StayTask; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; +import org.matsim.contrib.dvrp.util.LinkTimePair; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.router.DijkstraFactory; +import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.TravelTime; +import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; +import org.mockito.Mockito; + +/** + * @author Sebastian Hörl (sebhoerl) / IRT SystemX + */ +public class ComplexUnschedulerTest { + @Test + void testDirectDropoffAfterPickup() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest1); + fixture.addDrive("f20"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest2); + fixture.addDrive("f30"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); + fixture.addDrive("f50"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addDropoffRequest(otherRequest2); + fixture.addDrive("f60"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest1); + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(100.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(13, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 10001.0), // 0 + new ReferenceTask(DrtStayTask.class, 10001.0, 10301.0), // 1 + new ReferenceTask(DefaultDrtStopTask.class, 10301.0, 10361.0), // 2 + new ReferenceTask(DrtDriveTask.class, 10361.0, 20362.0), // 3 + new ReferenceTask(DrtStayTask.class, 20362.0, 20662.0), // 4 + new ReferenceTask(DefaultDrtStopTask.class, 20662.0, 20722.0), // 5 + new ReferenceTask(DrtDriveTask.class, 20722.0, 50723.0), // 6 + new ReferenceTask(DrtStayTask.class, 50723.0, 51745.0), // 7 + new ReferenceTask(DefaultDrtStopTask.class, 51745.0, 51805.0), // 8 + new ReferenceTask(DrtDriveTask.class, 51805.0, 61806.0), // 9 + new ReferenceTask(DrtStayTask.class, 61806.0, 62106.0), // 10 + new ReferenceTask(DefaultDrtStopTask.class, 62106.0, 62166.0), // 11 + new ReferenceTask(DrtStayTask.class, 62166.0, 30.0 * 3600.0) // 12 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(6); + assertEquals("f20", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f50", insertedDriveTask.getPath().getToLink().getId().toString()); + } + + @Test + void testStandardSituation() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest1); // f10 + fixture.addDrive("f20"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f20 + fixture.addDrive("f30"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addPickupRequest(otherRequest2); // f30 + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest2); // f40 + fixture.addDrive("f50"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addDrive("f60"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addDropoffRequest(otherRequest1); // f60 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(100.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(13, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 10001.0), // 0 + new ReferenceTask(DrtStayTask.class, 10001.0, 10301.0), // 1 + new ReferenceTask(DefaultDrtStopTask.class, 10301.0, 10361.0), // 2 + new ReferenceTask(DrtDriveTask.class, 10361.0, 30362.0), // 3 + new ReferenceTask(DrtStayTask.class, 30362.0, 31023.0), // 4 + new ReferenceTask(DefaultDrtStopTask.class, 31023.0, 31083.0), // 5 + new ReferenceTask(DrtDriveTask.class, 31083.0, 41084.0), // 6 + new ReferenceTask(DrtStayTask.class, 41084.0, 41384.0), // 7 + new ReferenceTask(DefaultDrtStopTask.class, 41384.0, 41444.0), // 8 + new ReferenceTask(DrtDriveTask.class, 41444.0, 61445.0), // 9 + new ReferenceTask(DrtStayTask.class, 61445.0, 62106.0), // 10 + new ReferenceTask(DefaultDrtStopTask.class, 62106.0, 62166.0), // 11 + new ReferenceTask(DrtStayTask.class, 62166.0, 30.0 * 3600.0) // 12 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(3); + assertEquals("f10", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f30", insertedDriveTask.getPath().getToLink().getId().toString()); + + DrtDriveTask insertedDriveTask2 = (DrtDriveTask) schedule.getTasks().get(9); + assertEquals("f40", insertedDriveTask2.getPath().getFromLink().getId().toString()); + assertEquals("f60", insertedDriveTask2.getPath().getToLink().getId().toString()); + } + + @Test + void testRemoveAtEnd() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest1); // f10 + fixture.addDrive("f20"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f20 + fixture.addDrive("f30"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addPickupRequest(otherRequest2); // f30 + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest2); // f40 + fixture.addDrive("f50"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest1); // f50 + fixture.addDrive("f60"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f60 // replace end + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(100.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 10001.0), // 0 + new ReferenceTask(DrtStayTask.class, 10001.0, 10301.0), // 1 + new ReferenceTask(DefaultDrtStopTask.class, 10301.0, 10361.0), // 2 + new ReferenceTask(DrtDriveTask.class, 10361.0, 30362.0), // 3 + new ReferenceTask(DrtStayTask.class, 30362.0, 31023.0), // 4 + new ReferenceTask(DefaultDrtStopTask.class, 31023.0, 31083.0), // 5 + new ReferenceTask(DrtDriveTask.class, 31083.0, 41084.0), // 6 + new ReferenceTask(DrtStayTask.class, 41084.0, 41384.0), // 7 + new ReferenceTask(DefaultDrtStopTask.class, 41384.0, 41444.0), // 8 + new ReferenceTask(DrtDriveTask.class, 41444.0, 51445.0), // 9 + new ReferenceTask(DrtStayTask.class, 51445.0, 51745.0), // 10 + new ReferenceTask(DefaultDrtStopTask.class, 51745.0, 51805.0), // 11 + new ReferenceTask(DrtStayTask.class, 51805.0, 30.0 * 3600.0) // 12 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(3); + assertEquals("f10", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f30", insertedDriveTask.getPath().getToLink().getId().toString()); + + DrtDriveTask insertedDriveTask2 = (DrtDriveTask) schedule.getTasks().get(9); + assertEquals("f40", insertedDriveTask2.getPath().getFromLink().getId().toString()); + assertEquals("f50", insertedDriveTask2.getPath().getToLink().getId().toString()); + + DrtStayTask stayTask = (DrtStayTask) schedule.getTasks().get(12); + assertEquals("f50", stayTask.getLink().getId().toString()); + } + + @Test + void testRemoveAtBeginningWithWaitSecond() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); // replace start + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f10 + fixture.addDrive("f20"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addPickupRequest(otherRequest1); // f20 + fixture.addDrive("f30"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest2); // f30 + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest2); // f40 + fixture.addDrive("f50"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addDrive("f60"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addDropoffRequest(otherRequest1); // f60 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(10100.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(15, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 10001.0), // 0 + new ReferenceTask(DrtStayTask.class, 10001.0, 10100.0), // 1 + new ReferenceTask(DrtDriveTask.class, 10100.0, 20101.0), // 2 + new ReferenceTask(DrtStayTask.class, 20101.0, 20662.0), // 3 + new ReferenceTask(DefaultDrtStopTask.class, 20662.0, 20722.0), // 4 + new ReferenceTask(DrtDriveTask.class, 20722.0, 30723.0), // 5 + new ReferenceTask(DrtStayTask.class, 30723.0, 31023.0), // 6 + new ReferenceTask(DefaultDrtStopTask.class, 31023.0, 31083.0), // 7 + new ReferenceTask(DrtDriveTask.class, 31083.0, 41084.0), // 8 + new ReferenceTask(DrtStayTask.class, 41084.0, 41384.0), // 9 + new ReferenceTask(DefaultDrtStopTask.class, 41384.0, 41444.0), // 10 + new ReferenceTask(DrtDriveTask.class, 41444.0, 61445.0), // 11 + new ReferenceTask(DrtStayTask.class, 61445.0, 62106.0), // 12 + new ReferenceTask(DefaultDrtStopTask.class, 62106.0, 62166.0), // 13 + new ReferenceTask(DrtStayTask.class, 62166.0, 30.0 * 3600.0) // 14 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(2); + assertEquals("f10", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f20", insertedDriveTask.getPath().getToLink().getId().toString()); + + DrtDriveTask insertedDriveTask2 = (DrtDriveTask) schedule.getTasks().get(11); + assertEquals("f40", insertedDriveTask2.getPath().getFromLink().getId().toString()); + assertEquals("f60", insertedDriveTask2.getPath().getToLink().getId().toString()); + } + + @Test + void testRemoveAtBeginningWithWaitFirst() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addWait(300.0); // replace start + fixture.addDrive("f10"); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f10 + fixture.addDrive("f20"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addPickupRequest(otherRequest1); // f20 + fixture.addDrive("f30"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest2); // f30 + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest2); // f40 + fixture.addDrive("f50"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addDrive("f60"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addDropoffRequest(otherRequest1); // f60 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(500.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(14, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtStayTask.class, 0.0, 500.0), // 0 + new ReferenceTask(DrtDriveTask.class, 500.0, 20501.0), // 1 + new ReferenceTask(DrtStayTask.class, 20501.0, 20662.0), // 2 + new ReferenceTask(DefaultDrtStopTask.class, 20662.0, 20722.0), // 3 + new ReferenceTask(DrtDriveTask.class, 20722.0, 30723.0), // 4 + new ReferenceTask(DrtStayTask.class, 30723.0, 31023.0), // 5 + new ReferenceTask(DefaultDrtStopTask.class, 31023.0, 31083.0), // 6 + new ReferenceTask(DrtDriveTask.class, 31083.0, 41084.0), // 7 + new ReferenceTask(DrtStayTask.class, 41084.0, 41384.0), // 8 + new ReferenceTask(DefaultDrtStopTask.class, 41384.0, 41444.0), // 9 + new ReferenceTask(DrtDriveTask.class, 41444.0, 61445.0), // 10 + new ReferenceTask(DrtStayTask.class, 61445.0, 62106.0), // 11 + new ReferenceTask(DefaultDrtStopTask.class, 62106.0, 62166.0), // 12 + new ReferenceTask(DrtStayTask.class, 62166.0, 30.0 * 3600.0) // 13 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(1); + assertEquals("f0", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f20", insertedDriveTask.getPath().getToLink().getId().toString()); + + DrtDriveTask insertedDriveTask2 = (DrtDriveTask) schedule.getTasks().get(10); + assertEquals("f40", insertedDriveTask2.getPath().getFromLink().getId().toString()); + assertEquals("f60", insertedDriveTask2.getPath().getToLink().getId().toString()); + } + + @Test + void testRemoveAtBeginningWithDriveDiversion() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest otherRequest1 = fixture.createRequest(); + AcceptedDrtRequest otherRequest2 = fixture.createRequest(); + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); // replace start + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f10 + fixture.addDrive("f20"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addPickupRequest(otherRequest1); // f20 + fixture.addDrive("f30"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(otherRequest2); // f30 + fixture.addDrive("f40"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(otherRequest2); // f40 + fixture.addDrive("f50"); // replace start + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addDrive("f60"); + fixture.addWait(300.0); // replace end + fixture.addStop(60.0).addDropoffRequest(otherRequest1); // f60 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + + OnlineDriveTaskTracker tracker = Mockito.mock(OnlineDriveTaskTracker.class); + schedule.getTasks().get(0).initTaskTracker(tracker); + + LinkTimePair diversionPoint = new LinkTimePair(fixture.network.getLinks().get(Id.createLinkId("f5")), 20.0); + Mockito.when(tracker.getDiversionPoint()).thenReturn(diversionPoint); + + Mockito.doAnswer(invocation -> { + VrpPathWithTravelData path = invocation.getArgument(0); + DriveTask task = (DriveTask) schedule.getTasks().get(0); + DivertedVrpPath divertedPath = new DivertedVrpPath(task.getPath(), path, 5); + task.pathDiverted(divertedPath, path.getArrivalTime()); + return null; + }).when(tracker).divertPath(Mockito.any()); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(500.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(13, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 15019.0), // 0 + new ReferenceTask(DrtStayTask.class, 15019.0, 20662.0), // 1 + new ReferenceTask(DefaultDrtStopTask.class, 20662.0, 20722.0), // 2 + new ReferenceTask(DrtDriveTask.class, 20722.0, 30723.0), // 3 + new ReferenceTask(DrtStayTask.class, 30723.0, 31023.0), // 4 + new ReferenceTask(DefaultDrtStopTask.class, 31023.0, 31083.0), // 5 + new ReferenceTask(DrtDriveTask.class, 31083.0, 41084.0), // 6 + new ReferenceTask(DrtStayTask.class, 41084.0, 41384.0), // 7 + new ReferenceTask(DefaultDrtStopTask.class, 41384.0, 41444.0), // 8 + new ReferenceTask(DrtDriveTask.class, 41444.0, 61445.0), // 9 + new ReferenceTask(DrtStayTask.class, 61445.0, 62106.0), // 10 + new ReferenceTask(DefaultDrtStopTask.class, 62106.0, 62166.0), // 11 + new ReferenceTask(DrtStayTask.class, 62166.0, 30.0 * 3600.0) // 12 + )); + + DrtDriveTask insertedDriveTask = (DrtDriveTask) schedule.getTasks().get(0); + assertEquals("f0", insertedDriveTask.getPath().getFromLink().getId().toString()); + assertEquals("f20", insertedDriveTask.getPath().getToLink().getId().toString()); + + DrtDriveTask insertedDriveTask2 = (DrtDriveTask) schedule.getTasks().get(9); + assertEquals("f40", insertedDriveTask2.getPath().getFromLink().getId().toString()); + assertEquals("f60", insertedDriveTask2.getPath().getToLink().getId().toString()); + } + + @Test + void testRemoveAllStartWithWait() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addWait(300.0); + fixture.addDrive("f10"); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f10 + fixture.addDrive("f20"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(0.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(2, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtStayTask.class, 0.0, 0.0), // 0 + new ReferenceTask(DrtStayTask.class, 0.0, 30.0 * 3600.0) // 1 + )); + + assertEquals("f0", ((StayTask) schedule.getTasks().get(0)).getLink().getId().toString()); + assertEquals("f0", ((StayTask) schedule.getTasks().get(1)).getLink().getId().toString()); + } + + @Test + void testRemoveAllStartWithDrive() { + Fixture fixture = new Fixture(); + Schedule schedule = fixture.schedule; + + AcceptedDrtRequest unscheduleRequest = fixture.createRequest(); + + fixture.addDrive("f10"); + fixture.addWait(300.0); + fixture.addStop(60.0).addPickupRequest(unscheduleRequest); // f10 + fixture.addDrive("f20"); + fixture.addWait(300.0); + fixture.addStop(60.0).addDropoffRequest(unscheduleRequest); // f50 + fixture.addFinalStay(30.0 * 3600.0); + + schedule.nextTask(); + + OnlineDriveTaskTracker tracker = Mockito.mock(OnlineDriveTaskTracker.class); + schedule.getTasks().get(0).initTaskTracker(tracker); + + LinkTimePair diversionPoint = new LinkTimePair(fixture.network.getLinks().get(Id.createLinkId("f5")), 20.0); + Mockito.when(tracker.getDiversionPoint()).thenReturn(diversionPoint); + + Mockito.doAnswer(invocation -> { + VrpPathWithTravelData path = invocation.getArgument(0); + DriveTask task = (DriveTask) schedule.getTasks().get(0); + DivertedVrpPath divertedPath = new DivertedVrpPath(task.getPath(), path, 5); + task.pathDiverted(divertedPath, path.getArrivalTime()); + return null; + }).when(tracker).divertPath(Mockito.any()); + + ComplexRequestUnscheduler unscheduler = new ComplexRequestUnscheduler(fixture.lookup, fixture.entryFactory, + fixture.taskFactory, fixture.router, fixture.travelTime, fixture.timingUpdater, false); + + unscheduler.unscheduleRequest(0.0, fixture.vehicle.getId(), unscheduleRequest.getId()); + + assertEquals(2, schedule.getTaskCount()); + + assertTasks(schedule, Arrays.asList( // + new ReferenceTask(DrtDriveTask.class, 0.0, 19.0), // 0 + new ReferenceTask(DrtStayTask.class, 19.0, 30.0 * 3600.0) // 1 + )); + + DrtDriveTask driveTask = (DrtDriveTask) schedule.getTasks().get(0); + assertEquals("f0", driveTask.getPath().getFromLink().getId().toString()); + assertEquals("f5", driveTask.getPath().getToLink().getId().toString()); + + assertEquals("f5", ((StayTask) schedule.getTasks().get(1)).getLink().getId().toString()); + } + + record ReferenceTask(Class taskType, double startTime, double endTime) { + } + + private static void assertTasks(Schedule schedule, List references) { + for (int i = 0; i < references.size(); i++) { + Task task = schedule.getTasks().get(i); + ReferenceTask reference = references.get(i); + + assertEquals(reference.taskType, task.getClass(), "wrong type in task " + i); + assertEquals(reference.startTime, task.getBeginTime(), 1e-3, "wrong begin time in task " + i); + assertEquals(reference.endTime, task.getEndTime(), 1e-3, "wrong end time in task " + i); + + if (i > 0) { + assertEquals(schedule.getTasks().get(i).getBeginTime(), + schedule.getTasks().get(i - 1).getEndTime(), 1e-3, "wrong transition from " + (i - 1) + " to " + i); + } + + assertTrue(task.getEndTime() >= task.getBeginTime(), "invalid task " + i); + } + } + + private Network createNetwork() { + Network network = NetworkUtils.createNetwork(); + NetworkFactory networkFactory = network.getFactory(); + + List nodes = new LinkedList<>(); + + for (int i = 0; i < 100; i++) { + Node node = networkFactory.createNode(Id.createNodeId("n" + i), new Coord(0.0, i * 1000.0)); + network.addNode(node); + nodes.add(node); + } + + for (int i = 0; i < 99; i++) { + Link forwardLink = networkFactory.createLink(Id.createLinkId("f" + i), nodes.get(i), nodes.get(i + 1)); + network.addLink(forwardLink); + + Link backwardLink = networkFactory.createLink(Id.createLinkId("b" + i), nodes.get(i + 1), nodes.get(i)); + network.addLink(backwardLink); + } + + for (Link link : network.getLinks().values()) { + link.setAllowedModes(Collections.singleton("car")); + link.setLength(1000.0); + link.setFreespeed(1.0); + } + + return network; + } + + private class Fixture { + private final DvrpVehicle vehicle; + private final Schedule schedule; + private final Network network; + + private Link currentLink; + private double currentTime; + + private final DrtTaskFactory taskFactory = new DrtTaskFactoryImpl(); + private final LeastCostPathCalculator router; + private final TravelTime travelTime = new FreeSpeedTravelTime(); + + private final VehicleEntry.EntryFactory entryFactory; + private final ScheduleTimingUpdater timingUpdater; + private final DvrpVehicleLookup lookup; + + private int requestIndex = 0; + + Fixture() { + this.network = createNetwork(); + + Link depotLink = network.getLinks().get(Id.createLinkId("f0")); + + DvrpVehicleSpecification vehicleSpecification = ImmutableDvrpVehicleSpecification.newBuilder() // + .id(Id.create("vehicle", DvrpVehicle.class)) // + .capacity(4) // + .serviceBeginTime(0.0) // + .serviceEndTime(30.0 * 3600.0) // + .startLinkId(depotLink.getId()) // + .build(); + + this.vehicle = new DvrpVehicleImpl(vehicleSpecification, depotLink); + this.schedule = vehicle.getSchedule(); + this.currentLink = vehicle.getStartLink(); + this.currentTime = 0.0; + this.router = new DijkstraFactory().createPathCalculator(network, + new OnlyTimeDependentTravelDisutility(travelTime), travelTime); + + this.lookup = Mockito.mock(DvrpVehicleLookup.class); + Mockito.when(this.lookup.lookupVehicle(Mockito.any())).thenReturn(vehicle); + + DrtConfigGroup drtConfig = new DrtConfigGroup(); + drtConfig.stopDuration = 30.0; + drtConfig.maxWaitTime = 600.0; + + this.entryFactory = new VehicleDataEntryFactoryImpl(); + + this.timingUpdater = Mockito.mock(ScheduleTimingUpdater.class); + } + + AcceptedDrtRequest createRequest() { + AcceptedDrtRequest request = Mockito.mock(AcceptedDrtRequest.class); + Mockito.when(request.getId()).thenReturn(Id.create("req_" + requestIndex++, Request.class)); + return request; + } + + DrtStayTask addWait(double duration) { + DrtStayTask task = taskFactory.createStayTask(vehicle, currentTime, currentTime + duration, currentLink); + schedule.addTask(task); + + currentTime += duration; + return task; + } + + DrtStayTask addStay(double duration) { + DrtStayTask task = taskFactory.createStayTask(vehicle, currentTime, currentTime + duration, currentLink); + schedule.addTask(task); + + currentTime += duration; + return task; + } + + DrtStayTask addFinalStay(double until) { + DrtStayTask task = taskFactory.createStayTask(vehicle, currentTime, Math.max(currentTime, until), + currentLink); + schedule.addTask(task); + + currentTime = Math.max(currentTime, until); + return task; + } + + DrtStopTask addStop(double duration) { + DrtStopTask task = taskFactory.createStopTask(vehicle, currentTime, currentTime + duration, currentLink); + schedule.addTask(task); + currentTime += duration; + return task; + } + + DrtDriveTask addDrive(String destinationLinkId) { + Link destinationLink = network.getLinks().get(Id.createLinkId(destinationLinkId)); + + VrpPathWithTravelData path = VrpPaths.calcAndCreatePath(currentLink, destinationLink, currentTime, router, + travelTime); + DrtDriveTask driveTask = taskFactory.createDriveTask(vehicle, path, DrtDriveTask.TYPE); + schedule.addTask(driveTask); + + currentTime = driveTask.getEndTime(); + currentLink = destinationLink; + + return driveTask; + } + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PersonStuckPrebookingTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PersonStuckPrebookingTest.java new file mode 100644 index 00000000000..4245cd4b4ca --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PersonStuckPrebookingTest.java @@ -0,0 +1,227 @@ +package org.matsim.contrib.drt.prebooking; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Activity; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.api.core.v01.population.Population; +import org.matsim.api.core.v01.population.PopulationFactory; +import org.matsim.contrib.drt.prebooking.logic.ProbabilityBasedPrebookingLogic; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEvent; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequest; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestValidator; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; +import org.matsim.testcases.MatsimTestUtils; + +/** + * @author Sebastian Hörl (sebhoerl) / IRT SystemX + */ +public class PersonStuckPrebookingTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void baselineTest() { + /* + * Agent personA is performing three drt legs during the day. Agent personB does + * exactly the same in parallel, both prebook their requests. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(20000.0); + + Controler controller = environment.build(); + + implementPopulation(controller.getScenario().getPopulation()); + PrebookingTest.installPrebooking(controller, false); + ProbabilityBasedPrebookingLogic.install(controller, + DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()), 1.0, 20000.0); + + EventCounter eventCounterA = EventCounter.install(controller, Id.createPersonId("personA")); + EventCounter eventCounterB = EventCounter.install(controller, Id.createPersonId("personB")); + + controller.run(); + + assertEquals(3, eventCounterA.submittedCount); + assertEquals(3, eventCounterA.dropoffCount); + + assertEquals(3, eventCounterB.submittedCount); + assertEquals(3, eventCounterB.dropoffCount); + } + + @Test + void cancelTest() { + /* + * Agent personA is performing three drt legs during the day. Agent personB does + * exactly the same in parallel, both prebook there requests. + * + * We cancel the first request of personA. We check that the other reservations + * are automatically rejected as soon as the person is stuck. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicle", 1, 1) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(20000.0); + + Controler controller = environment.build(); + + implementPopulation(controller.getScenario().getPopulation()); + PrebookingTest.installPrebooking(controller, false); + ProbabilityBasedPrebookingLogic.install(controller, + DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()), 1.0, 20000.0); + + EventCounter eventCounterA = EventCounter.install(controller, Id.createPersonId("personA")); + EventCounter eventCounterB = EventCounter.install(controller, Id.createPersonId("personB")); + + controller.addOverridingQSimModule(new AbstractDvrpModeQSimModule("drt") { + @Override + protected void configureQSim() { + addModalQSimComponentBinding().toProvider(modalProvider(getter -> { + PrebookingManager prebookingManager = getter.getModal(PrebookingManager.class); + + return new MobsimBeforeSimStepListener() { + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + if (e.getSimulationTime() == 500.0) { + prebookingManager.cancel(Id.create("drt_prebooked_0", Request.class)); + } + } + }; + })); + + bindModal(PassengerRequestValidator.class).toProvider(modalProvider(getter -> { + return new PassengerRequestValidator() { + @Override + public Set validateRequest(PassengerRequest request) { + if (!request.getId().toString().contains("prebooked")) { + return Collections.singleton("anything"); + } + + return Collections.emptySet(); + } + }; + })); + } + }); + + controller.run(); + + assertEquals(4, eventCounterA.submittedCount); + assertEquals(4, eventCounterA.rejectedCount); + assertEquals(0, eventCounterA.dropoffCount); + + assertEquals(3, eventCounterB.submittedCount); + assertEquals(0, eventCounterB.rejectedCount); + assertEquals(3, eventCounterB.dropoffCount); + } + + private void implementPopulation(Population population) { + PopulationFactory populationFactory = population.getFactory(); + + for (String personId : Arrays.asList("personA", "personB")) { + Person person = populationFactory.createPerson(Id.createPersonId(personId)); + population.addPerson(person); + + Plan plan = populationFactory.createPlan(); + person.addPlan(plan); + + Activity firstActivity = populationFactory.createActivityFromLinkId("generic", Id.createLinkId("1:1-2:1")); + firstActivity.setEndTime(2000.0); + plan.addActivity(firstActivity); + + // departure at 2000 + Leg firstLeg = populationFactory.createLeg("drt"); + plan.addLeg(firstLeg); + + Activity secondActivity = populationFactory.createActivityFromLinkId("generic", Id.createLinkId("5:5-6:5")); + secondActivity.setEndTime(6000.0); + plan.addActivity(secondActivity); + + // departure at 6000 + Leg secondLeg = populationFactory.createLeg("drt"); + plan.addLeg(secondLeg); + + Activity thirdActivity = populationFactory.createActivityFromLinkId("generic", Id.createLinkId("1:1-2:1")); + thirdActivity.setEndTime(10000.0); + plan.addActivity(thirdActivity); + + // departure at 10000 + Leg thirdLeg = populationFactory.createLeg("drt"); + plan.addLeg(thirdLeg); + + Activity finalActivity = populationFactory.createActivityFromLinkId("generic", Id.createLinkId("5:5-6:5")); + plan.addActivity(finalActivity); + } + } + + static private class EventCounter implements PassengerDroppedOffEventHandler, PassengerRequestSubmittedEventHandler, + PassengerRequestRejectedEventHandler { + private final Id personId; + + private EventCounter(Id personId) { + this.personId = personId; + } + + int dropoffCount = 0; + int submittedCount = 0; + int rejectedCount = 0; + + @Override + public void handleEvent(PassengerDroppedOffEvent event) { + if (event.getPersonId().equals(personId)) { + dropoffCount++; + } + } + + @Override + public void handleEvent(PassengerRequestSubmittedEvent event) { + if (event.getPersonIds().contains(personId)) { + submittedCount++; + } + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + if (event.getPersonIds().contains(personId)) { + rejectedCount++; + } + } + + static EventCounter install(Controler controller, Id personId) { + EventCounter instance = new EventCounter(personId); + + controller.addOverridingModule(new AbstractModule() { + + @Override + public void install() { + addEventHandlerBinding().toInstance(instance); + } + }); + + return instance; + } + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingGroupTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingGroupTest.java new file mode 100644 index 00000000000..c609ec084f8 --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingGroupTest.java @@ -0,0 +1,74 @@ +package org.matsim.contrib.drt.prebooking; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.prebooking.logic.AttributeBasedPrebookingLogic; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.passenger.PassengerGroupIdentifier; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.controler.Controler; +import org.matsim.testcases.MatsimTestUtils; + +import java.util.Optional; + + +public class PrebookingGroupTest { + + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); + + + static PrebookingParams installPrebooking(Controler controller) { + return installPrebooking(controller, true); + } + + static PrebookingParams installPrebooking(Controler controller, boolean installLogic) { + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + drtConfig.addParameterSet(new PrebookingParams()); + + if (installLogic) { + AttributeBasedPrebookingLogic.install(controller, drtConfig); + } + controller.addOverridingQSimModule(new AbstractDvrpModeQSimModule(drtConfig.getMode()) { + @Override + protected void configureQSim() { + bindModal(PassengerGroupIdentifier.class).toInstance(agent -> Optional.of(Id.create("group", PassengerGroupIdentifier.PassengerGroup.class))); + } + }); + + return drtConfig.getPrebookingParams().get(); + } + + @Test + public void oneRequestArrivingLate() { + + // copy of prebooking test but with two persons in one request + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + // 1800 indicated but only departing 2000 + .addRequest("personA", 0, 0, 5, 5, 2000.0, 0.0, 2000.0 - 200.0) // + .addRequest("personB", 0, 0, 5, 5, 2000.0, 0.0, 2000.0 - 200.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + PrebookingTestEnvironment.RequestInfo requestInfoA = environment.getRequestInfo().get("personA"); + Assertions.assertEquals(0.0, requestInfoA.submissionTime, 1e-3); + Assertions.assertEquals(2060.0, requestInfoA.pickupTime, 1e-3); + Assertions.assertEquals(2271.0, requestInfoA.dropoffTime, 1e-3); + + PrebookingTestEnvironment.RequestInfo requestInfoB = environment.getRequestInfo().get("personB"); + Assertions.assertEquals(0.0, requestInfoB.submissionTime, 1e-3); + Assertions.assertEquals(2060.0, requestInfoB.pickupTime, 1e-3); + Assertions.assertEquals(2271.0, requestInfoB.dropoffTime, 1e-3); + + // assert both persons are part of same drt request + Assertions.assertEquals(requestInfoA.drtRequestId, requestInfoB.drtRequestId); + } +} + diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java new file mode 100644 index 00000000000..cb149fc1f3b --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java @@ -0,0 +1,482 @@ +package org.matsim.contrib.drt.prebooking; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.contrib.drt.prebooking.PrebookingTestEnvironment.RequestInfo; +import org.matsim.contrib.drt.prebooking.logic.AttributeBasedPrebookingLogic; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.core.controler.Controler; +import org.matsim.testcases.MatsimTestUtils; + +/** + * @author Sebastian Hörl (sebhoerl) / IRT SystemX + */ +public class PrebookingTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void withoutPrebookedRequests() { + /*- + * Standard test running with prebooking but without any prebooked requests + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("personA", 0, 0, 5, 5, 2000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + controller.run(); + + RequestInfo requestInfo = environment.getRequestInfo().get("personA"); + assertEquals(2000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2146.0, requestInfo.pickupTime, 1e-3); + assertEquals(2357.0, requestInfo.dropoffTime, 1e-3); + + var taskInfo = environment.getTaskInfo().get("vehicleA"); + assertEquals("STAY", taskInfo.get(0).type); + assertEquals("DRIVE", taskInfo.get(1).type); + assertEquals("STOP", taskInfo.get(2).type); + assertEquals("DRIVE", taskInfo.get(3).type); + assertEquals("STOP", taskInfo.get(4).type); + + assertEquals(2001.0, taskInfo.get(1).startTime, 1e-3); + + assertEquals(2086.0, taskInfo.get(2).startTime, 1e-3); + assertEquals(2146.0, taskInfo.get(2).endTime, 1e-3); + } + + static PrebookingParams installPrebooking(Controler controller) { + return installPrebooking(controller, true); + } + + static PrebookingParams installPrebooking(Controler controller, boolean installLogic) { + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(controller.getConfig()); + drtConfig.addParameterSet(new PrebookingParams()); + + if (installLogic) { + AttributeBasedPrebookingLogic.install(controller, drtConfig); + } + + return drtConfig.getPrebookingParams().get(); + } + + @Test + void oneRequestArrivingLate() { + /*- + * One request arriving after the requested departure time. Vehicle should wait + * and depart with appropriate delay (taking into account a fixed duration for + * the person to enter instead of a fixed stop duration). + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + // 1800 indicated but only departing 2000 + .addRequest("personA", 0, 0, 5, 5, 2000.0, 0.0, 2000.0 - 200.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + RequestInfo requestInfo = environment.getRequestInfo().get("personA"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2060.0, requestInfo.pickupTime, 1e-3); + assertEquals(2271.0, requestInfo.dropoffTime, 1e-3); + + var taskInfo = environment.getTaskInfo().get("vehicleA"); + assertEquals("STAY", taskInfo.get(0).type); + assertEquals("DRIVE", taskInfo.get(1).type); + assertEquals("STAY", taskInfo.get(2).type); + assertEquals("STOP", taskInfo.get(3).type); + assertEquals("DRIVE", taskInfo.get(4).type); + assertEquals("STOP", taskInfo.get(5).type); + + assertEquals(1.0, taskInfo.get(1).startTime, 1e-3); // Pickup drive + assertEquals(86.0, taskInfo.get(2).startTime, 1e-3); // Starting to wait + assertEquals(1800.0, taskInfo.get(3).startTime, 1e-3); // Starting stop + assertEquals(2060.0, taskInfo.get(3).endTime, 1e-3); // Ending stop (260s duration) + assertEquals(2060.0, taskInfo.get(4).startTime, 1e-3); // Starting drive (ending stop) + } + + @Test + void oneRequestArrivingEarly() { + /*- + * One request arriving in advance before the requested departure time. Vehicle + * will pickup up agent and then depart after the duration to enter the vehicle. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + // 2200 indicated but already departing 2000 + .addRequest("personA", 0, 0, 5, 5, 2000.0, 0.0, 2000.0 + 200.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + RequestInfo requestInfo = environment.getRequestInfo().get("personA"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2260.0 + 1.0, requestInfo.pickupTime, 1e-3); // One second for notifying vehicle + assertEquals(2472.0, requestInfo.dropoffTime, 1e-3); + + var taskInfo = environment.getTaskInfo().get("vehicleA"); + assertEquals("STAY", taskInfo.get(0).type); + assertEquals("DRIVE", taskInfo.get(1).type); + assertEquals("STAY", taskInfo.get(2).type); + assertEquals("STOP", taskInfo.get(3).type); + assertEquals("DRIVE", taskInfo.get(4).type); + assertEquals("STOP", taskInfo.get(5).type); + + assertEquals(1.0, taskInfo.get(1).startTime, 1e-3); // Pickup drive + assertEquals(86.0, taskInfo.get(2).startTime, 1e-3); // Starting to wait + assertEquals(2200.0, taskInfo.get(3).startTime, 1e-3); // Starting stop + assertEquals(2261.0, taskInfo.get(3).endTime, 1e-3); // Ending stop (60s) + assertEquals(2261.0, taskInfo.get(4).startTime, 1e-3); // Starting drive (ending stop) + } + + @Test + void twoSequentialRequests() { + /*- + * Two requests that are scheduled in advance. + * - First the early one is submitted, then the late one + * - First the early one is picked up and dropped off, then the late one. + */ + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("earlyRequest", 0, 0, 5, 5, 2000.0, 0.0) // + .addRequest("lateRequest", 2, 2, 3, 3, 4000.0, 1000.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("earlyRequest"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2272.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("lateRequest"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(4000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(4104.0, requestInfo.dropoffTime, 1e-3); + } + } + + @Test + void twoSequentialRequests_inverseSubmission() { + /*- + * Two requests that are scheduled in advance. + * - First the late one is submitted, then the early one (inverse of above test). + * - First the early one is picked up and dropped off, then the late one. + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("earlyRequest", 0, 0, 5, 5, 2000.0, 1000.0) // + .addRequest("lateRequest", 2, 2, 3, 3, 4000.0, 0.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("earlyRequest"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2272.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("lateRequest"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(4000.0 + 60.0, requestInfo.pickupTime, 1e-3); + assertEquals(4103.0, requestInfo.dropoffTime, 1e-3); + } + } + + @Test + void sameTrip_differentDepartureTime() { + /*- + * Two requests with the same origin and destination, but distinct departure time. + * - First, early one is submitted, then late one. + * - Vehicle picks up and drops off early one, then late one. + * - In total four stops (P,D,P,D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("earlyRequest", 1, 1, 5, 5, 2000.0, 1000.0) // + .addRequest("lateRequest", 1, 1, 5, 5, 4000.0, 1100.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("earlyRequest"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2230.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("lateRequest"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + assertEquals(4000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(4230.0, requestInfo.dropoffTime, 1e-3); + } + + // Four stops, 2x pickup, 2x dropoff + assertEquals(4, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } + + @Test + void sameTrip_sameDepartureTime() { + /*- + * Two requests with the same origin and destination, and same departure time. + * - First, A is submitted, then B. + * - Vehicle picks up and A and B, then drops off A and B. + * - In total two stops (P,D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("requestA", 1, 1, 5, 5, 2000.0, 1000.0) // + .addRequest("requestB", 1, 1, 5, 5, 2000.0, 1100.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestA"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2230.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestB"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2230.0, requestInfo.dropoffTime, 1e-3); + } + + // Two stops, 1x pickup, 1x dropoff + assertEquals(2, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } + + @Test + void sameTrip_extendPickupDuration() { + /*- + * Two requests with the same origin and destination, different departure times. + * - First, A is submitted with departure time 2000 + * - Then, B is submitted with departure time 2020 + * - Scheduling A then B would give a total duration of 60 + 60 = 120s stop duration + * - Scheduling A then merging in B gives a total duration of 60 + 20 = 80s stop duration + * - Expected behavior is to merge the requests + * - In total two stops (P,D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("requestA", 1, 1, 5, 5, 2000.0, 1000.0) // + .addRequest("requestB", 1, 1, 5, 5, 2020.0, 1100.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestA"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + // We always add 1s for first pickup + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + // We have additional 19s because stop task is extended! + assertEquals(2230.0 + 19.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestB"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + // Second pickup does not have one second offset + assertEquals(2020.0 + 60.0 + 0.0, requestInfo.pickupTime, 1e-3); + assertEquals(2230.0 + 19.0, requestInfo.dropoffTime, 1e-3); + } + + // Two stops, 1x pickup, 1x dropoff + assertEquals(2, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } + + @Test + void sameTrip_splitPickup() { + /*- + * Two requests with the same origin and destination, different departure times. + * - First, A is submitted with departure time 2000 + * - Then, B is submitted with departure time 2080 + * - Stop for A goes from 2000 to 2060 + * - Stop for B goes from 2080 to 20140 + * - The requests don't overlap, so we schedule individual stops (in a more extreme use case we could schedule things in between then) + * - In total three stops (P, P, D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("requestA", 1, 1, 5, 5, 2000.0, 1000.0) // + .addRequest("requestB", 1, 1, 5, 5, 2080.0, 1100.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestA"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + // Pickup as planned + assertEquals(2000.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + + // Dropoff a bit later than before because we pickup another one on the way + assertEquals(2310.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestB"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + // We insert a later pickup + assertEquals(2080.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + + // Dropoff as planned + assertEquals(2310.0, requestInfo.dropoffTime, 1e-3); + } + + // Three stops, 2x pickup, 1x dropoff + assertEquals(3, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } + + @Test + void sameTrip_inverseSubmission_noPrepending() { + /*- + * Two requests with the same origin and destination, different departure times. + * - First, A is submitted with departure time 2020 + * - Then, B is submitted with departure time 2000 + * + * - This is inverse of sameTrip_extendPickupDuration above, the request with the earlier departure + * time is submitted second. + * - We would expect the requests to be merged, but this is not so trivial with the current code base: + * It would be necessary to shift the stop task to the past and extend it. Theoretically, this is + * possible but it would be nice to embed this in a more robust way in the code base. + * - Plus, it may change the current DRT behavior because we have these situations also in non-prebooked + * simulations: We may submit an immediate request and find an insertion for a stop task that starts + * in 5 seconds. This case is treated in standard DRT as any other request (extending the task but + * keeping the start time fixed). + * - We follow this default behaviour here: Instead of *prepending* the task with the new request, we + * *append* it as usual. If there is at least one pickup in the stop task with the standard stop + * durations, there is no additional cost of adding the request, but the person experiences a wait + * delay that could be minimized if we were able to prepend the task. + * - (Then again, do we actually want to do this, it would reserve the vehicle a few seconds more than + * necessary for a stop that is potentially prebooked in a long time). + * + * - Expected behavior in current implementation: Merge new request with the later departing existing + * one, which generates wait time for the customer. + * + * - In total two stops (P, D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("requestA", 1, 1, 5, 5, 2020.0, 1000.0) // + .addRequest("requestB", 1, 1, 5, 5, 2000.0, 1100.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestA"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2020.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2250.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestB"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + assertEquals(2000.0 + 20.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2250.0, requestInfo.dropoffTime, 1e-3); + } + + // Three stops, 1x pickup, 1x dropoff + assertEquals(2, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } + + @Test + void sameTrip_inverseSubmission_splitPickup() { + /*- + * Two requests with the same origin and destination, different departure times. + * - First, A is submitted with departure time 2020 + * - Then, B is submitted with departure time 1770 + * - B's departure is 250s before A, so appending it to A would lead to more than 300s + * of wait time, which is not a valid insertion + * - Hence, the insertion *after* the pickup of A is not valid + * - But the insertion *before* A is possible (it is usually evaluated but dominated by the insertion after) + * - TODO: May think this through and eliminate these insertion upfront + * + * - Expectation: Standard scheduling a prebooked request before another one (as if they had not the + * same origin link). + * - In total three stops (P,P,D) + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + .addRequest("requestA", 1, 1, 5, 5, 2020.0, 1000.0) // + .addRequest("requestB", 1, 1, 5, 5, 1470.0, 1100.0) // + .configure(300.0, 2.0, 1800.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + controller.run(); + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestA"); + assertEquals(1000.0, requestInfo.submissionTime, 1e-3); + assertEquals(2020.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2249.0 + 1.0, requestInfo.dropoffTime, 1e-3); + } + + { + RequestInfo requestInfo = environment.getRequestInfo().get("requestB"); + assertEquals(1100.0, requestInfo.submissionTime, 1e-3); + assertEquals(1470.0 + 60.0 + 1.0, requestInfo.pickupTime, 1e-3); + assertEquals(2249.0 + 1.0, requestInfo.dropoffTime, 1e-3); + } + + // Three stops, 2x pickup, 1x dropoff + assertEquals(3, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java new file mode 100644 index 00000000000..a80d8a42386 --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTestEnvironment.java @@ -0,0 +1,439 @@ +package org.matsim.contrib.drt.prebooking; + +import org.apache.commons.lang3.tuple.Pair; +import org.matsim.api.core.v01.Coord; +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.network.Network; +import org.matsim.api.core.v01.network.NetworkFactory; +import org.matsim.api.core.v01.network.Node; +import org.matsim.api.core.v01.population.*; +import org.matsim.contrib.drt.optimizer.insertion.DrtInsertionSearchParams; +import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchParams; +import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; +import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEventHandler; +import org.matsim.contrib.drt.prebooking.logic.AttributeBasedPrebookingLogic; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.drt.routing.DrtRouteFactory; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.DrtConfigs; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtModule; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.contrib.dvrp.fleet.FleetSpecificationImpl; +import org.matsim.contrib.dvrp.fleet.ImmutableDvrpVehicleSpecification; +import org.matsim.contrib.dvrp.passenger.*; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpModule; +import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.contrib.dvrp.vrpagent.TaskEndedEvent; +import org.matsim.contrib.dvrp.vrpagent.TaskEndedEventHandler; +import org.matsim.contrib.dvrp.vrpagent.TaskStartedEvent; +import org.matsim.contrib.dvrp.vrpagent.TaskStartedEventHandler; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.QSimConfigGroup.EndtimeInterpretation; +import org.matsim.core.config.groups.QSimConfigGroup.StarttimeInterpretation; +import org.matsim.core.config.groups.ScoringConfigGroup.ActivityParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.testcases.MatsimTestUtils; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class PrebookingTestEnvironment { + private final MatsimTestUtils utils; + + private final int width = 10; + private final int height = 10; + + private final double edgeLength = 200.0; + private final double speed = 10.0; + + private int vehicleCapacity = 4; + + private double maximumWaitTime = 3600.0; + private double detourRelative = 1.3; + private double detourAbsolute = 300.0; + private double stopDuration = 60.0; + private double endTime = 30.0 * 3600.0; + + public PrebookingTestEnvironment(MatsimTestUtils utils) { + this.utils = utils; + } + + public PrebookingTestEnvironment configure(double maximumWaitTime, double detourRelative, double detourAbsolute, + double stopDuration) { + this.maximumWaitTime = maximumWaitTime; + this.detourRelative = detourRelative; + this.detourAbsolute = detourAbsolute; + this.stopDuration = stopDuration; + return this; + } + + public PrebookingTestEnvironment endTime(double endTime) { + this.endTime = endTime; + return this; + } + + private class Request { + String personId; + + Pair origin = null; + Pair destination = null; + + double departureTime; + double submissionTime; + double plannedDepartureTime; + } + + List requests = new LinkedList<>(); + + public PrebookingTestEnvironment addRequest(String personId, int originX, int originY, int destinationX, + int destinationY, double departureTime, double submissionTime, double plannedDepartureTime) { + Request request = new Request(); + request.personId = personId; + request.origin = Pair.of(originX, originY); + request.destination = Pair.of(destinationX, destinationY); + request.departureTime = departureTime; + request.submissionTime = submissionTime; + request.plannedDepartureTime = plannedDepartureTime; + requests.add(request); + return this; + } + + public PrebookingTestEnvironment addRequest(String personId, int originX, int originY, int destinationX, + int destinationY, double departureTime, double submissionTime) { + return addRequest(personId, originX, originY, destinationX, destinationY, departureTime, submissionTime, + Double.NaN); + } + + public PrebookingTestEnvironment addRequest(String personId, int originX, int originY, int destinationX, + int destinationY, double departureTime) { + return addRequest(personId, originX, originY, destinationX, destinationY, departureTime, Double.NaN, + Double.NaN); + } + + private class Vehicle { + String vehicleId; + Pair depot; + } + + private List vehicles = new LinkedList<>(); + + public PrebookingTestEnvironment addVehicle(String vehicleId, int depotX, int depotY) { + Vehicle vehicle = new Vehicle(); + vehicle.vehicleId = vehicleId; + vehicle.depot = Pair.of(depotX, depotY); + vehicles.add(vehicle); + return this; + } + + public PrebookingTestEnvironment setVehicleCapacity(int vehicleCapacity) { + this.vehicleCapacity = vehicleCapacity; + return this; + } + + public Controler build() { + Config config = ConfigUtils.createConfig(); + buildConfig(config); + + Scenario scenario = ScenarioUtils.createScenario(config); + + scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DrtRoute.class, + new DrtRouteFactory()); + + buildNetwork(scenario); + buildPopulation(scenario); + + Controler controller = new Controler(scenario); + buildController(controller); + buildFleet(controller); + + configureRequestListener(controller); + configureVehicleListener(controller); + + return controller; + } + + private void buildFleet(Controler controller) { + FleetSpecification fleetSpecification = new FleetSpecificationImpl(); + + for (Vehicle vehicle : vehicles) { + fleetSpecification.addVehicleSpecification(ImmutableDvrpVehicleSpecification.newBuilder() // + .id(Id.create(vehicle.vehicleId, DvrpVehicle.class)) // + .capacity(vehicleCapacity) // + .serviceBeginTime(0.0) // + .serviceEndTime(endTime) // + .startLinkId(createLinkId(createNodeId(vehicle.depot.getLeft(), vehicle.depot.getRight()), + createNodeId(vehicle.depot.getLeft() + 1, vehicle.depot.getRight()))) // + .build()); + } + + controller.addOverridingModule(new AbstractDvrpModeModule("drt") { + @Override + public void install() { + bindModal(FleetSpecification.class).toInstance(fleetSpecification); + } + }); + } + + private void buildController(Controler controller) { + controller.addOverridingModule(new DvrpModule()); + controller.addOverridingModule(new MultiModeDrtModule()); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(controller.getConfig()); + controller.configureQSimComponents(DvrpQSimComponents.activateAllModes(multiModeDrtConfigGroup)); + } + + private void buildConfig(Config config) { + config.controller().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); + + config.qsim().setStartTime(0.0); + config.qsim().setSimStarttimeInterpretation(StarttimeInterpretation.onlyUseStarttime); + + config.qsim().setEndTime(endTime); + config.qsim().setSimEndtimeInterpretation(EndtimeInterpretation.onlyUseEndtime); + + ModeParams drtParams = new ModeParams("drt"); + config.scoring().addModeParams(drtParams); + + ActivityParams genericParams = new ActivityParams("generic"); + genericParams.setScoringThisActivityAtAll(false); + config.scoring().addActivityParams(genericParams); + + DvrpConfigGroup dvrpConfig = new DvrpConfigGroup(); + config.addModule(dvrpConfig); + + MultiModeDrtConfigGroup drtConfig = new MultiModeDrtConfigGroup(); + config.addModule(drtConfig); + + DrtConfigGroup modeConfig = new DrtConfigGroup(); + drtConfig.addParameterSet(modeConfig); + modeConfig.mode = "drt"; + modeConfig.maxWaitTime = maximumWaitTime; + modeConfig.maxTravelTimeAlpha = detourRelative; + modeConfig.maxTravelTimeBeta = detourAbsolute; + modeConfig.stopDuration = stopDuration; + modeConfig.idleVehiclesReturnToDepots = false; + modeConfig.vehiclesFile = null; + + DrtInsertionSearchParams searchParams = new SelectiveInsertionSearchParams(); + modeConfig.addDrtInsertionSearchParams(searchParams); + + DrtConfigs.adjustMultiModeDrtConfig(drtConfig, config.scoring(), config.routing()); + } + + private void buildPopulation(Scenario scenario) { + Population population = scenario.getPopulation(); + PopulationFactory factory = population.getFactory(); + + for (Request request : requests) { + Id personId = Id.createPersonId(request.personId); + + Id originLinkId = createLinkId(createNodeId(request.origin.getLeft(), request.origin.getRight()), + createNodeId(request.origin.getLeft() + 1, request.origin.getRight())); + Id destinationLinkId = createLinkId( + createNodeId(request.destination.getLeft(), request.destination.getRight()), + createNodeId(request.destination.getLeft() + 1, request.destination.getRight())); + + Person person = factory.createPerson(personId); + population.addPerson(person); + + Plan plan = factory.createPlan(); + person.addPlan(plan); + + Activity firstActivity = factory.createActivityFromLinkId("generic", originLinkId); + plan.addActivity(firstActivity); + firstActivity.setEndTime(request.departureTime); + + Leg firstLeg = factory.createLeg("drt"); + plan.addLeg(firstLeg); + + if (!Double.isNaN(request.submissionTime)) { + firstActivity.getAttributes().putAttribute(AttributeBasedPrebookingLogic.getSubmissionAttribute("drt"), + request.submissionTime); + } + + if (!Double.isNaN(request.plannedDepartureTime)) { + firstActivity.getAttributes().putAttribute( + AttributeBasedPrebookingLogic.getPlannedDepartureAttribute("drt"), + request.plannedDepartureTime); + } + + Activity secondActivity = factory.createActivityFromLinkId("generic", destinationLinkId); + plan.addActivity(secondActivity); + } + } + + private Id createNodeId(int i, int j) { + return Id.createNodeId(i + ":" + j); + } + + private Id createLinkId(Id startId, Id endId) { + return Id.createLinkId(startId.toString() + "-" + endId.toString()); + } + + private void buildNetwork(Scenario scenario) { + Network network = scenario.getNetwork(); + NetworkFactory factory = network.getFactory(); + + Node[][] nodes = new Node[width][height]; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + nodes[i][j] = factory.createNode(createNodeId(i, j), new Coord(i * edgeLength, j * edgeLength)); + network.addNode(nodes[i][j]); + } + } + + // Horizontal + for (int j = 0; j < height; j++) { + for (int i = 0; i < width - 1; i++) { + Node firstNode = nodes[i][j]; + Node secondNode = nodes[i + 1][j]; + + Id forwardId = createLinkId(firstNode.getId(), secondNode.getId()); + Id backwardId = createLinkId(secondNode.getId(), firstNode.getId()); + + Link forwardLink = factory.createLink(forwardId, firstNode, secondNode); + Link backwardLink = factory.createLink(backwardId, secondNode, firstNode); + + network.addLink(forwardLink); + network.addLink(backwardLink); + } + } + + // Vertical + for (int i = 0; i < width; i++) { + for (int j = 0; j < height - 1; j++) { + Node firstNode = nodes[i][j]; + Node secondNode = nodes[i][j + 1]; + + Id forwardId = createLinkId(firstNode.getId(), secondNode.getId()); + Id backwardId = createLinkId(secondNode.getId(), firstNode.getId()); + + Link forwardLink = factory.createLink(forwardId, firstNode, secondNode); + Link backwardLink = factory.createLink(backwardId, secondNode, firstNode); + + network.addLink(forwardLink); + network.addLink(backwardLink); + } + } + + // Defaults + for (Link link : network.getLinks().values()) { + link.setFreespeed(speed); + link.setCapacity(1e9); + link.setLength(edgeLength); + link.setNumberOfLanes(1.0); + } + } + + // ANALYSIS PART + + public class RequestInfo { + public boolean rejected = false; + + public double submissionTime = Double.NaN; + public double pickupTime = Double.NaN; + public double dropoffTime = Double.NaN; + + public List submissionTimes = new LinkedList<>(); + public Id drtRequestId = null; + } + + private Map requestInfo = new HashMap<>(); + + public Map getRequestInfo() { + return requestInfo; + } + + private void configureRequestListener(Controler controller) { + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(new RequestListener()); + } + }); + } + + private class RequestListener implements DrtRequestSubmittedEventHandler, PassengerPickedUpEventHandler, + PassengerDroppedOffEventHandler, PassengerRequestRejectedEventHandler { + @Override + public void handleEvent(DrtRequestSubmittedEvent event) { + for (Id personId : event.getPersonIds()) { + requestInfo.computeIfAbsent(personId.toString(), id -> new RequestInfo()).submissionTime = event + .getTime(); + requestInfo.computeIfAbsent(personId.toString(), id -> new RequestInfo()).drtRequestId = event + .getRequestId(); + requestInfo.computeIfAbsent(personId.toString(), id -> new RequestInfo()).submissionTimes + .add(event.getTime()); + } + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + for (Id personId : event.getPersonIds()) { + requestInfo.computeIfAbsent(personId.toString(), id -> new RequestInfo()).rejected = true; + } + } + + @Override + public void handleEvent(PassengerPickedUpEvent event) { + requestInfo.computeIfAbsent(event.getPersonId().toString(), id -> new RequestInfo()).pickupTime = event + .getTime(); + } + + @Override + public void handleEvent(PassengerDroppedOffEvent event) { + requestInfo.computeIfAbsent(event.getPersonId().toString(), id -> new RequestInfo()).dropoffTime = event + .getTime(); + } + } + + public class TaskInfo { + public double startTime = Double.NaN; + public double endTime = Double.NaN; + public String type; + } + + private Map> taskInfo = new HashMap<>(); + + public Map> getTaskInfo() { + return taskInfo; + } + + private void configureVehicleListener(Controler controller) { + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(new VehicleListener()); + } + }); + } + + private class VehicleListener implements TaskStartedEventHandler, TaskEndedEventHandler { + @Override + public void handleEvent(TaskStartedEvent event) { + taskInfo.computeIfAbsent(event.getDvrpVehicleId().toString(), id -> new LinkedList<>()).add(new TaskInfo()); + taskInfo.get(event.getDvrpVehicleId().toString()).getLast().startTime = event.getTime(); + taskInfo.get(event.getDvrpVehicleId().toString()).getLast().type = event.getTaskType().name(); + } + + @Override + public void handleEvent(TaskEndedEvent event) { + taskInfo.get(event.getDvrpVehicleId().toString()).getLast().endTime = event.getTime(); + } + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java index 365c5e04dff..e4d242dabcf 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java @@ -22,9 +22,9 @@ import java.util.Arrays; import java.util.List; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -66,11 +66,11 @@ * @author jbischoff */ public class DrtRoutingModuleTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testCottbusClosestAccessEgressStopFinder() { + void testCottbusClosestAccessEgressStopFinder() { Scenario scenario = createTestScenario(); ActivityFacilities facilities = scenario.getActivityFacilities(); final double networkTravelSpeed = 0.83333; @@ -111,7 +111,7 @@ public void testCottbusClosestAccessEgressStopFinder() { List routedList = dvrpRoutingModule.calcRoute( DefaultRoutingRequest.withoutAttributes(hf, wf, 8 * 3600, p1)); - Assert.assertEquals(5, routedList.size()); + Assertions.assertEquals(5, routedList.size()); Leg accessLegP1 = (Leg)routedList.get(0); GenericRouteImpl accessLegP1Route = (GenericRouteImpl)accessLegP1.getRoute(); @@ -129,32 +129,32 @@ public void testCottbusClosestAccessEgressStopFinder() { // drt boarding should be at link id 2183 or 2184, not totally clear which one of these (from and to nodes inverted) // drt alighting should be at link id 5866 or 5867, not totally clear which one of these (from and to nodes inverted) - Assert.assertEquals(TransportMode.walk, accessLegP1.getMode()); - Assert.assertEquals(Id.createLinkId(3699), accessLegP1Route.getStartLinkId()); - Assert.assertEquals(Id.createLinkId(2184), accessLegP1Route.getEndLinkId()); + Assertions.assertEquals(TransportMode.walk, accessLegP1.getMode()); + Assertions.assertEquals(Id.createLinkId(3699), accessLegP1Route.getStartLinkId()); + Assertions.assertEquals(Id.createLinkId(2184), accessLegP1Route.getEndLinkId()); - Assert.assertEquals(drtMode + " interaction", stageActivityAccessP1.getType()); - Assert.assertEquals(Id.createLinkId(2184), stageActivityAccessP1.getLinkId()); + Assertions.assertEquals(drtMode + " interaction", stageActivityAccessP1.getType()); + Assertions.assertEquals(Id.createLinkId(2184), stageActivityAccessP1.getLinkId()); - Assert.assertEquals(drtMode, realDrtLegP1.getMode()); - Assert.assertEquals(Id.createLinkId(2184), realDrtLegP1Route.getStartLinkId()); + Assertions.assertEquals(drtMode, realDrtLegP1.getMode()); + Assertions.assertEquals(Id.createLinkId(2184), realDrtLegP1Route.getStartLinkId()); /* * links 5866 and 5867 are located between the same nodes, so their drt stops should be at the same place place, * too. Therefore it is not clear which one of these is the right one, as ClosestAccessEgressStopFinder should * find the nearest drt stop, but both have the same distance from the destination facility. */ - Assert.assertTrue( + Assertions.assertTrue( realDrtLegP1Route.getEndLinkId().equals(Id.createLinkId(5866)) || realDrtLegP1Route.getEndLinkId() .equals(Id.createLinkId(5867))); Id endLink = realDrtLegP1Route.getEndLinkId(); // Check of other, more drt-specific attributes of the DrtRoute is missing, maybe these should be tested in DrtRoutingModule instead - Assert.assertEquals(drtMode + " interaction", stageActivityEgressP1.getType()); - Assert.assertEquals(endLink, stageActivityEgressP1.getLinkId()); + Assertions.assertEquals(drtMode + " interaction", stageActivityEgressP1.getType()); + Assertions.assertEquals(endLink, stageActivityEgressP1.getLinkId()); - Assert.assertEquals(TransportMode.walk, egressLegP1.getMode()); - Assert.assertEquals(endLink, egressLegP1Route.getStartLinkId()); - Assert.assertEquals(Id.createLinkId(7871), egressLegP1Route.getEndLinkId()); + Assertions.assertEquals(TransportMode.walk, egressLegP1.getMode()); + Assertions.assertEquals(endLink, egressLegP1Route.getStartLinkId()); + Assertions.assertEquals(Id.createLinkId(7871), egressLegP1Route.getEndLinkId()); // case 2: origin and destination outside max walking distance from next stop (>2000m vs. max 200m) Person p2 = scenario.getPopulation().getPersons().get(Id.createPersonId(2)); @@ -167,7 +167,7 @@ public void testCottbusClosestAccessEgressStopFinder() { List routedList2 = dvrpRoutingModule.calcRoute( DefaultRoutingRequest.withoutAttributes(hf2, wf2, 8 * 3600, p2)); - Assert.assertNull(routedList2); + Assertions.assertNull(routedList2); // case 3: origin and destination at the same coordinate, > 2000 m walking distance from next stop Person p3 = scenario.getPopulation().getPersons().get(Id.createPersonId(3)); @@ -180,7 +180,7 @@ public void testCottbusClosestAccessEgressStopFinder() { List routedList3 = dvrpRoutingModule.calcRoute( DefaultRoutingRequest.withoutAttributes(hf3, wf3, 8 * 3600, p3)); - Assert.assertNull(routedList3); + Assertions.assertNull(routedList3); // case 4: origin and destination at the same coordinate, in 200 m walking distance from next stop Person p4 = scenario.getPopulation().getPersons().get(Id.createPersonId(4)); @@ -193,7 +193,7 @@ public void testCottbusClosestAccessEgressStopFinder() { List routedList4 = dvrpRoutingModule.calcRoute( DefaultRoutingRequest.withoutAttributes(hf4, wf4, 8 * 3600, p4)); - Assert.assertNull(routedList4); + Assertions.assertNull(routedList4); // case 5: origin within 200 m walking distance from next stop, but destination outside walking distance Person p5 = scenario.getPopulation().getPersons().get(Id.createPersonId(5)); @@ -207,7 +207,7 @@ public void testCottbusClosestAccessEgressStopFinder() { DefaultRoutingRequest.withoutAttributes(hf5, wf5, 8 * 3600, p5)); // TODO: Asserts are prepared for interpreting maxWalkingDistance as a real maximum, but routing still works wrongly - Assert.assertNull(routedList5); + Assertions.assertNull(routedList5); // case 6: destination within 200 m walking distance from next stop, but origin outside walking distance Person p6 = scenario.getPopulation().getPersons().get(Id.createPersonId(6)); @@ -221,12 +221,12 @@ public void testCottbusClosestAccessEgressStopFinder() { DefaultRoutingRequest.withoutAttributes(hf6, wf6, 8 * 3600, p6)); // TODO: Asserts are prepared for interpreting maxWalkingDistance as a real maximum, but routing still works wrongly - Assert.assertNull(routedList6); + Assertions.assertNull(routedList6); } @Test - public void testRouteDescriptionHandling() { + void testRouteDescriptionHandling() { String oldRouteFormat = "600 400"; String newRouteFormat = "{\"maxWaitTime\":600.0,\"directRideTime\":400.0,\"unsharedPath\":[\"a\",\"b\",\"c\"]}"; @@ -243,13 +243,13 @@ public void testRouteDescriptionHandling() { DrtRoute drtRoute = new DrtRoute(h.getLinkId(), w.getLinkId()); drtRoute.setRouteDescription(oldRouteFormat); - Assert.assertTrue(drtRoute.getMaxWaitTime() == 600.); - Assert.assertTrue(drtRoute.getDirectRideTime() == 400); + Assertions.assertTrue(drtRoute.getMaxWaitTime() == 600.); + Assertions.assertTrue(drtRoute.getDirectRideTime() == 400); drtRoute.setRouteDescription(newRouteFormat); - Assert.assertTrue(drtRoute.getMaxWaitTime() == 600.); - Assert.assertTrue(drtRoute.getDirectRideTime() == 400); - Assert.assertTrue(drtRoute.getUnsharedPath().equals(Arrays.asList("a", "b", "c"))); + Assertions.assertTrue(drtRoute.getMaxWaitTime() == 600.); + Assertions.assertTrue(drtRoute.getDirectRideTime() == 400); + Assertions.assertTrue(drtRoute.getUnsharedPath().equals(Arrays.asList("a", "b", "c"))); } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifierTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifierTest.java index 750f73e21d2..cfdc3002eee 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifierTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/MultiModeDrtMainModeIdentifierTest.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Activity; @@ -14,14 +14,14 @@ import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.population.PopulationUtils; import org.matsim.core.router.TripRouter; public class MultiModeDrtMainModeIdentifierTest { @Test - public void test() { + void test() { DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); String drtMode = "drt"; drtConfigGroup.mode = drtMode; @@ -34,16 +34,16 @@ public void test() { List testElements = new ArrayList<>(); Leg l1 = PopulationUtils.createLeg(TransportMode.car); testElements.add(l1); - Assert.assertEquals(TransportMode.car, mmi.identifyMainMode(testElements)); + Assertions.assertEquals(TransportMode.car, mmi.identifyMainMode(testElements)); } { List testElements = new ArrayList<>(); Leg l1 = PopulationUtils.createLeg(drtMode); testElements.add(l1); - Assert.assertEquals(drtMode, mmi.identifyMainMode(testElements)); + Assertions.assertEquals(drtMode, mmi.identifyMainMode(testElements)); } { - String drtStageActivityType = PlanCalcScoreConfigGroup.createStageActivityType(drtMode); + String drtStageActivityType = ScoringConfigGroup.createStageActivityType(drtMode); List testElements = new ArrayList<>(); // #deleteBeforeRelease : only used to retrofit plans created since the merge of fallback routing module (sep'-dec'19) @@ -58,7 +58,7 @@ public void test() { testElements.add(l2); testElements.add(a3); testElements.add(l3); - Assert.assertEquals(drtMode, mmi.identifyMainMode(testElements)); + Assertions.assertEquals(drtMode, mmi.identifyMainMode(testElements)); } } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java index 3d28a85cffd..e3ac88d4985 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunDrtExampleIT.java @@ -20,6 +20,7 @@ package org.matsim.contrib.drt.run.examples; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; import java.net.URL; @@ -29,25 +30,32 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; - -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.contrib.drt.optimizer.DrtRequestInsertionRetryParams; import org.matsim.contrib.drt.optimizer.insertion.repeatedselective.RepeatedSelectiveInsertionSearchParams; import org.matsim.contrib.drt.optimizer.insertion.selective.SelectiveInsertionSearchParams; +import org.matsim.contrib.drt.prebooking.PrebookingParams; +import org.matsim.contrib.drt.prebooking.logic.ProbabilityBasedPrebookingLogic; +import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.drt.run.DrtControlerCreator; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.drt.stops.CorrectedStopTimeCalculator; import org.matsim.contrib.drt.stops.CumulativeStopTimeCalculator; import org.matsim.contrib.drt.stops.MinimumStopDurationAdapter; -import org.matsim.contrib.drt.stops.StaticPassengerStopDurationProvider; import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; +import org.matsim.contrib.drt.stops.StaticPassengerStopDurationProvider; import org.matsim.contrib.drt.stops.StopTimeCalculator; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler; +import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; +import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; import org.matsim.core.utils.io.IOUtils; @@ -63,11 +71,11 @@ */ public class RunDrtExampleIT { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); @Test - public void testRunDrtExampleWithNoRejections_ExtensiveSearch() { + void testRunDrtExampleWithNoRejections_ExtensiveSearch() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), @@ -78,8 +86,8 @@ public void testRunDrtExampleWithNoRejections_ExtensiveSearch() { drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated = false; } - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -94,7 +102,7 @@ public void testRunDrtExampleWithNoRejections_ExtensiveSearch() { } @Test - public void testRunDrtExampleWithNoRejections_SelectiveSearch() { + void testRunDrtExampleWithNoRejections_SelectiveSearch() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), @@ -112,8 +120,8 @@ public void testRunDrtExampleWithNoRejections_SelectiveSearch() { drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated = false; } - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -128,7 +136,7 @@ public void testRunDrtExampleWithNoRejections_SelectiveSearch() { } @Test - public void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { + void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), @@ -146,9 +154,9 @@ public void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated = false; } - config.controler().setLastIteration(3); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setLastIteration(3); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -163,7 +171,7 @@ public void testRunDrtExampleWithNoRejections_RepeatedSelectiveSearch() { } @Test - public void testRunDrtExampleWithRequestRetry() { + void testRunDrtExampleWithRequestRetry() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), @@ -176,8 +184,8 @@ public void testRunDrtExampleWithRequestRetry() { drtCfg.addParameterSet(drtRequestInsertionRetryParams); } - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -192,15 +200,15 @@ public void testRunDrtExampleWithRequestRetry() { } @Test - public void testRunDrtStopbasedExample() { + void testRunDrtStopbasedExample() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_stop_based_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -213,19 +221,19 @@ public void testRunDrtStopbasedExample() { verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); } - + @Test - public void testRunDrtStopbasedExampleWithFlexibleStopDuration() { + void testRunDrtStopbasedExampleWithFlexibleStopDuration() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_stop_based_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); - - Controler controller = DrtControlerCreator.createControler(config, false); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + + Controler controller = DrtControlerCreator.createControler(config, false); // This snippet adds the correction against wait times smaller than the defined stopDuration controller.addOverridingModule(new AbstractDvrpModeModule("drt") { @@ -235,7 +243,7 @@ public void install() { bindModal(StopTimeCalculator.class).toInstance(stopTimeCalculator); } }); - + controller.run(); var expectedStats = Stats.newBuilder() @@ -250,15 +258,15 @@ public void install() { } @Test - public void testRunServiceAreabasedExampleWithSpeedUp() { + void testRunServiceAreabasedExampleWithSpeedUp() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_serviceArea_based_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); RunDrtExample.run(config, false); var expectedStats = Stats.newBuilder() @@ -273,14 +281,14 @@ public void testRunServiceAreabasedExampleWithSpeedUp() { } @Test - public void testRunDrtExampleWithIncrementalStopDuration() { + void testRunDrtExampleWithIncrementalStopDuration() { Id.resetCaches(); URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_drt_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); Controler controller = DrtControlerCreator.createControler(config, false); @@ -296,12 +304,55 @@ public void install() { controller.run(); + // sh, 11/08/2023: updated after introducing prebookg, basically we generate a + // new feasible insertion (see InsertionGenerator) that previously did not + // exist, but has the same cost (pickup loss + drop-off loss) as the original + // one var expectedStats = Stats.newBuilder() .rejectionRate(0.04) .rejections(16) - .waitAverage(278.92) - .inVehicleTravelTimeMean(384.6) - .totalTravelTimeMean(663.52) + .waitAverage(278.76) + .inVehicleTravelTimeMean(384.93) + .totalTravelTimeMean(663.68) + .build(); + + verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); + } + + @Test + void testRunDrtWithPrebooking() { + Id.resetCaches(); + URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), + "mielec_drt_config.xml"); + + Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(), + new OTFVisConfigGroup()); + + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(utils.getOutputDirectory()); + + DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(config); + drtConfig.addParameterSet(new PrebookingParams()); + + Controler controller = DrtControlerCreator.createControler(config, false); + ProbabilityBasedPrebookingLogic.install(controller, drtConfig, 0.5, 4.0 * 3600.0); + + PrebookingTracker tracker = new PrebookingTracker(); + tracker.install(controller); + + controller.run(); + + assertEquals(157, tracker.immediateScheduled); + assertEquals(205, tracker.prebookedScheduled); + assertEquals(26, tracker.immediateRejected); + assertEquals(0, tracker.prebookedRejected); + + var expectedStats = Stats.newBuilder() + .rejectionRate(0.07) + .rejections(26) + .waitAverage(232.76) + .inVehicleTravelTimeMean(389.09) + .totalTravelTimeMean(621.85) .build(); verifyDrtCustomerStatsCloseToExpectedStats(utils.getOutputDirectory(), expectedStats); @@ -415,4 +466,40 @@ public Stats build() { } } } + + static private class PrebookingTracker implements PassengerRequestRejectedEventHandler, PassengerRequestScheduledEventHandler { + int immediateScheduled = 0; + int prebookedScheduled = 0; + int immediateRejected = 0; + int prebookedRejected = 0; + + @Override + public void handleEvent(PassengerRequestScheduledEvent event) { + if (event.getRequestId().toString().contains("prebooked")) { + prebookedScheduled++; + } else { + immediateScheduled++; + } + } + + @Override + public void handleEvent(PassengerRequestRejectedEvent event) { + if (event.getRequestId().toString().contains("prebooked")) { + prebookedRejected++; + } else { + immediateRejected++; + } + } + + void install(Controler controller) { + PrebookingTracker thisTracker = this; + + controller.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(thisTracker); + } + }); + } + } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExampleIT.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExampleIT.java index 88aae448e87..b5bdb9ca19a 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExampleIT.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunMultiModeDrtExampleIT.java @@ -22,13 +22,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunMultiModeDrtExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "multi_mode_one_shared_taxi_config.xml"); RunMultiModeDrtExample.run(configUrl, false, 0); diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExampleIT.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExampleIT.java index db6373e49be..eaa173d1466 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExampleIT.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/run/examples/RunOneSharedTaxiExampleIT.java @@ -20,7 +20,7 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; @@ -29,7 +29,7 @@ */ public class RunOneSharedTaxiExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "one_shared_taxi_config.xml"); RunOneSharedTaxiExample.run(configUrl, false, 1); } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/sharingmetrics/SharingFactorTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/sharingmetrics/SharingFactorTest.java new file mode 100644 index 00000000000..7a7acba2809 --- /dev/null +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/sharingmetrics/SharingFactorTest.java @@ -0,0 +1,199 @@ +package org.matsim.contrib.drt.sharingmetrics; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.passenger.events.DrtRequestSubmittedEvent; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.passenger.PassengerDroppedOffEvent; +import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEvent; +import org.matsim.core.events.ParallelEventsManager; +import org.matsim.testcases.MatsimTestUtils; + +import java.util.List; + +/** + * @author nkuehnel / MOIA + */ +public class SharingFactorTest { + + /** + * Test method for {@link SharingMetricsTracker}. + */ + @Test + public void testDrtSharingFactorHandler() { + String mode = "mode_0"; + + var vehicleId = Id.create("v1", DvrpVehicle.class); + var personId1 = Id.createPersonId("p1"); + var personId2 = Id.createPersonId("p2"); + + + ParallelEventsManager events = new ParallelEventsManager(false); + SharingMetricsTracker sharingFactorTracker = new SharingMetricsTracker(); + events.addHandler(sharingFactorTracker); + + events.initProcessing(); + + + { + //single trip, no pooling + var requestId = Id.create(0, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId, List.of(personId1), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId, personId1, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId, personId1, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId)); + Assertions.assertFalse(sharingFactorTracker.getPoolingRates().get(requestId)); + Assertions.assertEquals(1., sharingFactorTracker.getSharingFactors().get(requestId), MatsimTestUtils.EPSILON); + } + + //clean up + sharingFactorTracker.notifyMobsimBeforeCleanup(null); + + { + //two trips exactly after each other, no pooling + var requestId1 = Id.create(0, Request.class); + var requestId2 = Id.create(1, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId1, List.of(personId1), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId2, List.of(personId2), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerPickedUpEvent(300.0, mode, requestId2, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(500.0, mode, requestId2, personId2, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId1)); + Assertions.assertFalse(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertEquals(1., sharingFactorTracker.getSharingFactors().get(requestId1), MatsimTestUtils.EPSILON); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId2)); + Assertions.assertFalse(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertEquals(1., sharingFactorTracker.getSharingFactors().get(requestId2), MatsimTestUtils.EPSILON); + } + + //clean up + sharingFactorTracker.notifyMobsimBeforeCleanup(null); + + { + //two trips overlap half of the time + var requestId1 = Id.create(0, Request.class); + var requestId2 = Id.create(1, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId1, List.of(personId1), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId2, List.of(personId2), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerPickedUpEvent(200.0, mode, requestId2, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(400.0, mode, requestId2, personId2, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId1)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertEquals((100. + 100.) / (100 + 50), sharingFactorTracker.getSharingFactors().get(requestId1), MatsimTestUtils.EPSILON); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId2)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertEquals((100. + 100.) / (50 + 100), sharingFactorTracker.getSharingFactors().get(requestId2), MatsimTestUtils.EPSILON); + } + + + //clean up + sharingFactorTracker.notifyMobsimBeforeCleanup(null); + + { + // second trip (sharing factor = 2) happens completely within first trip (sharing factor = 1.2) + var requestId1 = Id.create(0, Request.class); + var requestId2 = Id.create(1, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId1, List.of(personId1), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId2, List.of(personId2), null, null, 0, 0, 0, 0, 0)); + + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerPickedUpEvent(200.0, mode, requestId2, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(300.0, mode, requestId2, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(400.0, mode, requestId1, personId1, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId1)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertEquals((100. + 100. + 100.) / (100 + 50 + 100), sharingFactorTracker.getSharingFactors().get(requestId1), MatsimTestUtils.EPSILON); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId2)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertEquals((100.) / (50.), sharingFactorTracker.getSharingFactors().get(requestId2), MatsimTestUtils.EPSILON); + } + + //clean up + sharingFactorTracker.notifyMobsimBeforeCleanup(null); + + { + // two persons share exact same trip but not part of a group + + var requestId1 = Id.create(0, Request.class); + var requestId2 = Id.create(1, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId1, List.of(personId1), null, null, 0, 0, 0, 0, 0)); + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId2, List.of(personId2), null, null, 0, 0, 0, 0, 0)); + + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId2, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(200.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(200.0, mode, requestId2, personId2, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId1)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertEquals(2., sharingFactorTracker.getSharingFactors().get(requestId1), MatsimTestUtils.EPSILON); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId2)); + Assertions.assertTrue(sharingFactorTracker.getPoolingRates().get(requestId2)); + Assertions.assertEquals(2., sharingFactorTracker.getSharingFactors().get(requestId2), MatsimTestUtils.EPSILON); + } + + + //clean up + sharingFactorTracker.notifyMobsimBeforeCleanup(null); + + { + // two persons part of a group -> not pooled + + var requestId1 = Id.create(0, Request.class); + Assertions.assertNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + + events.processEvent(new DrtRequestSubmittedEvent(0.0, mode, requestId1, List.of(personId1, personId2), null, null, 0, 0, 0, 0, 0)); + + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerPickedUpEvent(100.0, mode, requestId1, personId2, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(200.0, mode, requestId1, personId1, vehicleId)); + events.processEvent(new PassengerDroppedOffEvent(200.0, mode, requestId1, personId2, vehicleId)); + events.flush(); + + Assertions.assertNotNull(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertNotNull(sharingFactorTracker.getSharingFactors().get(requestId1)); + Assertions.assertFalse(sharingFactorTracker.getPoolingRates().get(requestId1)); + Assertions.assertEquals(1., sharingFactorTracker.getSharingFactors().get(requestId1), MatsimTestUtils.EPSILON); + } + } +} diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/speedup/DrtSpeedUpTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/speedup/DrtSpeedUpTest.java index d2c002a68a9..1f08cf7c993 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/speedup/DrtSpeedUpTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/speedup/DrtSpeedUpTest.java @@ -27,9 +27,10 @@ import static org.mockito.Mockito.when; import java.util.Arrays; +import java.util.Collections; import java.util.List; - -import org.junit.Test; +import java.util.Map; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -38,6 +39,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.Node; +import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.common.util.DistanceUtils; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector; import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector.EventSequence; @@ -54,7 +56,7 @@ import org.matsim.contrib.dvrp.passenger.PassengerPickedUpEvent; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.network.NetworkUtils; @@ -66,10 +68,10 @@ */ public class DrtSpeedUpTest { private final DrtSpeedUpParams drtSpeedUpParams = new DrtSpeedUpParams(); - private final ControlerConfigGroup controlerConfig = new ControlerConfigGroup(); + private final ControllerConfigGroup controlerConfig = new ControllerConfigGroup(); @Test - public final void test_computeMovingAverage() { + final void test_computeMovingAverage() { List list = List.of(2., 5., 22.); assertThat(computeMovingAverage(2, list)).isEqualTo(27. / 2); assertThat(computeMovingAverage(3, list)).isEqualTo(29. / 3); @@ -77,7 +79,7 @@ public final void test_computeMovingAverage() { } @Test - public void test_isTeleportDrtUsers() { + void test_isTeleportDrtUsers() { drtSpeedUpParams.fractionOfIterationsSwitchOn = 0.1; drtSpeedUpParams.fractionOfIterationsSwitchOff = 0.9; drtSpeedUpParams.intervalDetailedIteration = 10; @@ -121,7 +123,7 @@ public void test_isTeleportDrtUsers() { private final DrtEventSequenceCollector requestAnalyzer = mock(DrtEventSequenceCollector.class); @Test - public void test_useOnlyInitialEstimates_noRegression() { + void test_useOnlyInitialEstimates_noRegression() { //iters 0 & 100 - simulated, iters 1...99 - teleported drtSpeedUpParams.fractionOfIterationsSwitchOn = 0.0; drtSpeedUpParams.fractionOfIterationsSwitchOff = 1.0; @@ -158,7 +160,7 @@ public void test_useOnlyInitialEstimates_noRegression() { } @Test - public void test_useAveragesFromLastTwoSimulations_noRegression() { + void test_useAveragesFromLastTwoSimulations_noRegression() { //iters 0, 2, 4 - simulated, iters 1, 3 - teleported drtSpeedUpParams.fractionOfIterationsSwitchOn = 0.0; drtSpeedUpParams.fractionOfIterationsSwitchOff = 1.0; @@ -206,7 +208,7 @@ public void test_useAveragesFromLastTwoSimulations_noRegression() { } @Test - public void test_linearRegression() { + void test_linearRegression() { //iters 0, 2, 4 - simulated, iters 1, 3 - teleported drtSpeedUpParams.fractionOfIterationsSwitchOn = 0.0; drtSpeedUpParams.fractionOfIterationsSwitchOff = 1.0; @@ -270,8 +272,10 @@ private void updateRequestAnalyser(EventSequence... eventSequences) { private EventSequence eventSequence(String id, double submittedTime, double waitTime, double inVehicleSpeed) { var requestId = Id.create(id, Request.class); - var submittedEvent = new DrtRequestSubmittedEvent(submittedTime, MODE, requestId, null, linkAB.getId(), - linkBC.getId(), Double.NaN, Double.NaN, Double.NaN, Double.NaN); + var personId = Id.create(id, Person.class); + + var submittedEvent = new DrtRequestSubmittedEvent(submittedTime, MODE, requestId, List.of(personId), linkAB.getId(), + linkBC.getId(), Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN); var pickupEvent = new PassengerPickedUpEvent(submittedTime + waitTime, MODE, requestId, null, null); double rideTime = DistanceUtils.calculateDistance(linkBC, linkAB) / inVehicleSpeed; var dropoffEvent = new PassengerDroppedOffEvent(submittedTime + waitTime + rideTime, MODE, requestId, null, @@ -280,7 +284,8 @@ private EventSequence eventSequence(String id, double submittedTime, double wait MODE, requestId.toString()); var departureEvent = mock(PersonDepartureEvent.class); - return new EventSequence(departureEvent, submittedEvent, mock(PassengerRequestScheduledEvent.class), + + return new EventSequence(Id.createPersonId("r1"), departureEvent, submittedEvent, mock(PassengerRequestScheduledEvent.class), pickupEvent, dropoffEvent, List.of(drtFare)); } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/util/DrtEventsReadersTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/util/DrtEventsReadersTest.java index b34b5af05ad..6ba4b41e0c8 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/util/DrtEventsReadersTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/util/DrtEventsReadersTest.java @@ -25,9 +25,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.Event; import org.matsim.api.core.v01.network.Link; @@ -46,7 +47,7 @@ import org.matsim.contrib.dvrp.vrpagent.TaskStartedEvent; import org.matsim.contrib.dvrp.vrpagent.TaskStartedEventHandler; import org.matsim.core.api.experimental.events.EventsManager; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.algorithms.EventWriterXML; @@ -64,14 +65,14 @@ public class DrtEventsReadersTest { //standard dvrp events are tested in DvrpEventsReadersTest private final List drtEvents = List.of( - new DrtRequestSubmittedEvent(0, mode, request, person, link1, link2, 111, 222, 412.0, 512.0),// + new DrtRequestSubmittedEvent(0, mode, request, List.of(person), link1, link2, 111, 222, 0.0, 412.0, 512.0),// taskStarted(10, DrtDriveTask.TYPE, 0, link1),// taskEnded(30, DefaultDrtStopTask.TYPE, 1, link2), // taskStarted(50, DrtStayTask.TYPE, 2, link1),// taskEnded(70, EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE, 3, link2)); @Test - public void testReader() { + void testReader() { var outputStream = new ByteArrayOutputStream(); EventWriterXML writer = new EventWriterXML(outputStream); drtEvents.forEach(writer::handleEvent); @@ -83,7 +84,7 @@ public void testReader() { eventsManager.initProcessing(); DrtEventsReaders.createEventsReader(eventsManager) .readStream(new ByteArrayInputStream(outputStream.toByteArray()), - ControlerConfigGroup.EventsFileFormat.xml); + ControllerConfigGroup.EventsFileFormat.xml); eventsManager.finishProcessing(); assertThat(handler.handledEvents).usingRecursiveFieldByFieldElementComparator() diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/analysis/VehicleOccupancyProfileCalculator.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/analysis/VehicleOccupancyProfileCalculator.java index 8104898b89e..16a8136492c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/analysis/VehicleOccupancyProfileCalculator.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/analysis/VehicleOccupancyProfileCalculator.java @@ -164,10 +164,9 @@ public TimeDiscretizer getTimeDiscretizer() { private void increment(VehicleState state, double endTime) { Verify.verify(state.taskType != null); Verify.verify(state.occupancy >= 0); + Verify.verify(state.occupancy <= maxCapacity); - boolean servingPassengers = passengerServingTaskTypes.contains(state.taskType); - Verify.verify(servingPassengers || state.occupancy == 0, - "Vehicles not serving passengers must not be occupied"); + boolean servingPassengers = passengerServingTaskTypes.contains(state.taskType) || state.occupancy > 0; double[] profile = servingPassengers ? vehicleOccupancyProfiles.get(state.occupancy) : diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiModule.java index 1bbe061f8d7..ab5916c967e 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiModule.java @@ -25,6 +25,7 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.dvrp.fleet.FleetModule; import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; +import org.matsim.contrib.dvrp.passenger.AdvanceRequestProvider; import org.matsim.contrib.dvrp.passenger.DefaultPassengerRequestValidator; import org.matsim.contrib.dvrp.passenger.PassengerEngineQSimModule; import org.matsim.contrib.dvrp.passenger.PassengerEngineQSimModule.PassengerEngineType; @@ -87,6 +88,9 @@ protected void configureQSim() { // converts scheduled tasks into simulated actions (legs and activities) bindModal(VrpAgentLogic.DynActionCreator.class).to(OneTaxiActionCreator.class).in(Singleton.class); + + // no advance request + bindModal(AdvanceRequestProvider.class).toInstance(AdvanceRequestProvider.NONE); } }); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiOptimizer.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiOptimizer.java index fb23bac474d..ee5f38811fe 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiOptimizer.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiOptimizer.java @@ -133,7 +133,7 @@ public void requestSubmitted(Request request) { eventsManager.processEvent( new PassengerRequestScheduledEvent(timer.getTimeOfDay(), TransportMode.taxi, request.getId(), - req.getPassengerId(), vehicle.getId(), t1, t4)); + req.getPassengerIds(), vehicle.getId(), t1, t4)); } @Override diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiRequest.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiRequest.java index a1d86022e2a..de9f9f0936b 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiRequest.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/OneTaxiRequest.java @@ -28,6 +28,8 @@ import org.matsim.contrib.dvrp.passenger.PassengerRequest; import org.matsim.contrib.dvrp.passenger.PassengerRequestCreator; +import java.util.*; + /** * @author michalm */ @@ -36,18 +38,18 @@ public final class OneTaxiRequest implements PassengerRequest { private final double submissionTime; private final double earliestStartTime; - private final Id passengerId; + private final List> passengerIds = new ArrayList<>(); private final String mode; private final Link fromLink; private final Link toLink; - public OneTaxiRequest(Id id, Id passengerId, String mode, Link fromLink, Link toLink, - double departureTime, double submissionTime) { + public OneTaxiRequest(Id id, Collection> passengerIds, String mode, Link fromLink, Link toLink, + double departureTime, double submissionTime) { this.id = id; this.submissionTime = submissionTime; this.earliestStartTime = departureTime; - this.passengerId = passengerId; + this.passengerIds.addAll(passengerIds); this.mode = mode; this.fromLink = fromLink; this.toLink = toLink; @@ -79,8 +81,8 @@ public Link getToLink() { } @Override - public Id getPassengerId() { - return passengerId; + public List> getPassengerIds() { + return List.copyOf(passengerIds); } @Override @@ -88,11 +90,16 @@ public String getMode() { return mode; } + @Override + public int getPassengerCount() { + return passengerIds.size(); + } + public static final class OneTaxiRequestCreator implements PassengerRequestCreator { @Override - public OneTaxiRequest createRequest(Id id, Id passengerId, Route route, Link fromLink, + public OneTaxiRequest createRequest(Id id, List> passengerIds, Route route, Link fromLink, Link toLink, double departureTime, double submissionTime) { - return new OneTaxiRequest(id, passengerId, TransportMode.taxi, fromLink, toLink, departureTime, + return new OneTaxiRequest(id, passengerIds, TransportMode.taxi, fromLink, toLink, departureTime, submissionTime); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExample.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExample.java index 686ff8d9713..e151f68821c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExample.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExample.java @@ -42,7 +42,7 @@ public final class RunOneTaxiExample { public static void run(URL configUrl, String taxisFile, boolean otfvis, int lastIteration) { // load config Config config = ConfigUtils.loadConfig(configUrl, new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); // load scenario Scenario scenario = ScenarioUtils.loadScenario(config); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExample.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExample.java index 9c3298cde14..4c4232b15b5 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExample.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExample.java @@ -45,7 +45,7 @@ public class RunOneTaxiOneTruckExample { public static void run(URL configUrl, String taxisFile, String trucksFile, boolean otfvis, int lastIteration) { // load config Config config = ConfigUtils.loadConfig(configUrl, new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); // load scenario Scenario scenario = ScenarioUtils.loadScenario(config); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExample.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExample.java index 5f555ce90f7..2bb198672a7 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExample.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExample.java @@ -41,7 +41,7 @@ public final class RunOneTruckExample { public static void run(URL configUrl, String trucksFile, boolean otfvis, int lastIteration) { // load config Config config = ConfigUtils.loadConfig(configUrl, new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(lastIteration); + config.controller().setLastIteration(lastIteration); // load scenario Scenario scenario = ScenarioUtils.loadScenario(config); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AbstractPassengerRequestEvent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AbstractPassengerRequestEvent.java index e7d8df4a56c..529f2bfc5ba 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AbstractPassengerRequestEvent.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AbstractPassengerRequestEvent.java @@ -20,13 +20,15 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Map; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.Event; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; -import org.matsim.api.core.v01.events.HasPersonId; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * This class is designed for inheritance without overriding. @@ -35,19 +37,20 @@ * * @author Michal Maciejewski (michalm) */ -public abstract class AbstractPassengerRequestEvent extends Event implements HasPersonId { +public abstract class AbstractPassengerRequestEvent extends Event { public static final String ATTRIBUTE_MODE = "mode"; public static final String ATTRIBUTE_REQUEST = "request"; + public static final String ATTRIBUTE_PERSON = "person"; private final String mode; private final Id requestId; - private final Id personId; + private final List> personIds; - AbstractPassengerRequestEvent(double time, String mode, Id requestId, Id personId) { + protected AbstractPassengerRequestEvent(double time, String mode, Id requestId, List> personIds) { super(time); this.mode = mode; this.requestId = requestId; - this.personId = personId; + this.personIds = personIds; } public final String getMode() { @@ -62,11 +65,10 @@ public final Id getRequestId() { } /** - * @return id of the passenger (person) + * @return ids of the passengers (persons) */ - @Override - public final Id getPersonId() { - return personId; + public final List> getPersonIds() { + return List.copyOf(personIds); } @Override @@ -74,6 +76,7 @@ public Map getAttributes() { Map attr = super.getAttributes(); attr.put(ATTRIBUTE_MODE, mode); attr.put(ATTRIBUTE_REQUEST, requestId + ""); + attr.put(ATTRIBUTE_PERSON, personIds.stream().map(Object::toString).collect(Collectors.joining(","))); return attr; } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AdvanceRequestProvider.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AdvanceRequestProvider.java new file mode 100644 index 00000000000..56426adb184 --- /dev/null +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/AdvanceRequestProvider.java @@ -0,0 +1,13 @@ +package org.matsim.contrib.dvrp.passenger; + +import javax.annotation.Nullable; + +import org.matsim.api.core.v01.population.Leg; +import org.matsim.core.mobsim.framework.MobsimAgent; + +public interface AdvanceRequestProvider { + static public AdvanceRequestProvider NONE = (MobsimAgent agent, Leg leg) -> null; + + @Nullable + PassengerRequest retrieveRequest(MobsimAgent agent, Leg leg); +} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngine.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngine.java index 12600006799..7e11e5e8dd8 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngine.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngine.java @@ -19,18 +19,16 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.HashMap; -import java.util.Map; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; -import jakarta.inject.Inject; -import jakarta.inject.Provider; - +import com.google.common.base.Verify; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; @@ -45,7 +43,9 @@ import org.matsim.core.modal.ModalProviders; import com.google.common.base.Preconditions; -import com.google.common.base.Verify; + +import jakarta.inject.Inject; +import jakarta.inject.Provider; /** * @author Michal Maciejewski (michalm) @@ -54,6 +54,7 @@ public final class DefaultPassengerEngine implements PassengerEngine, PassengerR private final String mode; private final MobsimTimer mobsimTimer; + private final EventsManager eventsManager; private final PassengerRequestCreator requestCreator; private final VrpOptimizer optimizer; @@ -61,24 +62,34 @@ public final class DefaultPassengerEngine implements PassengerEngine, PassengerR private final PassengerRequestValidator requestValidator; private final InternalPassengerHandling internalPassengerHandling; + private final AdvanceRequestProvider advanceRequestProvider; private InternalInterface internalInterface; //accessed in doSimStep() and handleDeparture() (no need to sync) - private final Map, MobsimPassengerAgent> activePassengers = new HashMap<>(); + private final Map, List> activePassengers = new HashMap<>(); + + // holds vehicle stop activities for requests that have not arrived at departure point yet + private final Map, PassengerPickupActivity> waitingForPassenger = new HashMap<>(); //accessed in doSimStep() and handleEvent() (potential data races) private final Queue rejectedRequestsEvents = new ConcurrentLinkedQueue<>(); - DefaultPassengerEngine(String mode, EventsManager eventsManager, MobsimTimer mobsimTimer, - PassengerRequestCreator requestCreator, VrpOptimizer optimizer, Network network, - PassengerRequestValidator requestValidator) { + private final PassengerGroupIdentifier passengerGroupIdentifier; + private final Map, List> groupDepartureStage = new LinkedHashMap<>(); + + + DefaultPassengerEngine(String mode, EventsManager eventsManager, MobsimTimer mobsimTimer, PassengerRequestCreator requestCreator, + VrpOptimizer optimizer, Network network, PassengerRequestValidator requestValidator, AdvanceRequestProvider advanceRequestProvider, PassengerGroupIdentifier passengerGroupIdentifier) { this.mode = mode; this.mobsimTimer = mobsimTimer; this.requestCreator = requestCreator; this.optimizer = optimizer; this.network = network; this.requestValidator = requestValidator; + this.eventsManager = eventsManager; + this.advanceRequestProvider = advanceRequestProvider; + this.passengerGroupIdentifier = passengerGroupIdentifier; internalPassengerHandling = new InternalPassengerHandling(mode, eventsManager); } @@ -95,12 +106,88 @@ public void onPrepareSim() { @Override public void doSimStep(double time) { - while (!rejectedRequestsEvents.isEmpty()) { - MobsimPassengerAgent passenger = activePassengers.remove(rejectedRequestsEvents.poll().getRequestId()); - //not much else can be done for immediate requests - //set the passenger agent to abort - the event will be thrown by the QSim - passenger.setStateToAbort(mobsimTimer.getTimeOfDay()); - internalInterface.arrangeNextAgentState(passenger); + + handleGroupDepartures(time); + + // If prebooked requests are rejected (by the optimizer, through an + // event) after submission, but before departure, the PassengerEngine does not + // know this agent yet. Hence, we wait with setting the state to abort until the + // agent has arrived here (if ever). + + Iterator iterator = rejectedRequestsEvents.iterator(); + + while (iterator.hasNext()) { + PassengerRequestRejectedEvent event = iterator.next(); + if (event.getTime() == time) { + // There is a potential race condition wrt processing rejection events between doSimStep() and handleEvent(). + // To ensure a deterministic behaviour, we only process events from the previous time step. + break; + } + + List passengers = activePassengers.remove(event.getRequestId()); + + if (passengers != null) { + // not much else can be done for immediate requests + // set the passenger agent to abort - the event will be thrown by the QSim + for (MobsimPassengerAgent passenger: passengers) { + passenger.setStateToAbort(mobsimTimer.getTimeOfDay()); + internalInterface.arrangeNextAgentState(passenger); + } + iterator.remove(); + } + } + } + + private void handleGroupDepartures(double now) { + + groupDepartureStage.values().forEach(g -> g.sort(Comparator.comparing(Identifiable::getId))); + for (List group : groupDepartureStage.values()) { + handleDepartureImpl(now, group); + } + groupDepartureStage.clear(); + } + + private void handleDepartureImpl(double now, List group) { + List> groupIds = group.stream().map(Identifiable::getId).toList(); + + MobsimPassengerAgent representative = group.get(0); + + Id fromLinkId = representative.getCurrentLinkId(); + Id toLinkId = representative.getDestinationLinkId(); + + Preconditions.checkArgument(group.stream().allMatch(a -> a.getCurrentLinkId().equals(fromLinkId))); + Preconditions.checkArgument(group.stream().allMatch(a -> a.getDestinationLinkId().equals(toLinkId))); + + // try to find a prebooked requests that is associated to this leg + Leg leg = (Leg)((PlanAgent)representative).getCurrentPlanElement(); + PassengerRequest request = advanceRequestProvider.retrieveRequest(representative, leg); + + if (request == null) { // immediate request + Route route = leg.getRoute(); + request = requestCreator.createRequest(internalPassengerHandling.createRequestId(), + groupIds, route, getLink(fromLinkId), getLink(toLinkId), now, now); + + // must come before validateAndSubmitRequest (to come before rejection event) + eventsManager.processEvent(new PassengerWaitingEvent(now, mode, request.getId(), groupIds)); + activePassengers.put(request.getId(), group); + + validateAndSubmitRequest(group, request, now); + } else { // advance request + + Preconditions.checkArgument(request.getPassengerIds().size() == group.size()); + Preconditions.checkArgument(request.getPassengerIds().containsAll(groupIds)); + + for (MobsimPassengerAgent agent : group) { + eventsManager.processEvent(new PassengerWaitingEvent(now, mode, request.getId(), List.of(agent.getId()))); + } + + activePassengers.put(request.getId(), group); + + PassengerPickupActivity pickupActivity = waitingForPassenger.remove(request.getId()); + if (pickupActivity != null) { + // the vehicle is already waiting for the request, notify it + pickupActivity.notifyPassengersAreReadyForDeparture(group, now); + } } } @@ -117,17 +204,21 @@ public boolean handleDeparture(double now, MobsimAgent agent, Id fromLinkI MobsimPassengerAgent passenger = (MobsimPassengerAgent)agent; internalInterface.registerAdditionalAgentOnLink(passenger); - Id toLinkId = passenger.getDestinationLinkId(); + Optional> groupId = passengerGroupIdentifier.getGroupId(passenger); + + if(groupId.isPresent()) { + groupDepartureStage.computeIfAbsent(groupId.get(), k -> new ArrayList<>()).add(passenger); + //terminate early as more group members may depart later + return true; + } + + handleDepartureImpl(now, List.of(passenger)); - Route route = ((Leg)((PlanAgent)passenger).getCurrentPlanElement()).getRoute(); - PassengerRequest request = requestCreator.createRequest(internalPassengerHandling.createRequestId(), - passenger.getId(), route, getLink(fromLinkId), getLink(toLinkId), now, now); - validateAndSubmitRequest(passenger, request, now); return true; } - private void validateAndSubmitRequest(MobsimPassengerAgent passenger, PassengerRequest request, double now) { - activePassengers.put(request.getId(), passenger); + private void validateAndSubmitRequest(List passengers, PassengerRequest request, double now) { + activePassengers.put(request.getId(), passengers); if (internalPassengerHandling.validateRequest(request, requestValidator, now)) { //need to synchronise to address cases where requestSubmitted() may: // - be called from outside DepartureHandlers @@ -143,22 +234,49 @@ private void validateAndSubmitRequest(MobsimPassengerAgent passenger, PassengerR private Link getLink(Id linkId) { return Preconditions.checkNotNull(network.getLinks().get(linkId), - "Link id=%s does not exist in network for mode %s. Agent departs from a link that does not belong to that network?", - linkId, mode); + "Link id=%s does not exist in network for mode %s. Agent departs from a link that does not belong to that network?", linkId, mode); + } + + /** + * There are two ways of interacting with the PassengerEngine: + *

+ * - (1) The stop activity tries to pick up a passenger and receives whether the + * pickup succeeded or not (see tryPickUpPassenger). In the classic + * implementation, the vehicle only calls tryPickUpPassenger at the time when it + * actually wants to pick up the person (at the end of the activity). It may + * happen that the person is not present yet. In that case, the pickup request + * is saved and notifyPassengerReady is called on the stop activity upen + * departure of the agent. + *

+ * - (2) If pickup and dropoff times are handled more flexibly by the stop + * activity, it might want to detect whether an agent is ready to be picked up, + * then start an "interaction time" and only after perform the actual pickup. + * For that purpose, we have queryPickUpPassenger, which indicates whether the + * agent is already there, and, if not, makes sure that the stop activity is + * notified once the agent arrives for departure. + */ + @Override + public boolean notifyWaitForPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId) { + if (!activePassengers.containsKey(requestId)) { + waitingForPassenger.put(requestId, pickupActivity); + return false; + } + + return true; } @Override - public boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, + public boolean tryPickUpPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId, double now) { - boolean pickedUp = internalPassengerHandling.tryPickUpPassenger(driver, activePassengers.get(requestId), + boolean pickedUp = internalPassengerHandling.tryPickUpPassengers(driver, activePassengers.get(requestId), requestId, now); Verify.verify(pickedUp, "Not possible without prebooking"); return pickedUp; } @Override - public void dropOffPassenger(MobsimDriverAgent driver, Id requestId, double now) { - internalPassengerHandling.dropOffPassenger(driver, activePassengers.remove(requestId), requestId, now); + public void dropOffPassengers(MobsimDriverAgent driver, Id requestId, double now) { + internalPassengerHandling.dropOffPassengers(driver, activePassengers.remove(requestId), requestId, now); } @Override @@ -178,9 +296,9 @@ public static Provider createProvider(String mode) { @Override public DefaultPassengerEngine get() { - return new DefaultPassengerEngine(getMode(), eventsManager, mobsimTimer, - getModalInstance(PassengerRequestCreator.class), getModalInstance(VrpOptimizer.class), - getModalInstance(Network.class), getModalInstance(PassengerRequestValidator.class)); + return new DefaultPassengerEngine(getMode(), eventsManager, mobsimTimer, getModalInstance(PassengerRequestCreator.class), + getModalInstance(VrpOptimizer.class), getModalInstance(Network.class), getModalInstance(PassengerRequestValidator.class), + getModalInstance(AdvanceRequestProvider.class), getModalInstance(PassengerGroupIdentifier.class)); } }; } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/InternalPassengerHandling.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/InternalPassengerHandling.java index 67da85c61a7..c36393d16f4 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/InternalPassengerHandling.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/InternalPassengerHandling.java @@ -22,6 +22,7 @@ import static java.lang.String.format; +import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -70,39 +71,50 @@ boolean validateRequest(PassengerRequest request, PassengerRequestValidator requ LOGGER.warn(format("Request: %s of mode: %s will not be served. Agent will get stuck. Cause: %s", request.getId(), mode, cause)); eventsManager.processEvent( - new PassengerRequestRejectedEvent(now, mode, request.getId(), request.getPassengerId(), cause)); + new PassengerRequestRejectedEvent(now, mode, request.getId(), request.getPassengerIds(), cause)); } return violations.isEmpty(); } - boolean tryPickUpPassenger(MobsimDriverAgent driver, MobsimPassengerAgent passenger, Id requestId, + boolean tryPickUpPassengers(MobsimDriverAgent driver, List passengers, Id requestId, double now) { - if (internalInterface.unregisterAdditionalAgentOnLink(passenger.getId(), driver.getCurrentLinkId()) == null) { - //only possible with prebooking - return false; + + //ensure for every passenger first + for (MobsimPassengerAgent passenger : passengers) { + if (internalInterface.unregisterAdditionalAgentOnLink(passenger.getId(), driver.getCurrentLinkId()) == null) { + //only possible with prebooking + return false; + } } - MobsimVehicle mobVehicle = driver.getVehicle(); - mobVehicle.addPassenger(passenger); - passenger.setVehicle(mobVehicle); + for (MobsimPassengerAgent passenger : passengers) { + + MobsimVehicle mobVehicle = driver.getVehicle(); + mobVehicle.addPassenger(passenger); + passenger.setVehicle(mobVehicle); + + Id vehicleId = Id.create(mobVehicle.getId(), DvrpVehicle.class); + eventsManager.processEvent(new PersonEntersVehicleEvent(now, passenger.getId(), mobVehicle.getId())); + eventsManager.processEvent(new PassengerPickedUpEvent(now, mode, requestId, passenger.getId(), vehicleId)); + } - Id vehicleId = Id.create(mobVehicle.getId(), DvrpVehicle.class); - eventsManager.processEvent(new PersonEntersVehicleEvent(now, passenger.getId(), mobVehicle.getId())); - eventsManager.processEvent(new PassengerPickedUpEvent(now, mode, requestId, passenger.getId(), vehicleId)); return true; } - void dropOffPassenger(MobsimDriverAgent driver, MobsimPassengerAgent passenger, Id requestId, double now) { + void dropOffPassengers(MobsimDriverAgent driver, List passengers, Id requestId, double now) { MobsimVehicle mobVehicle = driver.getVehicle(); - mobVehicle.removePassenger(passenger); - passenger.setVehicle(null); - Id vehicleId = Id.create(mobVehicle.getId(), DvrpVehicle.class); - eventsManager.processEvent(new PassengerDroppedOffEvent(now, mode, requestId, passenger.getId(), vehicleId)); - eventsManager.processEvent(new PersonLeavesVehicleEvent(now, passenger.getId(), mobVehicle.getId())); - passenger.notifyArrivalOnLinkByNonNetworkMode(passenger.getDestinationLinkId()); - passenger.endLegAndComputeNextState(now); - internalInterface.arrangeNextAgentState(passenger); + for (MobsimPassengerAgent passenger : passengers) { + mobVehicle.removePassenger(passenger); + passenger.setVehicle(null); + + eventsManager.processEvent(new PassengerDroppedOffEvent(now, mode, requestId, passenger.getId(), vehicleId)); + eventsManager.processEvent(new PersonLeavesVehicleEvent(now, passenger.getId(), mobVehicle.getId())); + + passenger.notifyArrivalOnLinkByNonNetworkMode(passenger.getDestinationLinkId()); + passenger.endLegAndComputeNextState(now); + internalInterface.arrangeNextAgentState(passenger); + } } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerDropoffActivity.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerDropoffActivity.java index e93a08f840b..7d157e4c798 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerDropoffActivity.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerDropoffActivity.java @@ -54,7 +54,7 @@ protected boolean isLastStep(double now) { protected void afterLastStep(double now) { // dropoff at the end of stop activity for (PassengerRequest request : requests.values()) { - passengerHandler.dropOffPassenger(driver, request.getId(), now); + passengerHandler.dropOffPassengers(driver, request.getId(), now); } } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerPickupActivity.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerPickupActivity.java index 8d7bcb2da96..badc060b37e 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerPickupActivity.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/MultiPassengerPickupActivity.java @@ -19,9 +19,13 @@ package org.matsim.contrib.dvrp.passenger; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.schedule.StayTask; @@ -35,7 +39,7 @@ public class MultiPassengerPickupActivity extends FirstLastSimStepDynActivity im private final Map, ? extends PassengerRequest> requests; private final double expectedEndTime; - private int passengersPickedUp = 0; + private int requestsPickedUp = 0; public MultiPassengerPickupActivity(PassengerHandler passengerHandler, DynAgent driver, StayTask pickupTask, Map, ? extends PassengerRequest> requests, String activityType) { @@ -49,32 +53,32 @@ public MultiPassengerPickupActivity(PassengerHandler passengerHandler, DynAgent @Override protected boolean isLastStep(double now) { - return passengersPickedUp == requests.size() && now >= expectedEndTime; + return requestsPickedUp == requests.size() && now >= expectedEndTime; } @Override protected void beforeFirstStep(double now) { for (PassengerRequest request : requests.values()) { - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { - passengersPickedUp++; + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { + requestsPickedUp++; } } } @Override - public void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, double now) { - PassengerRequest request = getRequestForPassenger(passenger.getId()); - if (passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now)) { - passengersPickedUp++; + public void notifyPassengersAreReadyForDeparture(List passengers, double now) { + PassengerRequest request = getRequestForPassenger(passengers.stream().map(Identifiable::getId).toList()); + if (passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now)) { + requestsPickedUp++; } else { throw new IllegalStateException("The passenger is not on the link or not available for departure!"); } } - private PassengerRequest getRequestForPassenger(Id passengerId) { + private PassengerRequest getRequestForPassenger(List> passengerIds) { return requests.values() .stream() - .filter(r -> passengerId.equals(r.getPassengerId())) + .filter(r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) .findAny() .orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineQSimModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineQSimModule.java index 6f9517c5153..25372c12000 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineQSimModule.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineQSimModule.java @@ -4,6 +4,8 @@ import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import java.util.Optional; + /** * dvrp needs {@link PassengerHandler} bound to something. It is first bound to a {@link PassengerEngine} so it can also do stuff on its own. Then, * {@link PassengerEngine} is bound to one of the existing implementations. @@ -27,6 +29,8 @@ public PassengerEngineQSimModule(String mode, PassengerEngineType type) { @Override protected void configureQSim() { bindModal(PassengerHandler.class).to(modalKey(PassengerEngine.class)); + bindModal(PassengerGroupIdentifier.class).toInstance(agent -> Optional.empty()); + // (PassengerEngine is a more powerful interface.) addMobsimScopeEventHandlerBinding().to(modalKey(PassengerEngine.class)); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineWithPrebooking.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineWithPrebooking.java index 3e6fb064d00..dc7939b34df 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineWithPrebooking.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerEngineWithPrebooking.java @@ -19,12 +19,7 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.stream.Collectors; @@ -62,6 +57,7 @@ public final class PassengerEngineWithPrebooking private final String mode; private final MobsimTimer mobsimTimer; + private final EventsManager eventsManager; private final PreplanningEngine preplanningEngine; private final PassengerRequestCreator requestCreator; @@ -87,6 +83,7 @@ public final class PassengerEngineWithPrebooking this.optimizer = optimizer; this.network = network; this.requestValidator = requestValidator; + this.eventsManager = eventsManager; internalPassengerHandling = new InternalPassengerHandling(mode, eventsManager); } @@ -137,11 +134,12 @@ public void bookTrip(MobsimPassengerAgent passenger, TripInfoWithRequiredBooking double now = mobsimTimer.getTimeOfDay(); //TODO have a separate request creator for prebooking (accept TripInfo instead of Route) PassengerRequest request = requestCreator.createRequest(internalPassengerHandling.createRequestId(), - passenger.getId(), tripInfo.getOriginalRequest().getPlannedRoute(), + List.of(passenger.getId()), tripInfo.getOriginalRequest().getPlannedRoute(), getLink(tripInfo.getPickupLocation().getLinkId()), getLink(tripInfo.getDropoffLocation().getLinkId()), tripInfo.getExpectedBoardingTime(), now); validateAndSubmitRequest(passenger, request, tripInfo.getOriginalRequest(), now); - advanceRequests.put(request.getPassengerId(), request); + // hard assumption that with this engine, passenger ids is always a singleton. nkuehnel oct '23 + advanceRequests.put(request.getPassengerIds().stream().findFirst().orElseThrow(), request); } private Link getLink(Id linkId) { return Preconditions.checkNotNull(network.getLinks().get(linkId), @@ -164,10 +162,14 @@ private Link getLink(Id linkId) { //TODO what if it was already rejected while prebooking?? PassengerRequest prebookedRequest = prebookedRequests.get(0); + + eventsManager.processEvent(new PassengerWaitingEvent(now, mode, prebookedRequest.getId(), prebookedRequest.getPassengerIds())); + PassengerPickupActivity awaitingPickup = awaitingPickups.remove(prebookedRequest.getId()); if (awaitingPickup != null) { - awaitingPickup.notifyPassengerIsReadyForDeparture(passenger, now); + awaitingPickup.notifyPassengersAreReadyForDeparture(List.of(passenger), now); } + return true; } @@ -197,7 +199,7 @@ private void validateAndSubmitRequest(MobsimPassengerAgent passenger, PassengerR // ================ PICKUP / DROPOFF @Override - public boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, + public boolean tryPickUpPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId, double now) { Id linkId = driver.getCurrentLinkId(); RequestEntry requestEntry = activeRequests.get(requestId); @@ -210,7 +212,7 @@ public boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, Mobsim return false;// wait for the passenger } - if (!internalPassengerHandling.tryPickUpPassenger(driver, passenger, requestId, now)) { + if (!internalPassengerHandling.tryPickUpPassengers(driver, List.of(passenger), requestId, now)) { // the passenger has already been picked up and is on another taxi trip // seems there have been at least 2 requests made by this passenger for this location awaitingPickups.put(requestId, pickupActivity); @@ -221,8 +223,8 @@ public boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, Mobsim } @Override - public void dropOffPassenger(MobsimDriverAgent driver, Id requestId, double now) { - internalPassengerHandling.dropOffPassenger(driver, activeRequests.remove(requestId).passenger, requestId, now); + public void dropOffPassengers(MobsimDriverAgent driver, Id requestId, double now) { + internalPassengerHandling.dropOffPassengers(driver, List.of(activeRequests.remove(requestId).passenger), requestId, now); } // ================ REJECTED/SCHEDULED EVENTS @@ -294,4 +296,25 @@ public static Provider createProvider(String mode) { } }; } + + /* + * This method has been retrofitted with the new prebooking implementation in + * Nov 2023. Not sure if this is the right way to do it, this class doesn't seem + * to be tested anywhere. /sebhoerl + */ + @Override + public boolean notifyWaitForPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId) { + Id linkId = driver.getCurrentLinkId(); + RequestEntry requestEntry = activeRequests.get(requestId); + MobsimPassengerAgent passenger = requestEntry.passenger; + + if (passenger.getCurrentLinkId() != linkId + || passenger.getState() != MobsimAgent.State.LEG + || !passenger.getMode().equals(mode)) { + awaitingPickups.put(requestId, pickupActivity); + return false;// wait for the passenger + } + + return true; // passenger present? + } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerGroupIdentifier.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerGroupIdentifier.java new file mode 100644 index 00000000000..0a644c87a72 --- /dev/null +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerGroupIdentifier.java @@ -0,0 +1,20 @@ +package org.matsim.contrib.dvrp.passenger; + +import org.matsim.api.core.v01.Id; +import org.matsim.core.mobsim.framework.MobsimPassengerAgent; + +import java.util.Optional; + +/** + * Provides a method to identify the passenger group id of an agent. + * @author nkuehnel / MOIA + */ +public interface PassengerGroupIdentifier { + + class PassengerGroup { + private PassengerGroup(){} + } + + Optional> getGroupId(MobsimPassengerAgent agent); + +} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerHandler.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerHandler.java index 1a9e313731c..06912f29ae2 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerHandler.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerHandler.java @@ -30,8 +30,10 @@ * This looks quite general. But as of now is a dvrp thing. kai, apr'23 */ public interface PassengerHandler { - boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId, + boolean notifyWaitForPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId); + + boolean tryPickUpPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId, double now); - void dropOffPassenger(MobsimDriverAgent driver, Id requestId, double now); + void dropOffPassengers(MobsimDriverAgent driver, Id requestId, double now); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerPickupActivity.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerPickupActivity.java index a083ee9ce18..b8aa5cd611e 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerPickupActivity.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerPickupActivity.java @@ -22,6 +22,9 @@ import org.matsim.contrib.dynagent.DynActivity; import org.matsim.core.mobsim.framework.MobsimPassengerAgent; +import java.util.List; +import java.util.Set; + public interface PassengerPickupActivity extends DynActivity { - void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, double now); + void notifyPassengersAreReadyForDeparture(List passengers, double now); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequest.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequest.java index b3378b28f14..e6cbca39641 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequest.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequest.java @@ -24,6 +24,8 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; +import java.util.List; + public interface PassengerRequest extends Request { /** * @return beginning of the time window (inclusive) - earliest time when the passenger can be picked up @@ -41,7 +43,9 @@ default double getLatestStartTime() { Link getToLink(); - Id getPassengerId(); + List> getPassengerIds(); String getMode(); + + int getPassengerCount(); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestCreator.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestCreator.java index 9423cfd113b..15d4fe0ddde 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestCreator.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestCreator.java @@ -25,6 +25,8 @@ import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.dvrp.optimizer.Request; +import java.util.List; + /** * @author michalm */ @@ -34,7 +36,7 @@ public interface PassengerRequestCreator { * Prefer stateless implementation, otherwise provide other ways to achieve thread-safety. * * @param id request ID - * @param passengerId passenger ID + * @param passengerIds list of unique passenger IDs * @param route planned route (the required route type depends on the optimizer) * @param fromLink start location * @param toLink end location @@ -42,6 +44,6 @@ public interface PassengerRequestCreator { * @param submissionTime time at which request was submitted * @return */ - PassengerRequest createRequest(Id id, Id passengerId, Route route, Link fromLink, Link toLink, - double departureTime, double submissionTime); + PassengerRequest createRequest(Id id, List> passengerIds, Route route, Link fromLink, Link toLink, + double departureTime, double submissionTime); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestRejectedEvent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestRejectedEvent.java index fbe61390f34..13c131743db 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestRejectedEvent.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestRejectedEvent.java @@ -20,14 +20,15 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Map; -import java.util.Objects; +import java.util.*; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.GenericEvent; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; +import static org.matsim.api.core.v01.events.HasPersonId.ATTRIBUTE_PERSON; + /** * @author michalm */ @@ -38,9 +39,9 @@ public class PassengerRequestRejectedEvent extends AbstractPassengerRequestEvent private final String cause; - public PassengerRequestRejectedEvent(double time, String mode, Id requestId, Id personId, + public PassengerRequestRejectedEvent(double time, String mode, Id requestId, List> personIds, String cause) { - super(time, mode, requestId, personId); + super(time, mode, requestId, personIds); this.cause = cause; } @@ -65,8 +66,12 @@ public static PassengerRequestRejectedEvent convert(GenericEvent event) { double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); - Id personId = Id.createPersonId(attributes.get(ATTRIBUTE_PERSON)); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = new ArrayList<>(); + for (String person : personIdsAttribute) { + personIds.add(Id.create(person, Person.class)); + } String cause = Objects.requireNonNull(attributes.get(ATTRIBUTE_CAUSE)); - return new PassengerRequestRejectedEvent(time, mode, requestId, personId, cause); + return new PassengerRequestRejectedEvent(time, mode, requestId, personIds, cause); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestScheduledEvent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestScheduledEvent.java index 9de0b19b344..413b668db89 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestScheduledEvent.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestScheduledEvent.java @@ -20,8 +20,7 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Map; -import java.util.Objects; +import java.util.*; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.GenericEvent; @@ -29,6 +28,8 @@ import org.matsim.contrib.dvrp.fleet.DvrpVehicle; import org.matsim.contrib.dvrp.optimizer.Request; +import static org.matsim.api.core.v01.events.HasPersonId.ATTRIBUTE_PERSON; + /** * @author michalm */ @@ -46,9 +47,9 @@ public class PassengerRequestScheduledEvent extends AbstractPassengerRequestEven /** * An event processed upon request submission. */ - public PassengerRequestScheduledEvent(double time, String mode, Id requestId, Id personId, + public PassengerRequestScheduledEvent(double time, String mode, Id requestId, List> personIds, Id vehicleId, double pickupTime, double dropoffTime) { - super(time, mode, requestId, personId); + super(time, mode, requestId, personIds); this.vehicleId = vehicleId; this.pickupTime = pickupTime; this.dropoffTime = dropoffTime; @@ -94,10 +95,14 @@ public static PassengerRequestScheduledEvent convert(GenericEvent event) { double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); - Id personId = Id.createPersonId(attributes.get(ATTRIBUTE_PERSON)); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = new ArrayList<>(); + for (String person : personIdsAttribute) { + personIds.add(Id.create(person, Person.class)); + } Id vehicleId = Id.create(attributes.get(ATTRIBUTE_VEHICLE), DvrpVehicle.class); double pickupTime = Double.parseDouble(attributes.get(ATTRIBUTE_PICKUP_TIME)); double dropoffTime = Double.parseDouble(attributes.get(ATTRIBUTE_DROPOFF_TIME)); - return new PassengerRequestScheduledEvent(time, mode, requestId, personId, vehicleId, pickupTime, dropoffTime); + return new PassengerRequestScheduledEvent(time, mode, requestId, personIds, vehicleId, pickupTime, dropoffTime); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestSubmittedEvent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestSubmittedEvent.java index 73dd882740c..0b7981bd634 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestSubmittedEvent.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerRequestSubmittedEvent.java @@ -20,8 +20,7 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Map; -import java.util.Objects; +import java.util.*; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.GenericEvent; @@ -29,6 +28,8 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.dvrp.optimizer.Request; +import static org.matsim.api.core.v01.events.HasPersonId.ATTRIBUTE_PERSON; + /** * @author michalm */ @@ -41,9 +42,9 @@ public class PassengerRequestSubmittedEvent extends AbstractPassengerRequestEven private final Id fromLinkId; private final Id toLinkId; - public PassengerRequestSubmittedEvent(double time, String mode, Id requestId, Id personId, + public PassengerRequestSubmittedEvent(double time, String mode, Id requestId, List> personIds, Id fromLinkId, Id toLinkId) { - super(time, mode, requestId, personId); + super(time, mode, requestId, personIds); this.fromLinkId = fromLinkId; this.toLinkId = toLinkId; } @@ -80,9 +81,14 @@ public static PassengerRequestSubmittedEvent convert(GenericEvent event) { double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); - Id personId = Id.createPersonId(attributes.get(ATTRIBUTE_PERSON)); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = new ArrayList<>(); + for (String person : personIdsAttribute) { + personIds.add(Id.create(person, Person.class)); + } + Id fromLinkId = Id.createLinkId(attributes.get(ATTRIBUTE_FROM_LINK)); Id toLinkId = Id.createLinkId(attributes.get(ATTRIBUTE_TO_LINK)); - return new PassengerRequestSubmittedEvent(time, mode, requestId, personId, fromLinkId, toLinkId); + return new PassengerRequestSubmittedEvent(time, mode, requestId, personIds, fromLinkId, toLinkId); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEvent.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEvent.java new file mode 100644 index 00000000000..db9a477954e --- /dev/null +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEvent.java @@ -0,0 +1,59 @@ +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2017 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.contrib.dvrp.passenger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.GenericEvent; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.dvrp.optimizer.Request; + +/** + * @author Sebastian Hörl (sebhoerl), IRT SystemX + */ +public class PassengerWaitingEvent extends AbstractPassengerRequestEvent { + public static final String EVENT_TYPE = "passenger waiting"; + + public PassengerWaitingEvent(double time, String mode, Id requestId, List> personIds) { + super(time, mode, requestId, personIds); + } + + @Override + public String getEventType() { + return EVENT_TYPE; + } + + public static PassengerWaitingEvent convert(GenericEvent event) { + Map attributes = event.getAttributes(); + double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME)); + String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE)); + Id requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class); + String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(","); + List> personIds = new ArrayList<>(); + for (String person : personIdsAttribute) { + personIds.add(Id.create(person, Person.class)); + } + return new PassengerWaitingEvent(time, mode, requestId, personIds); + } +} diff --git a/matsim/src/main/java/org/matsim/core/router/FastRouterType.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEventHandler.java similarity index 79% rename from matsim/src/main/java/org/matsim/core/router/FastRouterType.java rename to contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEventHandler.java index 0c70498ab49..1ca52e48d2f 100644 --- a/matsim/src/main/java/org/matsim/core/router/FastRouterType.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/PassengerWaitingEventHandler.java @@ -1,10 +1,9 @@ /* *********************************************************************** * * project: org.matsim.* - * FastRouterType.java * * * *********************************************************************** * * * - * copyright : (C) 2012 by the members listed in the COPYING, * + * copyright : (C) 2017 by the members listed in the COPYING, * * LICENSE and WARRANTY file. * * email : info at matsim dot org * * * @@ -18,15 +17,13 @@ * * * *********************************************************************** */ -package org.matsim.core.router; +package org.matsim.contrib.dvrp.passenger; + +import org.matsim.core.events.handler.EventHandler; /** - * Type Pointer is no longer supported. For now we still keep it here so we - * can throw an exception if somebody tries to us it. - * - * @author cdobler + * @author Sebastian Hörl (sebhoerl), IRT SystemX */ -public enum FastRouterType { - ARRAY, POINTER +public interface PassengerWaitingEventHandler extends EventHandler { + void handleEvent(final PassengerWaitingEvent event); } - diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/RequestQueue.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/RequestQueue.java deleted file mode 100644 index 14859041fe1..00000000000 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/RequestQueue.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2020 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.contrib.dvrp.passenger; - -import java.util.Collection; -import java.util.Comparator; -import java.util.PriorityQueue; -import java.util.Queue; -import java.util.TreeSet; - -import org.matsim.contrib.dvrp.optimizer.Request; - -/** - * @author Michal Maciejewski (michalm) - */ -public final class RequestQueue { - public static RequestQueue withLimitedAdvanceRequestPlanningHorizon( - double planningHorizon) { - //all immediate and selected advance (i.e. starting within the planning horizon) requests are scheduled - return new RequestQueue<>(planningHorizon); - } - - public static RequestQueue withInfiniteAdvanceRequestPlanningHorizon() { - return new RequestQueue<>(Double.POSITIVE_INFINITY);//all immediate and advance requests are scheduled - } - - public static RequestQueue withNoAdvanceRequestPlanningHorizon() { - return new RequestQueue<>(0);//immediate requests only - } - - private static final Comparator ABSOLUTE_COMPARATOR = Comparator.comparing( - PassengerRequest::getEarliestStartTime) - .thenComparing(PassengerRequest::getLatestStartTime) - .thenComparing(Request::getSubmissionTime) - .thenComparing(Request::getId); - - //all requests in the planning horizon (also includes old requests: never scheduled or unscheduled) - private final Collection schedulableRequests = new TreeSet<>(ABSOLUTE_COMPARATOR); - - //advance requests that are not in the planning horizon - private final Queue postponedRequests = new PriorityQueue<>(ABSOLUTE_COMPARATOR); - - private final double planningHorizon; - - private double lastTimeStep = -Double.MAX_VALUE; - - private RequestQueue(double planningHorizon) { - this.planningHorizon = planningHorizon; - } - - public void updateQueuesOnNextTimeSteps(double currentTime) { - lastTimeStep = currentTime; - while (!postponedRequests.isEmpty() && isSchedulable(postponedRequests.peek())) { - schedulableRequests.add(postponedRequests.poll()); - } - } - - public void addRequest(R request) { - (isSchedulable(request) ? schedulableRequests : postponedRequests).add(request); - } - - private boolean isSchedulable(R request) { - return request.getEarliestStartTime() <= lastTimeStep + planningHorizon; - } - - /** - * Assumes external code can modify schedulableRequests (e.g. remove scheduled requests and add unscheduled ones) - * - * @return requests to be inserted into vehicle schedules - */ - public Collection getSchedulableRequests() { - return schedulableRequests; - } -} diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerDropoffActivity.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerDropoffActivity.java index 5d74a5ed024..afab824bd96 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerDropoffActivity.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerDropoffActivity.java @@ -48,6 +48,6 @@ protected boolean isLastStep(double now) { @Override protected void afterLastStep(double now) { - passengerHandler.dropOffPassenger(driver, request.getId(), now); + passengerHandler.dropOffPassengers(driver, request.getId(), now); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerPickupActivity.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerPickupActivity.java index 33883acfcd6..3f0ee34bb62 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerPickupActivity.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/SinglePassengerPickupActivity.java @@ -19,18 +19,23 @@ package org.matsim.contrib.dvrp.passenger; +import org.matsim.api.core.v01.Identifiable; import org.matsim.contrib.dvrp.schedule.StayTask; import org.matsim.contrib.dynagent.DynAgent; import org.matsim.contrib.dynagent.FirstLastSimStepDynActivity; import org.matsim.core.mobsim.framework.MobsimPassengerAgent; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + public class SinglePassengerPickupActivity extends FirstLastSimStepDynActivity implements PassengerPickupActivity { private final PassengerHandler passengerHandler; private final DynAgent driver; private final PassengerRequest request; private final double expectedEndTime; - private boolean passengerAboard = false; + private boolean passengersAboard = false; public SinglePassengerPickupActivity(PassengerHandler passengerHandler, DynAgent driver, StayTask pickupTask, PassengerRequest request, String activityType) { @@ -44,22 +49,22 @@ public SinglePassengerPickupActivity(PassengerHandler passengerHandler, DynAgent @Override protected boolean isLastStep(double now) { - return passengerAboard && now >= expectedEndTime; + return passengersAboard && now >= expectedEndTime; } @Override protected void beforeFirstStep(double now) { - passengerAboard = passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now); + passengersAboard = passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now); } @Override - public void notifyPassengerIsReadyForDeparture(MobsimPassengerAgent passenger, double now) { - if (passenger.getId().equals(request.getPassengerId())) { + public void notifyPassengersAreReadyForDeparture(List passengers, double now) { + if (request.getPassengerIds().containsAll(passengers.stream().map(Identifiable::getId).toList())) { throw new IllegalArgumentException("I am waiting for a different passenger!"); } - passengerAboard = passengerHandler.tryPickUpPassenger(this, driver, request.getId(), now); - if (!passengerAboard) { + passengersAboard = passengerHandler.tryPickUpPassengers(this, driver, request.getId(), now); + if (!passengersAboard) { throw new IllegalStateException("The passenger is not on the link or not available for departure!"); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngine.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngine.java index 0906bed9e71..1f773a77043 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngine.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngine.java @@ -20,10 +20,7 @@ package org.matsim.contrib.dvrp.passenger; -import java.util.Collection; -import java.util.Comparator; -import java.util.PriorityQueue; -import java.util.Queue; +import java.util.*; import jakarta.inject.Inject; import jakarta.inject.Provider; @@ -35,6 +32,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.dvrp.optimizer.Request; import org.matsim.contrib.dvrp.run.DvrpModes; @@ -120,8 +118,10 @@ public void doSimStep(double time) { //first process passenger dropoff events while (!teleportedRequests.isEmpty() && teleportedRequests.peek().getLeft() <= time) { PassengerRequest request = teleportedRequests.poll().getRight(); - eventsManager.processEvent( - new PassengerDroppedOffEvent(time, mode, request.getId(), request.getPassengerId(), null)); + for (Id passenger : request.getPassengerIds()) { + eventsManager.processEvent( + new PassengerDroppedOffEvent(time, mode, request.getId(), passenger, null)); + } } //then end teleported rides @@ -143,10 +143,12 @@ public boolean handleDeparture(double now, MobsimAgent agent, Id fromLinkI Id toLinkId = passenger.getDestinationLinkId(); Route route = ((Leg)((PlanAgent)passenger).getCurrentPlanElement()).getRoute(); PassengerRequest request = requestCreator.createRequest(internalPassengerHandling.createRequestId(), - passenger.getId(), route, getLink(fromLinkId), getLink(toLinkId), now, now); + List.of(passenger.getId()), route, getLink(fromLinkId), getLink(toLinkId), now, now); + + eventsManager.processEvent(new PassengerWaitingEvent(now, mode, request.getId(), request.getPassengerIds())); if (internalPassengerHandling.validateRequest(request, requestValidator, now)) { - Route teleportedRoute = adaptLegRouteForTeleportation(passenger, request, now); + Route teleportedRoute = adaptLegRouteForTeleportation(List.of(passenger), request, now); eventsManager.processEvent(new PassengerPickedUpEvent(now, mode, request.getId(), passenger.getId(), null)); teleportationEngine.handleDeparture(now, passenger, fromLinkId); teleportedRequests.add(ImmutablePair.of(now + teleportedRoute.getTravelTime().seconds(), request)); @@ -160,20 +162,22 @@ public boolean handleDeparture(double now, MobsimAgent agent, Id fromLinkI return true; } - private Route adaptLegRouteForTeleportation(MobsimPassengerAgent passenger, PassengerRequest request, double now) { + private Route adaptLegRouteForTeleportation(List passengers, PassengerRequest request, double now) { Route teleportedRoute = teleportedRouteCalculator.calculateRoute(request); - Leg leg = (Leg)WithinDayAgentUtils.getCurrentPlanElement(passenger);//side effect: makes the plan modifiable - Route originalRoute = leg.getRoute(); - Verify.verify(originalRoute.getStartLinkId().equals(teleportedRoute.getStartLinkId())); - Verify.verify(originalRoute.getEndLinkId().equals(teleportedRoute.getEndLinkId())); - Verify.verify(teleportedRoute.getTravelTime().isDefined()); + for (MobsimPassengerAgent passenger : passengers) { + Leg leg = (Leg)WithinDayAgentUtils.getCurrentPlanElement(passenger);//side effect: makes the plan modifiable + Route originalRoute = leg.getRoute(); + Verify.verify(originalRoute.getStartLinkId().equals(teleportedRoute.getStartLinkId())); + Verify.verify(originalRoute.getEndLinkId().equals(teleportedRoute.getEndLinkId())); + Verify.verify(teleportedRoute.getTravelTime().isDefined()); - leg.getAttributes().putAttribute(ORIGINAL_ROUTE_ATTRIBUTE, originalRoute); - leg.setRoute(teleportedRoute); + leg.getAttributes().putAttribute(ORIGINAL_ROUTE_ATTRIBUTE, originalRoute); + leg.setRoute(teleportedRoute); + } eventsManager.processEvent(new PassengerRequestScheduledEvent(mobsimTimer.getTimeOfDay(), mode, request.getId(), - request.getPassengerId(), null, now, now + teleportedRoute.getTravelTime().seconds())); + request.getPassengerIds(), null, now, now + teleportedRoute.getTravelTime().seconds())); return teleportedRoute; } @@ -184,13 +188,19 @@ private Link getLink(Id linkId) { } @Override - public boolean tryPickUpPassenger(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, + public boolean notifyWaitForPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, + Id requestId) { + throw new UnsupportedOperationException("No notifying when teleporting"); + } + + @Override + public boolean tryPickUpPassengers(PassengerPickupActivity pickupActivity, MobsimDriverAgent driver, Id requestId, double now) { throw new UnsupportedOperationException("No picking-up when teleporting"); } @Override - public void dropOffPassenger(MobsimDriverAgent driver, Id requestId, double now) { + public void dropOffPassengers(MobsimDriverAgent driver, Id requestId, double now) { throw new UnsupportedOperationException("No dropping-off when teleporting"); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java index cc4b609e6cc..5724d537d36 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpConfigGroup.java @@ -37,7 +37,7 @@ import jakarta.validation.constraints.Positive; import jakarta.validation.constraints.PositiveOrZero; -public final class DvrpConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets { +public class DvrpConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets { private static final Logger log = LogManager.getLogger(DvrpConfigGroup.class); public static final String GROUP_NAME = "dvrp"; @@ -143,7 +143,7 @@ protected void checkConsistency(Config config) { if (config.qsim().isRemoveStuckVehicles()) { throw new RuntimeException("Stuck DynAgents cannot be removed from simulation"); } - if (!config.parallelEventHandling().getSynchronizeOnSimSteps()) { + if (!config.eventsManager().getSynchronizeOnSimSteps()) { throw new RuntimeException("Synchronization on sim steps is required"); } } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/util/DvrpEventsReaders.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/util/DvrpEventsReaders.java index 2df41bed134..093071c7f08 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/util/DvrpEventsReaders.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/util/DvrpEventsReaders.java @@ -28,6 +28,7 @@ import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent; import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent; import org.matsim.contrib.dvrp.passenger.PassengerRequestSubmittedEvent; +import org.matsim.contrib.dvrp.passenger.PassengerWaitingEvent; import org.matsim.contrib.dvrp.schedule.Task; import org.matsim.contrib.dvrp.vrpagent.TaskEndedEvent; import org.matsim.contrib.dvrp.vrpagent.TaskStartedEvent; @@ -41,6 +42,7 @@ public static Map createCustomEven return Map.of(PassengerRequestSubmittedEvent.EVENT_TYPE, PassengerRequestSubmittedEvent::convert,// PassengerRequestScheduledEvent.EVENT_TYPE, PassengerRequestScheduledEvent::convert,// PassengerRequestRejectedEvent.EVENT_TYPE, PassengerRequestRejectedEvent::convert,// + PassengerWaitingEvent.EVENT_TYPE, PassengerWaitingEvent::convert,// PassengerPickedUpEvent.EVENT_TYPE, PassengerPickedUpEvent::convert, // PassengerDroppedOffEvent.EVENT_TYPE, PassengerDroppedOffEvent::convert,// TaskStartedEvent.EVENT_TYPE, e -> TaskStartedEvent.convert(e, stringToTaskTypeConverter), diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java index abdcc4521b3..68d6e327ed5 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; @@ -158,6 +159,36 @@ public String getType() { public void setType(String type) { throw new UnsupportedOperationException(); } + + @Override + public int getIterationCreated() { + throw new UnsupportedOperationException(); + } + + @Override + public void setIterationCreated(int iteration) { + throw new UnsupportedOperationException(); + } + + @Override + public Id getId() { + throw new UnsupportedOperationException(); + } + + @Override + public void setPlanId(Id planId) { + throw new UnsupportedOperationException(); + } + + @Override + public String getPlanMutator() { + throw new UnsupportedOperationException(); + } + + @Override + public void setPlanMutator(String planMutator) { + throw new UnsupportedOperationException(); + } @Override public void setScore(Double score) { diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExample.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExample.java index 3bb9d6b7231..0952558534d 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExample.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExample.java @@ -47,9 +47,9 @@ public static void run(URL context, String networkFile, boolean otfvis) { config.qsim().setSimStarttimeInterpretation(StarttimeInterpretation.onlyUseStarttime); config.qsim().setSnapshotStyle(SnapshotStyle.queue); config.network().setInputFile(networkFile); - config.controler().setOutputDirectory("./test/output/random_dyn_agent/"); - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(0); + config.controller().setOutputDirectory("./test/output/random_dyn_agent/"); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); config.addConfigConsistencyChecker(new DynQSimConfigConsistencyChecker()); Scenario scenario = ScenarioUtils.loadScenario(config); diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java index 4a4be662672..34321d05068 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/Zones.java @@ -20,27 +20,14 @@ package org.matsim.contrib.zone; import java.io.File; +import java.io.UncheckedIOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.List; import java.util.Map; -import org.geotools.geometry.jts.JTS; -import org.geotools.referencing.CRS; -import org.locationtech.jts.geom.MultiPolygon; -import org.locationtech.jts.geom.Polygon; -import org.locationtech.jts.geom.util.PolygonExtracter; import org.matsim.api.core.v01.Id; import org.matsim.contrib.zone.io.ZoneShpReader; -import org.matsim.contrib.zone.io.ZoneShpWriter; import org.matsim.contrib.zone.io.ZoneXmlReader; -import org.matsim.contrib.zone.io.ZoneXmlWriter; -import org.matsim.core.utils.geometry.geotools.MGC; -import org.matsim.core.utils.io.UncheckedIOException; -import org.opengis.referencing.FactoryException; -import org.opengis.referencing.crs.CoordinateReferenceSystem; -import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.TransformException; public class Zones { public static Map, Zone> readZones(String zonesXmlFile, String zonesShpFile) { diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java index 6ee572bb03f..0adab8701df 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java @@ -33,7 +33,7 @@ */ public class FreeSpeedTravelTimeMatrix implements TravelTimeMatrix { public static FreeSpeedTravelTimeMatrix createFreeSpeedMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams params, int numberOfThreads, - double qSimTimeStepSize) { + double qSimTimeStepSize) { return new FreeSpeedTravelTimeMatrix(dvrpNetwork, params, numberOfThreads, new QSimFreeSpeedTravelTime(qSimTimeStepSize)); } @@ -48,7 +48,7 @@ public FreeSpeedTravelTimeMatrix(Network dvrpNetwork, DvrpTravelTimeMatrixParams var routingParams = new TravelTimeMatrices.RoutingParams(dvrpNetwork, travelTime, travelDisutility, numberOfThreads); freeSpeedTravelTimeMatrix = TravelTimeMatrices.calculateTravelTimeMatrix(routingParams, centralNodes, 0); freeSpeedTravelTimeSparseMatrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams, params.maxNeighborDistance, - params.maxNeighborTravelTime, 0); + params.maxNeighborTravelTime, 0).orElse(null); } @Override @@ -56,9 +56,11 @@ public int getTravelTime(Node fromNode, Node toNode, double departureTime) { if (fromNode == toNode) { return 0; } - int time = freeSpeedTravelTimeSparseMatrix.get(fromNode, toNode); - if (time >= 0) {// value is present - return time; + if (freeSpeedTravelTimeSparseMatrix != null) { + int time = freeSpeedTravelTimeSparseMatrix.get(fromNode, toNode); + if (time >= 0) {// value is present + return time; + } } return freeSpeedTravelTimeMatrix.get(gridSystem.getZone(fromNode), gridSystem.getZone(toNode)); } diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java index 38e5709b173..dcea254ac6c 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/TravelTimeMatrices.java @@ -1,13 +1,29 @@ -/* - * Copyright (C) Schweizerische Bundesbahnen SBB, 2018. - */ - +/* *********************************************************************** * + * project: org.matsim.* * + * + * * + * *********************************************************************** * + * * + * copyright : (C) 2023 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.contrib.zone.skims; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.IntStream; import org.matsim.api.core.v01.network.Network; @@ -41,7 +57,7 @@ public static Matrix calculateTravelTimeMatrix(RoutingParams params, Map centralNodes, double departureTime, Matrix travelTimeMatrix, - LeastCostPathTree lcpTree) { + LeastCostPathTree lcpTree) { Node fromNode = centralNodes.get(fromZone); lcpTree.calculate(fromNode.getId().index(), departureTime, null, null); @@ -50,26 +66,31 @@ private static void computeForDepartureZone(Zone fromZone, Map centr int nodeIndex = toNode.getId().index(); OptionalTime currOptionalTime = lcpTree.getTime(nodeIndex); double currTime = currOptionalTime.orElseThrow(() -> new RuntimeException( - "Undefined Time. Reason could be that the dvrp network is not fully connected. Please check and/or clean.")); + "Undefined Time. Reason could be that the dvrp network is not fully connected. Please check and/or clean.")); double tt = currTime - departureTime; travelTimeMatrix.set(fromZone, toZone, tt); } } - public static SparseMatrix calculateTravelTimeSparseMatrix(RoutingParams params, double maxDistance, double maxTravelTime, double departureTime) { + public static Optional calculateTravelTimeSparseMatrix(RoutingParams params, double maxDistance, double maxTravelTime, + double departureTime) { SparseMatrix travelTimeMatrix = new SparseMatrix(); + if (maxDistance == 0 && maxTravelTime == 0) { + return Optional.empty(); + } + var nodes = params.routingNetwork.getNodes().values(); var counter = "DVRP free-speed TT sparse matrix: node "; Calculation calculation = (lcpTree, n) -> computeForDepartureNode(n, nodes, departureTime, travelTimeMatrix, lcpTree, maxDistance, - maxTravelTime); + maxTravelTime); calculate(params, nodes, calculation, counter); - return travelTimeMatrix; + return Optional.of(travelTimeMatrix); } private static void computeForDepartureNode(Node fromNode, Collection nodes, double departureTime, SparseMatrix sparseMatrix, - LeastCostPathTree lcpTree, double maxDistance, double maxTravelTime) { + LeastCostPathTree lcpTree, double maxDistance, double maxTravelTime) { lcpTree.calculate(fromNode.getId().index(), departureTime, null, null, - (nodeIndex, arrivalTime, travelCost, distance, departTime) -> distance >= maxDistance && arrivalTime >= departTime + maxTravelTime); + (nodeIndex, arrivalTime, travelCost, distance, departTime) -> distance >= maxDistance && arrivalTime >= departTime + maxTravelTime); List neighborNodes = new ArrayList<>(); for (Node toNode : nodes) { @@ -94,8 +115,8 @@ private interface Calculation { private static void calculate(RoutingParams params, Collection elements, Calculation calculation, String counterPrefix) { var trees = IntStream.range(0, params.numberOfThreads) - .mapToObj(i -> new LeastCostPathTree(new SpeedyGraph(params.routingNetwork), params.travelTime, params.travelDisutility)) - .toList(); + .mapToObj(i -> new LeastCostPathTree(new SpeedyGraph(params.routingNetwork), params.travelTime, params.travelDisutility)) + .toList(); var executorService = new ExecutorServiceWithResource<>(trees); var counter = new Counter(counterPrefix, " / " + elements.size()); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/benchmark/DvrpBenchmarkQSimModuleTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/benchmark/DvrpBenchmarkQSimModuleTest.java index 1571faf0e43..da9b96c0036 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/benchmark/DvrpBenchmarkQSimModuleTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/benchmark/DvrpBenchmarkQSimModuleTest.java @@ -25,7 +25,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.core.network.NetworkUtils; import org.matsim.core.router.util.TravelTime; @@ -36,7 +36,7 @@ */ public class DvrpBenchmarkQSimModuleTest { @Test - public void calcLinkSpeed() { + void calcLinkSpeed() { var link = NetworkUtils.createLink(Id.createLinkId("id"), null, null, null, 150, 15, 10, 1); var vehicle = mock(Vehicle.class); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExampleIT.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExampleIT.java index 0e509daca53..cb490c13c13 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExampleIT.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiExampleIT.java @@ -21,13 +21,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunOneTaxiExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "generic_dvrp_one_taxi_config.xml"); RunOneTaxiExample.run(configUrl, "one_taxi_vehicles.xml", false, 0); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiWithPrebookingExampleIT.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiWithPrebookingExampleIT.java index 02917236596..b6661027c45 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiWithPrebookingExampleIT.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxi/RunOneTaxiWithPrebookingExampleIT.java @@ -32,9 +32,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.assertj.core.data.Offset; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -68,19 +68,19 @@ public class RunOneTaxiWithPrebookingExampleIT { private static final Logger log = LogManager.getLogger(RunOneTaxiWithPrebookingExampleIT.class); - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); - @Ignore + @Disabled @Test - public void testRun() { + void testRun() { // load config URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "generic_dvrp_one_taxi_config.xml"); Config config = ConfigUtils.loadConfig(configUrl, new DvrpConfigGroup(), new OTFVisConfigGroup()); - config.controler().setLastIteration(0); + config.controller().setLastIteration(0); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); { QSimComponentsConfigGroup qsimComponentsConfig = ConfigUtils.addOrGetModule(config, QSimComponentsConfigGroup.class); @@ -142,7 +142,7 @@ public void install() { if (event instanceof AgentWakeupEvent) { wakeupEvents.put(((AgentWakeupEvent)event).getPersonId(), (AgentWakeupEvent)event); } else if (event instanceof PassengerRequestScheduledEvent) { - requestScheduledEvents.put(((PassengerRequestScheduledEvent)event).getPersonId(), + requestScheduledEvents.put(((PassengerRequestScheduledEvent)event).getPersonIds().stream().findFirst().orElseThrow(), (PassengerRequestScheduledEvent)event); } else if (event instanceof ActivityEndEvent && ((ActivityEndEvent)event).getActType() .equals("dummy")) { @@ -239,7 +239,7 @@ private static void assertRequestScheduledEvent(Map, PassengerRequest PassengerRequestScheduledEvent event = events.get(Id.createPersonId(personId)); assertThat(event.getVehicleId().toString()).isEqualTo("taxi_one"); assertThat(event.getPickupTime()).isCloseTo(pickupTime, Offset.offset(0.01)); - assertThat(event.getPersonId().toString()).isEqualTo(personId); + assertThat(event.getPersonIds().get(0).toString()).isEqualTo(personId); assertThat(event.getRequestId().toString()).isEqualTo(requestId); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExampleIT.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExampleIT.java index 8f9ec937f63..10c9373563d 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExampleIT.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetaxionetruck/RunOneTaxiOneTruckExampleIT.java @@ -22,13 +22,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunOneTaxiOneTruckExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "one_taxi_one_truck_config.xml"); RunOneTaxiOneTruckExample.run(configUrl, "one_taxi_vehicles.xml", "one_truck_vehicles.xml", false, 0); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExampleIT.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExampleIT.java index 1363005eb93..b43bcac98b5 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExampleIT.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/examples/onetruck/RunOneTruckExampleIT.java @@ -21,13 +21,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunOneTruckExampleIT { @Test - public void testRun() { + void testRun() { URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "one_truck_config.xml"); RunOneTruckExample.run(configUrl, "one_truck_vehicles.xml", false, 0); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngineTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngineTest.java index 6032c73484a..97579d14517 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngineTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/DefaultPassengerEngineTest.java @@ -22,9 +22,10 @@ import static org.matsim.contrib.dvrp.passenger.PassengerEngineTestFixture.*; +import java.util.Collections; +import java.util.List; import java.util.Set; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.ActivityEndEvent; import org.matsim.api.core.v01.events.ActivityStartEvent; @@ -60,7 +61,6 @@ import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; -import com.google.inject.name.Names; /** * @author Michal Maciejewski (michalm) @@ -79,9 +79,9 @@ public class DefaultPassengerEngineTest { private final Fleet fleet = () -> ImmutableMap.of(oneTaxi.getId(), oneTaxi); @Test - public void test_valid_served() { + void test_valid_served() { double departureTime = 0; - fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, fixture.PERSON_ID); PassengerRequestValidator requestValidator = request -> Set.of();//valid createQSim(requestValidator, OneTaxiOptimizer.class).run(); @@ -98,9 +98,11 @@ public void test_valid_served() { var requestId = Id.create("taxi_0", Request.class); fixture.assertPassengerEvents( + Collections.singleton(fixture.PERSON_ID), new ActivityEndEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), new PersonDepartureEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), MODE, MODE), - new PassengerRequestScheduledEvent(departureTime, MODE, requestId, fixture.PERSON_ID, VEHICLE_ID, 0, + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID)), + new PassengerRequestScheduledEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID), VEHICLE_ID, 0, scheduledDropoffTime), new PersonEntersVehicleEvent(pickupStartTime, fixture.PERSON_ID, Id.createVehicleId(VEHICLE_ID)), new PassengerPickedUpEvent(pickupStartTime, MODE, requestId, fixture.PERSON_ID, VEHICLE_ID), @@ -111,33 +113,39 @@ public void test_valid_served() { } @Test - public void test_invalid_rejected() { + void test_invalid_rejected() { double departureTime = 0; - fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, fixture.PERSON_ID); PassengerRequestValidator requestValidator = request -> Set.of("invalid"); createQSim(requestValidator, OneTaxiOptimizer.class).run(); var requestId = Id.create("taxi_0", Request.class); - fixture.assertPassengerEvents(new ActivityEndEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), + fixture.assertPassengerEvents( + Collections.singleton(fixture.PERSON_ID), + new ActivityEndEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), new PersonDepartureEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), MODE, MODE), - new PassengerRequestRejectedEvent(0, MODE, requestId, fixture.PERSON_ID, "invalid"), - new PersonStuckEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), MODE)); + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID)), + new PassengerRequestRejectedEvent(0, MODE, requestId, List.of(fixture.PERSON_ID), "invalid"), + new PersonStuckEvent(1, fixture.PERSON_ID, fixture.linkAB.getId(), MODE)); } @Test - public void test_valid_rejected() { + void test_valid_rejected() { double departureTime = 0; - fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, fixture.PERSON_ID); PassengerRequestValidator requestValidator = request -> Set.of(); createQSim(requestValidator, RejectingOneTaxiOptimizer.class).run(); var requestId = Id.create("taxi_0", Request.class); - fixture.assertPassengerEvents(new ActivityEndEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), + fixture.assertPassengerEvents( + Collections.singleton(fixture.PERSON_ID), + new ActivityEndEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), new PersonDepartureEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), MODE, MODE), - new PassengerRequestRejectedEvent(0, MODE, requestId, fixture.PERSON_ID, "rejecting_all_requests"), - new PersonStuckEvent(0, fixture.PERSON_ID, fixture.linkAB.getId(), MODE)); + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID)), + new PassengerRequestRejectedEvent(0, MODE, requestId, List.of(fixture.PERSON_ID), "rejecting_all_requests"), + new PersonStuckEvent(1, fixture.PERSON_ID, fixture.linkAB.getId(), MODE)); } private static class RejectingOneTaxiOptimizer implements VrpOptimizer { @@ -151,7 +159,7 @@ private static class RejectingOneTaxiOptimizer implements VrpOptimizer { public void requestSubmitted(Request request) { PassengerRequest passengerRequest = (PassengerRequest)request; eventsManager.processEvent(new PassengerRequestRejectedEvent(timer.getTimeOfDay(), MODE, request.getId(), - passengerRequest.getPassengerId(), "rejecting_all_requests")); + passengerRequest.getPassengerIds(), "rejecting_all_requests")); } @Override @@ -175,6 +183,7 @@ protected void configureQSim() { bindModal(PassengerRequestCreator.class).to(OneTaxiRequest.OneTaxiRequestCreator.class) .asEagerSingleton(); bindModal(PassengerRequestValidator.class).toInstance(requestValidator); + bindModal(AdvanceRequestProvider.class).toInstance(AdvanceRequestProvider.NONE); //supply addQSimComponentBinding(DynActivityEngine.COMPONENT_NAME).to(DynActivityEngine.class); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerEngineTestFixture.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerEngineTestFixture.java index 84ec6202a63..1f83607037f 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerEngineTestFixture.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerEngineTestFixture.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.matsim.api.core.v01.Coord; @@ -81,7 +82,7 @@ public PassengerEngineTestFixture() { eventsManager.initProcessing(); } - void addPersonWithLeg(Link fromLink, Link toLink, double departureTime) { + void addPersonWithLeg(Link fromLink, Link toLink, double departureTime, Id person_id) { PopulationFactory factory = scenario.getPopulation().getFactory(); Plan plan = factory.createPlan(); @@ -99,15 +100,18 @@ void addPersonWithLeg(Link fromLink, Link toLink, double departureTime) { plan.addActivity(factory.createActivityFromLinkId(END_ACTIVITY, toLink.getId())); - Person person = factory.createPerson(PERSON_ID); + Person person = factory.createPerson(person_id); person.addPlan(plan); scenario.getPopulation().addPerson(person); } - void assertPassengerEvents(Event... events) { + void assertPassengerEvents(Collection> personIds, Event... events) { assertThat(recordedEvents.size()).isGreaterThanOrEqualTo(events.length); var recordedPassengerEvents = recordedEvents.stream() - .filter(e -> e instanceof HasPersonId && ((HasPersonId)e).getPersonId().equals(PERSON_ID)); + .filter(e -> + e instanceof HasPersonId && personIds.contains(((HasPersonId)e).getPersonId()) || + e instanceof AbstractPassengerRequestEvent + ); assertThat(recordedPassengerEvents).usingRecursiveFieldByFieldElementComparator().containsExactly(events); } } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerGroupTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerGroupTest.java new file mode 100644 index 00000000000..61a9804b4bf --- /dev/null +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/PassengerGroupTest.java @@ -0,0 +1,143 @@ +package org.matsim.contrib.dvrp.passenger; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.compress.utils.Sets; +import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.*; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.dvrp.examples.onetaxi.OneTaxiActionCreator; +import org.matsim.contrib.dvrp.examples.onetaxi.OneTaxiOptimizer; +import org.matsim.contrib.dvrp.examples.onetaxi.OneTaxiRequest; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleImpl; +import org.matsim.contrib.dvrp.fleet.Fleet; +import org.matsim.contrib.dvrp.fleet.ImmutableDvrpVehicleSpecification; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.optimizer.VrpOptimizer; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.contrib.dvrp.run.DvrpModes; +import org.matsim.contrib.dvrp.run.MobsimTimerProvider; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentSourceQSimModule; +import org.matsim.contrib.dynagent.run.DynActivityEngine; +import org.matsim.core.events.MobsimScopeEventHandlingModule; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.mobsim.qsim.QSimBuilder; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.matsim.contrib.dvrp.passenger.PassengerEngineTestFixture.*; + +/** + * @author nkuehnel / MOIA + */ +public class PassengerGroupTest { + + private final PassengerEngineTestFixture fixture = new PassengerEngineTestFixture(); + + private final Id VEHICLE_ID = Id.create("taxi1", DvrpVehicle.class); + private final DvrpVehicle oneTaxi = new DvrpVehicleImpl(ImmutableDvrpVehicleSpecification.newBuilder() + .id(VEHICLE_ID) + .serviceBeginTime(0) + .serviceEndTime(3600) + .startLinkId(fixture.linkAB.getId()) + .capacity(1) + .build(), fixture.linkAB); + private final Fleet fleet = () -> ImmutableMap.of(oneTaxi.getId(), oneTaxi); + + @Test + void test_group() { + double departureTime = 0; + Id person1 = Id.createPersonId("1"); + Id person2 = Id.createPersonId("2"); + + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, person1); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, person2); + + PassengerRequestValidator requestValidator = request -> Set.of();//valid + createQSim(requestValidator, OneTaxiOptimizer.class).run(); + + double pickupStartTime = 1; + double pickupEndTime = pickupStartTime + OneTaxiOptimizer.PICKUP_DURATION; + double taxiDepartureTime = pickupEndTime + 1; + double taxiEntersLinkBATime = taxiDepartureTime + 1; + double taxiArrivalTime = taxiEntersLinkBATime + (fixture.linkBA.getLength() / fixture.linkBA.getFreespeed()); + double dropoffEndTime = taxiArrivalTime + OneTaxiOptimizer.DROPOFF_DURATION; + + //1 second delay between pickupEndTime and taxiDepartureTime is not considered in schedules + double scheduledDropoffTime = dropoffEndTime - pickupStartTime - 1; + + var requestId = Id.create("taxi_0", Request.class); + fixture.assertPassengerEvents( + List.of(person1, person2), + new ActivityEndEvent(departureTime, person2, fixture.linkAB.getId(), null, START_ACTIVITY), + new PersonDepartureEvent(departureTime, person2, fixture.linkAB.getId(), MODE, MODE), + new ActivityEndEvent(departureTime, person1, fixture.linkAB.getId(), null, START_ACTIVITY), + new PersonDepartureEvent(departureTime, person1, fixture.linkAB.getId(), MODE, MODE), + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(person1, person2)), + new PassengerRequestScheduledEvent(departureTime, MODE, requestId, List.of(person1, person2), VEHICLE_ID, 0, + scheduledDropoffTime), + new PersonEntersVehicleEvent(pickupStartTime, person1, Id.createVehicleId(VEHICLE_ID)), + new PassengerPickedUpEvent(pickupStartTime, MODE, requestId, person1, VEHICLE_ID), + new PersonEntersVehicleEvent(pickupStartTime, person2, Id.createVehicleId(VEHICLE_ID)), + new PassengerPickedUpEvent(pickupStartTime, MODE, requestId, person2, VEHICLE_ID), + new PassengerDroppedOffEvent(dropoffEndTime, MODE, requestId, person1, VEHICLE_ID), + new PersonLeavesVehicleEvent(dropoffEndTime, person1, Id.createVehicleId(VEHICLE_ID)), + new PersonArrivalEvent(dropoffEndTime, person1, fixture.linkBA.getId(), MODE), + new ActivityStartEvent(dropoffEndTime, person1, fixture.linkBA.getId(), null, END_ACTIVITY), + new PassengerDroppedOffEvent(dropoffEndTime, MODE, requestId, person2, VEHICLE_ID), + new PersonLeavesVehicleEvent(dropoffEndTime, person2, Id.createVehicleId(VEHICLE_ID)), + new PersonArrivalEvent(dropoffEndTime, person2, fixture.linkBA.getId(), MODE), + new ActivityStartEvent(dropoffEndTime, person2, fixture.linkBA.getId(), null, END_ACTIVITY) + ); + } + + + private QSim createQSim(PassengerRequestValidator requestValidator, Class optimizerClass) { + return new QSimBuilder(fixture.config).useDefaults() + .addOverridingModule(new MobsimScopeEventHandlingModule()) + .addQSimModule(new PassengerEngineQSimModule(MODE, PassengerEngineQSimModule.PassengerEngineType.DEFAULT)) + .addQSimModule(new VrpAgentSourceQSimModule(MODE)) + .addQSimModule(new AbstractDvrpModeQSimModule(MODE) { + @Override + protected void configureQSim() { + bindModal(Network.class).toInstance(fixture.network); + bind(MobsimTimer.class).toProvider(MobsimTimerProvider.class).asEagerSingleton(); + + //requests + bindModal(PassengerRequestCreator.class).to(OneTaxiRequest.OneTaxiRequestCreator.class) + .asEagerSingleton(); + bindModal(PassengerRequestValidator.class).toInstance(requestValidator); + bindModal(AdvanceRequestProvider.class).toInstance(AdvanceRequestProvider.NONE); + + //supply + addQSimComponentBinding(DynActivityEngine.COMPONENT_NAME).to(DynActivityEngine.class); + bindModal(Fleet.class).toInstance(fleet); + bindModal(VehicleType.class).toInstance(VehicleUtils.getDefaultVehicleType()); + bindModal(VrpOptimizer.class).to(optimizerClass).asEagerSingleton(); + bindModal(VrpAgentLogic.DynActionCreator.class).to(OneTaxiActionCreator.class) + .asEagerSingleton(); + + } + }) + .addOverridingQSimModule(new AbstractDvrpModeQSimModule(MODE) { + @Override + protected void configureQSim() { + //groups + bindModal(PassengerGroupIdentifier.class).toInstance(agent -> Optional.of(Id.create("group1", PassengerGroupIdentifier.PassengerGroup.class))); + } + }) + .configureQSimComponents(components -> { + components.addComponent(DvrpModes.mode(MODE)); + components.addNamedComponent(DynActivityEngine.COMPONENT_NAME); + }) + .build(fixture.scenario, fixture.eventsManager); + } +} diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngineTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngineTest.java index d88211dc547..e26364800ab 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngineTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/passenger/TeleportingPassengerEngineTest.java @@ -20,17 +20,9 @@ package org.matsim.contrib.dvrp.passenger; -import static org.matsim.contrib.dvrp.passenger.PassengerEngineTestFixture.*; - -import java.util.Set; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.events.ActivityEndEvent; -import org.matsim.api.core.v01.events.ActivityStartEvent; -import org.matsim.api.core.v01.events.PersonArrivalEvent; -import org.matsim.api.core.v01.events.PersonDepartureEvent; -import org.matsim.api.core.v01.events.PersonStuckEvent; +import org.matsim.api.core.v01.events.*; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.dvrp.optimizer.Request; @@ -45,6 +37,12 @@ import org.matsim.core.mobsim.qsim.QSimBuilder; import org.matsim.core.population.routes.GenericRouteImpl; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.matsim.contrib.dvrp.passenger.PassengerEngineTestFixture.*; + /** * @author Michal Maciejewski (michalm) */ @@ -52,9 +50,9 @@ public class TeleportingPassengerEngineTest { private final PassengerEngineTestFixture fixture = new PassengerEngineTestFixture(); @Test - public void test_valid_teleported() { + void test_valid_teleported() { double departureTime = 0; - fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, fixture.PERSON_ID); double travelTime = 999; double travelDistance = 555; @@ -70,9 +68,11 @@ public void test_valid_teleported() { double arrivalTime = departureTime + travelTime; var requestId = Id.create("taxi_0", Request.class); fixture.assertPassengerEvents( + Collections.singleton(fixture.PERSON_ID), new ActivityEndEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), new PersonDepartureEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), MODE, MODE), - new PassengerRequestScheduledEvent(departureTime, MODE, requestId, fixture.PERSON_ID, null, departureTime, + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID)), + new PassengerRequestScheduledEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID), null, departureTime, arrivalTime), new PassengerPickedUpEvent(departureTime, MODE, requestId, fixture.PERSON_ID, null), new PassengerDroppedOffEvent(arrivalTime, MODE, requestId, fixture.PERSON_ID, null), new TeleportationArrivalEvent(arrivalTime, fixture.PERSON_ID, travelDistance, MODE), @@ -81,9 +81,9 @@ public void test_valid_teleported() { } @Test - public void test_invalid_rejected() { + void test_invalid_rejected() { double departureTime = 0; - fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime); + fixture.addPersonWithLeg(fixture.linkAB, fixture.linkBA, departureTime, fixture.PERSON_ID); TeleportedRouteCalculator teleportedRouteCalculator = request -> null; // unused PassengerRequestValidator requestValidator = request -> Set.of("invalid"); @@ -91,9 +91,11 @@ public void test_invalid_rejected() { var requestId = Id.create("taxi_0", Request.class); fixture.assertPassengerEvents( + Collections.singleton(fixture.PERSON_ID), new ActivityEndEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), null, START_ACTIVITY), new PersonDepartureEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), MODE, MODE), - new PassengerRequestRejectedEvent(departureTime, MODE, requestId, fixture.PERSON_ID, "invalid"), + new PassengerWaitingEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID)), + new PassengerRequestRejectedEvent(departureTime, MODE, requestId, List.of(fixture.PERSON_ID), "invalid"), new PersonStuckEvent(departureTime, fixture.PERSON_ID, fixture.linkAB.getId(), MODE)); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/LeastCostPathTreeStopCriteriaTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/LeastCostPathTreeStopCriteriaTest.java index 9b83de3356f..b10829bc365 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/LeastCostPathTreeStopCriteriaTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/LeastCostPathTreeStopCriteriaTest.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.function.IntToDoubleFunction; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.core.router.speedy.LeastCostPathTree.StopCriterion; import org.matsim.testcases.fakes.FakeNode; @@ -39,7 +39,7 @@ public class LeastCostPathTreeStopCriteriaTest { @Test - public void testAnd() { + void testAnd() { StopCriterion scTrue = (nodeIndex, arrivalTime, travelCost, distance, departureTime) -> true; StopCriterion scFalse = (nodeIndex, arrivalTime, travelCost, distance, departureTime) -> false; @@ -51,7 +51,7 @@ public void testAnd() { } @Test - public void testOr() { + void testOr() { StopCriterion scTrue = (nodeIndex, arrivalTime, travelCost, distance, departureTime) -> true; StopCriterion scFalse = (nodeIndex, arrivalTime, travelCost, distance, departureTime) -> false; @@ -63,7 +63,7 @@ public void testOr() { } @Test - public void testMaxTravelTime() { + void testMaxTravelTime() { StopCriterion sc = maxTravelTime(100); //TT is 100 - continue @@ -74,13 +74,13 @@ public void testMaxTravelTime() { } @Test - public void testAllEndNodesReached_noEndNodes() { + void testAllEndNodesReached_noEndNodes() { assertThatThrownBy(() -> allEndNodesReached(List.of())).isExactlyInstanceOf(IllegalArgumentException.class) .hasMessage("At least one end node must be provided."); } @Test - public void testAllEndNodesReached_oneEndNode() { + void testAllEndNodesReached_oneEndNode() { var endNode = new FakeNode(Id.createNodeId("end_node")); var otherNode = new FakeNode(Id.createNodeId("other_node")); StopCriterion sc = allEndNodesReached(List.of(endNode)); @@ -96,7 +96,7 @@ public void testAllEndNodesReached_oneEndNode() { } @Test - public void testAllEndNodesReached_twoEndNodes() { + void testAllEndNodesReached_twoEndNodes() { var endNode1 = new FakeNode(Id.createNodeId("end_node_1")); var endNode2 = new FakeNode(Id.createNodeId("end_node_2")); var otherNode = new FakeNode(Id.createNodeId("other_node")); @@ -119,13 +119,13 @@ public void testAllEndNodesReached_twoEndNodes() { } @Test - public void testLeastCostEndNodeReached_noEndNodes() { + void testLeastCostEndNodeReached_noEndNodes() { assertThatThrownBy(() -> new LeastCostEndNodeReached(List.of(), value -> 0)).isExactlyInstanceOf( IllegalArgumentException.class).hasMessage("At least one end node must be provided."); } @Test - public void testLeastCostEndNodeReached_oneEndNode() { + void testLeastCostEndNodeReached_oneEndNode() { var endNodeId = Id.createNodeId("end_node"); var otherNodeId = Id.createNodeId("other_node"); @@ -152,7 +152,7 @@ public void testLeastCostEndNodeReached_oneEndNode() { } @Test - public void testLeastCostEndNodeReached_twoEndNodes_stopBeforeReachingTheOtherEndNode() { + void testLeastCostEndNodeReached_twoEndNodes_stopBeforeReachingTheOtherEndNode() { var endNodeId1 = Id.createNodeId("end_node"); var endNodeId2 = Id.createNodeId("end_node_2"); var otherNodeId = Id.createNodeId("other_node"); @@ -172,7 +172,7 @@ public void testLeastCostEndNodeReached_twoEndNodes_stopBeforeReachingTheOtherEn } @Test - public void testLeastCostEndNodeReached_twoEndNodes_bothVisited_fartherEndNodeWithLowerTotalCost() { + void testLeastCostEndNodeReached_twoEndNodes_bothVisited_fartherEndNodeWithLowerTotalCost() { var endNodeId1 = Id.createNodeId("end_node"); var endNodeId2 = Id.createNodeId("end_node_2"); @@ -192,7 +192,7 @@ public void testLeastCostEndNodeReached_twoEndNodes_bothVisited_fartherEndNodeWi } @Test - public void testLeastCostEndNodeReached_twoEndNodes_noAdditionalCost_stopAfterVisitingFirstEndNode() { + void testLeastCostEndNodeReached_twoEndNodes_noAdditionalCost_stopAfterVisitingFirstEndNode() { var endNodeId1 = Id.createNodeId("end_node"); var endNodeId2 = Id.createNodeId("end_node_2"); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/OneToManyPathCalculatorTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/OneToManyPathCalculatorTest.java index d042fb3c814..2db1640cdf5 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/OneToManyPathCalculatorTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/path/OneToManyPathCalculatorTest.java @@ -26,8 +26,8 @@ import java.util.List; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; @@ -68,7 +68,7 @@ public class OneToManyPathCalculatorTest { private final LeastCostPathTree dijkstraTree = new LeastCostPathTree(new SpeedyGraph(network), travelTime, new TimeAsTravelDisutility(travelTime)); - @Before + @BeforeEach public void init() { for (Node node : List.of(nodeA, nodeB, nodeC, nodeD, nodeE)) { nodeMap.put(node.getId(), node); @@ -76,7 +76,7 @@ public void init() { } @Test - public void forward_fromNodeB_toNodeB() { + void forward_fromNodeB_toNodeB() { //forward search starting from nodeB at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, true, linkAB, 0); @@ -94,7 +94,7 @@ public void forward_fromNodeB_toNodeB() { } @Test - public void forward_fromNodeB_toNodesBD() { + void forward_fromNodeB_toNodesBD() { //forward search starting from nodeB at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, true, linkAB, 0); @@ -109,7 +109,7 @@ public void forward_fromNodeB_toNodesBD() { } @Test - public void forward_fromNodeB_toNodesBD_maxTravelTime() { + void forward_fromNodeB_toNodesBD_maxTravelTime() { //forward search starting from nodeB at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, true, linkAB, 0); @@ -124,7 +124,7 @@ public void forward_fromNodeB_toNodesBD_maxTravelTime() { } @Test - public void backward_fromNodeD_toNodeD() { + void backward_fromNodeD_toNodeD() { //backward search starting from nodeD at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, false, linkDE, 0); @@ -142,7 +142,7 @@ public void backward_fromNodeD_toNodeD() { } @Test - public void backward_fromNodeD_toNodesBD() { + void backward_fromNodeD_toNodesBD() { //backward search starting from nodeD at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, false, linkDE, 0); @@ -157,7 +157,7 @@ public void backward_fromNodeD_toNodesBD() { } @Test - public void backward_fromNodeD_toNodesBD_maxTravelTime() { + void backward_fromNodeD_toNodesBD_maxTravelTime() { //backward search starting from nodeD at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, false, linkDE, 0); @@ -172,7 +172,7 @@ public void backward_fromNodeD_toNodesBD_maxTravelTime() { } @Test - public void equalFromLinkAndToLink() { + void equalFromLinkAndToLink() { LeastCostPathTree mockedTree = mock(LeastCostPathTree.class); for (boolean forward : List.of(true, false)) { @@ -186,7 +186,7 @@ public void equalFromLinkAndToLink() { } @Test - public void pathData_forward() { + void pathData_forward() { //forward search starting from linkAB at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, true, linkAB, 0); @@ -198,7 +198,7 @@ public void pathData_forward() { } @Test - public void pathData_backward() { + void pathData_backward() { //backward search starting from linkDE at time 0 var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, false, linkDE, 0); @@ -210,7 +210,7 @@ public void pathData_backward() { } @Test - public void pathData_fromLinkEqualsToLink() { + void pathData_fromLinkEqualsToLink() { for (boolean forward : List.of(true, false)) { var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, forward, linkAB, 0); pathCalculator.calculateDijkstraTree(List.of(linkAB)); @@ -219,7 +219,7 @@ public void pathData_fromLinkEqualsToLink() { } @Test - public void pathData_nodeNotReached() { + void pathData_nodeNotReached() { for (boolean forward : List.of(true, false)) { var pathCalculator = new OneToManyPathCalculator(nodeMap, dijkstraTree, travelTime, forward, linkAB, 0); pathCalculator.calculateDijkstraTree(List.of(linkBC)); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/DiversionTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/DiversionTest.java index 5f158a0480a..2aa72304e53 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/DiversionTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/DiversionTest.java @@ -4,9 +4,8 @@ import java.util.List; import java.util.Objects; import java.util.Set; - -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -75,7 +74,6 @@ public class DiversionTest { static public final String MODE = "testmode"; static public final int DIVERSION_FREQUENCY = 10; - @Test /** * This is a relatively complex test to the the diversion behaviour. The * experiment is constructed as folows: We have one DVRP vehicle which moves @@ -120,14 +118,15 @@ public class DiversionTest { * current one. * */ - public void testRepeatedSameDestinationDiversions() { + @Test + void testRepeatedSameDestinationDiversions() { Config config = ConfigUtils.createConfig(); { /* Create some necessary configuration for the test */ - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(0); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); config.qsim().setStartTime(0.0); config.qsim().setSimStarttimeInterpretation(StarttimeInterpretation.onlyUseStarttime); @@ -221,18 +220,18 @@ protected void configureQSim() { // Took the fixed value from the simulation, to make sure this stays consistent // over refactorings - Assert.assertEquals(testTracker.eventBasedArrivalTime, 657.0, 0); + Assertions.assertEquals(testTracker.eventBasedArrivalTime, 657.0, 0); // Initially calculated arrival time should predict correctly the final arrival // time - Assert.assertEquals(testTracker.initialArrivalTime, 657.0, 0); + Assertions.assertEquals(testTracker.initialArrivalTime, 657.0, 0); // Along the route, when diverting to the same destination, arrival time should // stay constant - testTracker.diversionArrivalTimes.forEach(t -> Assert.assertEquals(t, 657.0, 0)); + testTracker.diversionArrivalTimes.forEach(t -> Assertions.assertEquals(t, 657.0, 0)); // Also ,the task end time should be consistent with the path - testTracker.taskEndTimes.forEach(t -> Assert.assertEquals(t, 657.0, 0)); + testTracker.taskEndTimes.forEach(t -> Assertions.assertEquals(t, 657.0, 0)); } static private class TestModeModule extends AbstractDvrpModeModule { @@ -423,7 +422,6 @@ static private class TestTracker { private List taskEndTimes = new LinkedList<>(); } - @Test /** * This test is similar as the one above. However, there is another catch when * diverting, which is not covered on top. In fact, following the QSim and @@ -447,14 +445,15 @@ static private class TestTracker { * get a reduced arrival time estimate by one second. * */ - public void testRepeatedDiversionToDifferentDestinationRightBeforeLastLink() { + @Test + void testRepeatedDiversionToDifferentDestinationRightBeforeLastLink() { Config config = ConfigUtils.createConfig(); { /* Create some necessary configuration for the test */ - config.controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setLastIteration(0); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(0); config.qsim().setStartTime(0.0); config.qsim().setSimStarttimeInterpretation(StarttimeInterpretation.onlyUseStarttime); @@ -549,15 +548,15 @@ protected void configureQSim() { // Took the fixed value from the simulation, to make sure this stays consistent // over refactorings - same as previous unit test - Assert.assertEquals(testTracker.eventBasedArrivalTime, 657.0, 0); + Assertions.assertEquals(testTracker.eventBasedArrivalTime, 657.0, 0); // Initially calculated arrival time should predict correctly the final arrival // time - as in the first unit test as we route to L8 - Assert.assertEquals(testTracker.initialArrivalTime, 657.0, 0); + Assertions.assertEquals(testTracker.initialArrivalTime, 657.0, 0); // Along the route, when diverting to the same destination, arrival time should // stay constant - testTracker.diversionArrivalTimes.forEach(t -> Assert.assertEquals(t, 739.0, 0)); + testTracker.diversionArrivalTimes.forEach(t -> Assertions.assertEquals(t, 739.0, 0)); // Without fix in OnlineDriveTaskTrackerImpl, the last test will lead to a // difference of one second for the samples at late times diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/RoutingTimeStructureTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/RoutingTimeStructureTest.java index 41760878b96..f670f83a405 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/RoutingTimeStructureTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/router/RoutingTimeStructureTest.java @@ -28,7 +28,7 @@ import java.util.Optional; import org.apache.commons.lang3.tuple.Pair; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; @@ -49,7 +49,7 @@ */ public class RoutingTimeStructureTest { @Test - public void testTimingWithSimpleAccess() { + void testTimingWithSimpleAccess() { TimeInterpretation timeInterpretation = TimeInterpretation.create(ConfigUtils.createConfig()); Facility fromFacility = mock(Facility.class); @@ -109,7 +109,7 @@ public void testTimingWithSimpleAccess() { } @Test - public void testTimingWithComplexAccess() { + void testTimingWithComplexAccess() { TimeInterpretation timeInterpretation = TimeInterpretation.create(ConfigUtils.createConfig()); Facility fromFacility = mock(Facility.class); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimatorTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimatorTest.java index 229738c16ce..808df1ff835 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimatorTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimeEstimatorTest.java @@ -22,8 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -61,7 +60,7 @@ public class DvrpOfflineTravelTimeEstimatorTest { private final TimeDiscretizer timeDiscretizer = new TimeDiscretizer(200, 100); @Test - public void getLinkTravelTime_timeAreCorrectlyBinned() { + void getLinkTravelTime_timeAreCorrectlyBinned() { var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer, 0.25, null); //bin 0 @@ -79,7 +78,7 @@ public void getLinkTravelTime_timeAreCorrectlyBinned() { } @Test - public void getLinkTravelTime_exponentialAveragingOverIterations() { + void getLinkTravelTime_exponentialAveragingOverIterations() { double alpha = 0.25; //observed TTs for each time bin @@ -124,7 +123,7 @@ public void getLinkTravelTime_exponentialAveragingOverIterations() { } @Test - public void getLinkTravelTime_linkOutsideNetwork_fail() { + void getLinkTravelTime_linkOutsideNetwork_fail() { var linkOutsideNetwork = new FakeLink(Id.createLinkId("some-link")); var estimator = new DvrpOfflineTravelTimeEstimator(initialTT, null, network, timeDiscretizer, 0.25, null); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimesTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimesTest.java index efaa83bac7b..e3b904d4084 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimesTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/trafficmonitoring/DvrpOfflineTravelTimesTest.java @@ -34,8 +34,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.common.timeprofile.TimeDiscretizer; @@ -52,7 +51,7 @@ public class DvrpOfflineTravelTimesTest { private final Id linkIdB = Id.createLinkId("B"); @Test - public void saveLinkTravelTimes() throws IOException { + void saveLinkTravelTimes() throws IOException { //the matrix may have more than 2 rows (depends on how many link ids are cached) var linkTTs = new double[Id.getNumberOfIds(Link.class)][]; @@ -70,7 +69,7 @@ public void saveLinkTravelTimes() throws IOException { } @Test - public void loadLinkTravelTimes() throws IOException { + void loadLinkTravelTimes() throws IOException { var line0 = String.join(";", "linkId", "0.0", "900.0", "1800.0", "2700.0", "3600.0"); var line1 = String.join(";", "A", 0.1 + "", 1.1 + "", 2.2 + "", 3.3 + "", 4.4 + ""); var line2 = String.join(";", "B", 5.5 + "", 6.6 + "", 7.7 + "", 8.8 + "", 9.9 + ""); @@ -89,7 +88,7 @@ public void loadLinkTravelTimes() throws IOException { } @Test - public void convertToLinkTravelTimes() { + void convertToLinkTravelTimes() { var link = new FakeLink(Id.createLinkId("link_A")); var timeDiscretizer = new TimeDiscretizer(100, 100); @@ -105,7 +104,7 @@ public void convertToLinkTravelTimes() { } @Test - public void asTravelTime() { + void asTravelTime() { var linkA = new FakeLink(Id.createLinkId("link_A")); var linkB = new FakeLink(Id.createLinkId("link_B")); var timeDiscretizer = new TimeDiscretizer(100, 100); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/util/DvrpEventsReadersTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/util/DvrpEventsReadersTest.java index fec0ba99afc..3f8cbc2594e 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/util/DvrpEventsReadersTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/util/DvrpEventsReadersTest.java @@ -21,14 +21,15 @@ package org.matsim.contrib.dvrp.util; import static org.assertj.core.api.Assertions.assertThat; -import static org.matsim.core.config.groups.ControlerConfigGroup.EventsFileFormat; +import static org.matsim.core.config.groups.ControllerConfigGroup.EventsFileFormat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.Event; import org.matsim.api.core.v01.network.Link; @@ -71,16 +72,16 @@ private enum TestTaskType implements Task.TaskType { } private final List dvrpEvents = List.of( - new PassengerRequestSubmittedEvent(0, mode, request, person, fromLink, toLink), - new PassengerRequestScheduledEvent(1, mode, request, person, vehicle, 100, 200), - new PassengerRequestRejectedEvent(2, mode, request, person, "cause_1"), + new PassengerRequestSubmittedEvent(0, mode, request, List.of(person), fromLink, toLink), + new PassengerRequestScheduledEvent(1, mode, request, List.of(person), vehicle, 100, 200), + new PassengerRequestRejectedEvent(2, mode, request, List.of(person), "cause_1"), new PassengerPickedUpEvent(111, mode, request, person, vehicle), new PassengerDroppedOffEvent(222, mode, request, person, vehicle), new TaskStartedEvent(300, mode, vehicle, driver, TestTaskType.DRIVE_TASK, 0, fromLink), new TaskEndedEvent(333, mode, vehicle, driver, TestTaskType.DRIVE_TASK, 0, toLink)); @Test - public void testReader() { + void testReader() { var outputStream = new ByteArrayOutputStream(); EventWriterXML writer = new EventWriterXML(outputStream); dvrpEvents.forEach(writer::handleEvent); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentLogicTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentLogicTest.java index 89958aed641..9546a1ce4e4 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentLogicTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentLogicTest.java @@ -26,7 +26,7 @@ import static org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic.BEFORE_SCHEDULE_ACTIVITY_TYPE; import static org.mockito.Mockito.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; @@ -86,7 +86,7 @@ public void nextTask(DvrpVehicle vehicle) { null, dynAgentLogic); @Test - public void testInitialActivity_unplanned() { + void testInitialActivity_unplanned() { DynActivity initialActivity = dynAgentLogic.computeInitialActivity(dynAgent); assertThat(initialActivity.getActivityType()).isEqualTo(BEFORE_SCHEDULE_ACTIVITY_TYPE); @@ -95,7 +95,7 @@ public void testInitialActivity_unplanned() { } @Test - public void testInitialActivity_planned() { + void testInitialActivity_planned() { DynActivity initialActivity = dynAgentLogic.computeInitialActivity(dynAgent); StayTask task0 = new DefaultStayTask(TestTaskType.TYPE, 10, 90, startLink); @@ -107,7 +107,7 @@ public void testInitialActivity_planned() { } @Test - public void testInitialActivity_started_failure() { + void testInitialActivity_started_failure() { DynActivity initialActivity = dynAgentLogic.computeInitialActivity(dynAgent); StayTask task0 = new DefaultStayTask(TestTaskType.TYPE, 10, 90, startLink); @@ -121,7 +121,7 @@ public void testInitialActivity_started_failure() { } @Test - public void testNextAction_unplanned_completed() { + void testNextAction_unplanned_completed() { IdleDynActivity nextAction = (IdleDynActivity)dynAgentLogic.computeNextAction(null, vehicle.getServiceEndTime()); @@ -131,7 +131,7 @@ public void testNextAction_unplanned_completed() { } @Test - public void testNextAction_planned_started() { + void testNextAction_planned_started() { double time = 10; StayTask task0 = new DefaultStayTask(TestTaskType.TYPE, time, 90, startLink); vehicle.getSchedule().addTask(task0); @@ -142,7 +142,7 @@ public void testNextAction_planned_started() { } @Test - public void testNextAction_started_started() { + void testNextAction_started_started() { double time = 50; StayTask task0 = new DefaultStayTask(TestTaskType.TYPE, 10, time, startLink); vehicle.getSchedule().addTask(task0); @@ -156,7 +156,7 @@ public void testNextAction_started_started() { } @Test - public void testNextAction_started_completed() { + void testNextAction_started_completed() { double time = 90; StayTask task0 = new DefaultStayTask(TestTaskType.TYPE, 10, time, startLink); vehicle.getSchedule().addTask(task0); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExampleTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExampleTest.java index 7076c71a804..78db1598058 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExampleTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/dynagent/examples/random/RunRandomDynAgentExampleTest.java @@ -21,13 +21,13 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; public class RunRandomDynAgentExampleTest { @Test - public void testRun() { + void testRun() { URL networkUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("dvrp-grid"), "config.xml"); RunRandomDynAgentExample.run(networkUrl, "grid_network.xml", false); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java index 697585b3ff6..dc09184888e 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/SquareGridTest.java @@ -25,7 +25,7 @@ import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Node; @@ -36,20 +36,20 @@ */ public class SquareGridTest { @Test - public void emptyNodes_fail() { + void emptyNodes_fail() { assertThatThrownBy(() -> new SquareGrid(List.of(), 100)).isExactlyInstanceOf(IllegalArgumentException.class) .hasMessage("Cannot create SquareGrid if no nodes"); } @Test - public void outsideBoundaries_withinEpsilon_success() { + void outsideBoundaries_withinEpsilon_success() { Node node_0_0 = node(0, 0); SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); assertThatCode(() -> grid.getZone(new Coord(-EPSILON, EPSILON))).doesNotThrowAnyException(); } @Test - public void outsideBoundaries_outsideEpsilon_fail() { + void outsideBoundaries_outsideEpsilon_fail() { Node node_0_0 = node(0, 0); SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); assertThatThrownBy(() -> grid.getZone(new Coord(-2 * EPSILON, 0))).isExactlyInstanceOf( @@ -57,7 +57,7 @@ public void outsideBoundaries_outsideEpsilon_fail() { } @Test - public void testLazyZoneCreation() { + void testLazyZoneCreation() { Node node_0_0 = node(0, 0); SquareGrid grid = new SquareGrid(List.of(node_0_0), 100); @@ -69,7 +69,7 @@ public void testLazyZoneCreation() { } @Test - public void testGrid() { + void testGrid() { Node node_0_0 = node(0, 0); Node node_150_150 = node(150, 150); SquareGrid grid = new SquareGrid(List.of(node_0_0, node_150_150), 100); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java index e5522c47942..c5743ffaafb 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; @@ -47,7 +47,7 @@ public FreeSpeedTravelTimeMatrixTest() { } @Test - public void matrix() { + void matrix() { DvrpTravelTimeMatrixParams params = new DvrpTravelTimeMatrixParams(); params.cellSize = 100; params.maxNeighborDistance = 0; @@ -67,7 +67,7 @@ public void matrix() { } @Test - public void sparseMatrix() { + void sparseMatrix() { DvrpTravelTimeMatrixParams params = new DvrpTravelTimeMatrixParams(); params.cellSize = 100; params.maxNeighborDistance = 9999; diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java index 18f59308d00..02e6f9fc5dd 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/MatrixTest.java @@ -26,7 +26,7 @@ import java.util.NoSuchElementException; import java.util.Set; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.contrib.zone.Zone; @@ -46,7 +46,7 @@ public class MatrixTest { private final static int MAX_ALLOWED_VALUE = (1 << 16) - 2; @Test - public void get_unsetValue() { + void get_unsetValue() { for (Zone from : zones) { for (Zone to : zones) { assertThatThrownBy(() -> matrix.get(from, to)).isExactlyInstanceOf(NoSuchElementException.class) @@ -56,7 +56,7 @@ public void get_unsetValue() { } @Test - public void get_validValue() { + void get_validValue() { matrix.set(zoneA, zoneB, 0); assertThat(matrix.get(zoneA, zoneB)).isEqualTo(0); @@ -65,7 +65,7 @@ public void get_validValue() { } @Test - public void set_invalidValue() { + void set_invalidValue() { assertThatThrownBy(() -> matrix.set(zoneA, zoneB, Double.POSITIVE_INFINITY)).isExactlyInstanceOf( IllegalArgumentException.class); assertThatThrownBy(() -> matrix.set(zoneA, zoneC, -1)).isExactlyInstanceOf(IllegalArgumentException.class); @@ -74,13 +74,13 @@ public void set_invalidValue() { } @Test - public void get_unknownZone() { + void get_unknownZone() { assertThatThrownBy(() -> matrix.get(zoneA, unknownZone)).isExactlyInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> matrix.get(unknownZone, zoneC)).isExactlyInstanceOf(IllegalArgumentException.class); } @Test - public void set_unknownZone() { + void set_unknownZone() { assertThatThrownBy(() -> matrix.set(zoneA, unknownZone, 1)).isExactlyInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> matrix.set(unknownZone, zoneC, 1)).isExactlyInstanceOf(IllegalArgumentException.class); } diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/SparseMatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/SparseMatrixTest.java index 808730fea7c..a277900e956 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/SparseMatrixTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/SparseMatrixTest.java @@ -24,8 +24,7 @@ import static org.matsim.contrib.zone.skims.SparseMatrix.SparseRow; import java.util.List; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Node; import org.matsim.contrib.zone.skims.SparseMatrix.NodeAndTime; @@ -44,7 +43,7 @@ public class SparseMatrixTest { private final List allNodes = List.of(nodeA, nodeB, nodeC); @Test - public void emptyMatrix() { + void emptyMatrix() { var matrix = new SparseMatrix(); for (Node from : allNodes) { for (Node to : allNodes) { @@ -54,7 +53,7 @@ public void emptyMatrix() { } @Test - public void triangularMatrix() { + void triangularMatrix() { var matrix = new SparseMatrix(); //A -> A, B, C matrix.setRow(nodeA, @@ -76,7 +75,7 @@ public void triangularMatrix() { } @Test - public void nodeAndTimeOrderNotImportant() { + void nodeAndTimeOrderNotImportant() { //A -> A, B, C var nodeAndTimes = List.of(nodeAndTime(nodeA, 0), nodeAndTime(nodeB, 1), nodeAndTime(nodeC, 2)); diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java index 380ab35182c..02d7b7bd241 100644 --- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/TravelTimeMatricesTest.java @@ -24,7 +24,7 @@ import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Network; @@ -39,7 +39,7 @@ */ public class TravelTimeMatricesTest { @Test - public void travelTimeMatrix() { + void travelTimeMatrix() { Network network = NetworkUtils.createNetwork(); Node nodeA = NetworkUtils.createAndAddNode(network, Id.createNodeId("A"), new Coord(0, 0)); Node nodeB = NetworkUtils.createAndAddNode(network, Id.createNodeId("B"), new Coord(150, 150)); @@ -58,7 +58,7 @@ public void travelTimeMatrix() { } @Test - public void travelTimeSparseMatrix_maxDistance() { + void travelTimeSparseMatrix_maxDistance() { Network network = NetworkUtils.createNetwork(); Node nodeA = NetworkUtils.createAndAddNode(network, Id.createNodeId("A"), new Coord(0, 0)); Node nodeB = NetworkUtils.createAndAddNode(network, Id.createNodeId("B"), new Coord(150, 150)); @@ -69,7 +69,7 @@ public void travelTimeSparseMatrix_maxDistance() { NetworkUtils.createAndAddLink(network, Id.createLinkId("CA"), nodeC, nodeA, 600, 15, 80, 1); double maxDistance = 300;// B->A->C and C->A->B are pruned by the limit - var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), maxDistance, 0, 0); + var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), maxDistance, 0, 0).orElseThrow(); assertThat(matrix.get(nodeA, nodeA)).isEqualTo(0); assertThat(matrix.get(nodeA, nodeB)).isEqualTo(10); @@ -85,7 +85,7 @@ public void travelTimeSparseMatrix_maxDistance() { } @Test - public void travelTimeSparseMatrix_maxTravelTime() { + void travelTimeSparseMatrix_maxTravelTime() { Network network = NetworkUtils.createNetwork(); Node nodeA = NetworkUtils.createAndAddNode(network, Id.createNodeId("A"), new Coord(0, 0)); Node nodeB = NetworkUtils.createAndAddNode(network, Id.createNodeId("B"), new Coord(150, 150)); @@ -97,7 +97,7 @@ public void travelTimeSparseMatrix_maxTravelTime() { // 20 s (max TT) corresponds to 300 m (max distance) in another test (see: travelTimeSparseMatrix_maxDistance()) double maxTravelTime = 20;// B->A->C and C->A->B are pruned by the limit - var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), 0, maxTravelTime, 0); + var matrix = TravelTimeMatrices.calculateTravelTimeSparseMatrix(routingParams(network), 0, maxTravelTime, 0).orElseThrow(); assertThat(matrix.get(nodeA, nodeA)).isEqualTo(0); assertThat(matrix.get(nodeA, nodeB)).isEqualTo(10); diff --git a/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTBackwardTest.java b/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTBackwardTest.java index 7377d2c7ba0..828831db27b 100644 --- a/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTBackwardTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTBackwardTest.java @@ -24,7 +24,7 @@ import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -80,7 +80,7 @@ public class SpeedyMultiSourceALTBackwardTest { travelDisutility); @Test - public void testOneSource_backward() { + void testOneSource_backward() { var startNode = new StartNode(nodeB, 9999, 7777); var path = multiSourceALT.calcLeastCostPath(List.of(startNode), nodeA, null, null, true); assertThat(path.nodes).containsExactly(nodeA, nodeE, nodeD, nodeB); @@ -90,7 +90,7 @@ public void testOneSource_backward() { } @Test - public void testManySources_backward_sameStartCost() { + void testManySources_backward_sameStartCost() { var startNodeB = new StartNode(nodeB, 9999, 7777); var startNodeC = new StartNode(nodeC, 9999, 7777); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, true); @@ -101,7 +101,7 @@ public void testManySources_backward_sameStartCost() { } @Test - public void testManySources_backward_selectFartherNodeWithLowerCost() { + void testManySources_backward_selectFartherNodeWithLowerCost() { var startNodeB = new StartNode(nodeB, 100, 7777); var startNodeC = new StartNode(nodeC, 111, 1111); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, true); @@ -112,7 +112,7 @@ public void testManySources_backward_selectFartherNodeWithLowerCost() { } @Test - public void testManySources_backward_selectNearestNodeWithHigherCost() { + void testManySources_backward_selectNearestNodeWithHigherCost() { var startNodeB = new StartNode(nodeB, 100, 7777); var startNodeC = new StartNode(nodeC, 109, 1111); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, true); diff --git a/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTForwardTest.java b/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTForwardTest.java index 35158e0b0c1..45287f7b776 100644 --- a/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTForwardTest.java +++ b/contribs/dvrp/src/test/java/org/matsim/core/router/speedy/SpeedyMultiSourceALTForwardTest.java @@ -24,7 +24,7 @@ import java.util.List; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -78,7 +78,7 @@ public class SpeedyMultiSourceALTForwardTest { travelDisutility); @Test - public void testOneSource_forward() { + void testOneSource_forward() { var startNode = new StartNode(nodeB, 9999, 7777); var path = multiSourceALT.calcLeastCostPath(List.of(startNode), nodeA, null, null, false); assertThat(path.nodes).containsExactly(nodeB, nodeD, nodeE, nodeA); @@ -88,7 +88,7 @@ public void testOneSource_forward() { } @Test - public void testManySources_forward_sameStartCost() { + void testManySources_forward_sameStartCost() { var startNodeB = new StartNode(nodeB, 9999, 7777); var startNodeC = new StartNode(nodeC, 9999, 7777); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, false); @@ -99,7 +99,7 @@ public void testManySources_forward_sameStartCost() { } @Test - public void testManySources_forward_selectFartherNodeWithLowerCost() { + void testManySources_forward_selectFartherNodeWithLowerCost() { var startNodeB = new StartNode(nodeB, 100, 7777); var startNodeC = new StartNode(nodeC, 111, 1111); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, false); @@ -110,7 +110,7 @@ public void testManySources_forward_selectFartherNodeWithLowerCost() { } @Test - public void testManySources_forward_selectNearestNodeWithHigherCost() { + void testManySources_forward_selectNearestNodeWithHigherCost() { var startNodeB = new StartNode(nodeB, 100, 7777); var startNodeC = new StartNode(nodeC, 109, 1111); var path = multiSourceALT.calcLeastCostPath(List.of(startNodeB, startNodeC), nodeA, null, null, false); diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/PositionEmissionsModule.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/PositionEmissionsModule.java index 5d9974f9c92..4652c3d7339 100644 --- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/PositionEmissionsModule.java +++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/PositionEmissionsModule.java @@ -37,7 +37,7 @@ import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.api.core.v01.events.HasPersonId; import org.matsim.core.config.Config; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.events.MatsimEventsReader; @@ -68,7 +68,7 @@ private static void checkConsistency(Config config) { if (config.qsim().getSnapshotPeriod() > 1) { throw new RuntimeException("only snapshot periods of 1s are supported."); } - if (!config.controler().getSnapshotFormat().contains(ControlerConfigGroup.SnapshotFormat.positionevents)) { + if (!config.controller().getSnapshotFormat().contains(ControllerConfigGroup.SnapshotFormat.positionevents)) { throw new RuntimeException("config.controler.snapshotFormat must be set to 'positionevents'"); } if (isNotCorrectSnapshotStyle(config.qsim().getSnapshotStyle())) { diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/CreateEmissionConfig.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/CreateEmissionConfig.java index 74f24e7321c..f50fc6a6d27 100644 --- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/CreateEmissionConfig.java +++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/CreateEmissionConfig.java @@ -23,19 +23,19 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigWriter; import org.matsim.core.config.groups.*; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ActivityParams; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ScoringConfigGroup.ActivityParams; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.Controler; import org.matsim.core.controler.MatsimServices; /** - * - * Creates a config file + * + * Creates a config file * with necessary emission input files for the {@link EmissionsConfigGroup EmissionsConfigGroup}. - * + * * This config file is used by the {@link RunDetailedEmissionToolOfflineExample OfflineExample} and * the {@link RunDetailedEmissionToolOnlineExample OnlineExample} - * + * * @author benjamin, julia * * @deprecated -- has not been maintained and should in consequence be phased out. kai, nov'21 @@ -45,47 +45,47 @@ public final class CreateEmissionConfig { private static final String inputPath = "./test/input/org/matsim/contrib/emissions/"; - private static final String networkFile = //inputPath + + private static final String networkFile = //inputPath + "sample_network.xml"; - private static final String plansFile = //inputPath + + private static final String plansFile = //inputPath + "sample_population.xml"; - private static final String emissionVehicleFile = //inputPath + + private static final String emissionVehicleFile = //inputPath + "sample_emissionVehicles.xml"; - + private static final String roadTypeMappingFile = //inputPath + "sample_roadTypeMapping.txt"; - + private static final String averageFleetWarmEmissionFactorsFile = //inputPath + "sample_EFA_HOT_vehcat_2005average.txt"; private static final String averageFleetColdEmissionFactorsFile = //inputPath + "sample_EFA_ColdStart_vehcat_2005average.txt"; - + private static final boolean isUsingDetailedEmissionCalculation = true; private static final String detailedWarmEmissionFactorsFile = //inputPath + "sample_EFA_HOT_SubSegm_2005detailed.txt"; private static final String detailedColdEmissionFactorsFile = //inputPath + "sample_EFA_ColdStart_SubSegm_2005detailed.txt"; - + private static final String outputPath = "./test/output/"; private static final String configFilePath = inputPath + "config_v2.xml"; - + private static final int numberOfIterations = 6; - - + + public static void main(String[] args) { - + Config config = new Config(); config.addCoreModules(); MatsimServices controler = new Controler(config); - + // controlerConfigGroup - ControlerConfigGroup ccg = controler.getConfig().controler(); + ControllerConfigGroup ccg = controler.getConfig().controller(); ccg.setOutputDirectory(outputPath); ccg.setFirstIteration(0); ccg.setLastIteration(numberOfIterations-1); - + // planCalcScoreConfigGroup - PlanCalcScoreConfigGroup pcs = controler.getConfig().planCalcScore(); + ScoringConfigGroup pcs = controler.getConfig().scoring(); ActivityParams homeP = new ActivityParams("home"); homeP.setTypicalDuration(12 * 3600); pcs.addActivityParams(homeP); @@ -94,21 +94,21 @@ public static void main(String[] args) { pcs.addActivityParams(workP); // strategy - StrategyConfigGroup scg = controler.getConfig().strategy(); + ReplanningConfigGroup scg = controler.getConfig().replanning(); StrategySettings strategySettings = new StrategySettings(); strategySettings.setStrategyName("ChangeExpBeta"); strategySettings.setWeight(1.0); scg.addStrategySettings(strategySettings); - + // network NetworkConfigGroup ncg = controler.getConfig().network(); ncg.setInputFile(networkFile); - + // plans PlansConfigGroup pcg = controler.getConfig().plans(); pcg.setInputFile(plansFile); - - // define emission tool input files + + // define emission tool input files EmissionsConfigGroup ecg = new EmissionsConfigGroup() ; controler.getConfig().addModule(ecg); @@ -137,11 +137,11 @@ public static void main(String[] args) { // ecg.setEmissionCostMultiplicationFactor(1.0); // ecg.setConsideringCO2Costs(true); // ecg.setEmissionEfficiencyFactor(1.0); - - // write config + + // write config ConfigWriter cw = new ConfigWriter(config); cw.write(configFilePath); - + } diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExample.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExample.java index fd852ba1a61..bd1af3c2a90 100644 --- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExample.java +++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExample.java @@ -26,9 +26,7 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; -import org.matsim.core.controler.Controler; import org.matsim.core.controler.Injector; -import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; import org.matsim.core.events.algorithms.EventWriterXML; @@ -39,7 +37,7 @@ /** * - * Use the config file as created by the + * Use the config file as created by the * {@link CreateEmissionConfig CreateEmissionConfig} to calculate * emissions based on the link leave events of an events file. Resulting emission events are written into an event file. * @@ -55,7 +53,7 @@ public final class RunAverageEmissionToolOfflineExample{ private Config config; - // ======================================================================================================= + // ======================================================================================================= public static void main (String[] args){ RunAverageEmissionToolOfflineExample emissionToolOfflineExampleV2 = new RunAverageEmissionToolOfflineExample(); @@ -105,7 +103,7 @@ public void install(){ EmissionModule emissionModule = injector.getInstance(EmissionModule.class); // OutputDirectoryHierarchy outputDirectoryHierarchy = injector.getInstance( OutputDirectoryHierarchy.class ); - final String outputDirectory = scenario.getConfig().controler().getOutputDirectory(); + final String outputDirectory = scenario.getConfig().controller().getOutputDirectory(); EventWriterXML emissionEventWriter = new EventWriterXML( outputDirectory + emissionEventsFilename ); emissionModule.getEmissionEventsManager().addHandler(emissionEventWriter); diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExample.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExample.java index a4818fcf794..191766556c2 100644 --- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExample.java +++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExample.java @@ -29,7 +29,6 @@ import org.matsim.core.controler.Injector; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; -import org.matsim.core.events.ParallelEventsManager; import org.matsim.core.events.algorithms.EventWriterXML; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.io.IOUtils; @@ -38,7 +37,7 @@ /** * - * Use the config file as created by the + * Use the config file as created by the * {@link CreateEmissionConfig CreateEmissionConfig} to calculate * emissions based on the link leave events of an events file. Resulting emission events are written into an event file. * @@ -54,7 +53,7 @@ public final class RunDetailedEmissionToolOfflineExample{ // private static final String emissionEventOutputFileName = "5.emission.events.offline.xml.gz"; private Config config; - // ======================================================================================================= + // ======================================================================================================= public static void main (String[] args){ RunDetailedEmissionToolOfflineExample emissionToolOfflineExampleV2Vehv1 = new RunDetailedEmissionToolOfflineExample(); @@ -96,7 +95,7 @@ public void install(){ EmissionModule emissionModule = injector.getInstance(EmissionModule.class); - final String outputDirectory = scenario.getConfig().controler().getOutputDirectory(); + final String outputDirectory = scenario.getConfig().controller().getOutputDirectory(); EventWriterXML emissionEventWriter = new EventWriterXML( outputDirectory + RunAverageEmissionToolOfflineExample.emissionEventsFilename ) ; emissionModule.getEmissionEventsManager().addHandler(emissionEventWriter); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/EmissionModuleTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/EmissionModuleTest.java index 5f61653ebc3..c7cde9b6eb1 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/EmissionModuleTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/EmissionModuleTest.java @@ -1,7 +1,7 @@ package org.matsim.contrib.emissions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.contrib.emissions.utils.TestUtils; @@ -15,52 +15,55 @@ import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; /** * Most of the other test implicitly test the EmissionModule as well. Still, I guess it makes sense to have this here */ public class EmissionModuleTest { - @Rule - public MatsimTestUtils testUtils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils testUtils = new MatsimTestUtils(); - @Test(expected = RuntimeException.class) - public void testWithIncorrectNetwork() { + @Test + void testWithIncorrectNetwork() { + assertThrows(RuntimeException.class, () -> { - var scenarioURL = ExamplesUtils.getTestScenarioURL("emissions-sampleScenario"); + var scenarioURL = ExamplesUtils.getTestScenarioURL("emissions-sampleScenario"); - var emissionConfig = new EmissionsConfigGroup(); - emissionConfig.setHbefaTableConsistencyCheckingLevel(EmissionsConfigGroup.HbefaTableConsistencyCheckingLevel.none); - emissionConfig.setAverageColdEmissionFactorsFile(IOUtils.extendUrl(scenarioURL, "sample_41_EFA_ColdStart_SubSegm_2020detailed.csv").toString()); - emissionConfig.setAverageWarmEmissionFactorsFile(IOUtils.extendUrl(scenarioURL, "sample_41_EFA_HOT_vehcat_2020average.csv").toString()); - emissionConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.directlyTryAverageTable); + var emissionConfig = new EmissionsConfigGroup(); + emissionConfig.setHbefaTableConsistencyCheckingLevel(EmissionsConfigGroup.HbefaTableConsistencyCheckingLevel.none); + emissionConfig.setAverageColdEmissionFactorsFile(IOUtils.extendUrl(scenarioURL, "sample_41_EFA_ColdStart_SubSegm_2020detailed.csv").toString()); + emissionConfig.setAverageWarmEmissionFactorsFile(IOUtils.extendUrl(scenarioURL, "sample_41_EFA_HOT_vehcat_2020average.csv").toString()); + emissionConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.directlyTryAverageTable); - var config = ConfigUtils.createConfig(emissionConfig); + var config = ConfigUtils.createConfig(emissionConfig); - // create a scenario with a random network where every link has a hbefa road type except one link. - var scenario = ScenarioUtils.createMutableScenario(config); - var network = TestUtils.createRandomNetwork(1000, 10000, 10000); - new VspHbefaRoadTypeMapping().addHbefaMappings(network); - network.getLinks().values().iterator().next().getAttributes().removeAttribute(EmissionUtils.HBEFA_ROAD_TYPE); - scenario.setNetwork(network); + // create a scenario with a random network where every link has a hbefa road type except one link. + var scenario = ScenarioUtils.createMutableScenario(config); + var network = TestUtils.createRandomNetwork(1000, 10000, 10000); + new VspHbefaRoadTypeMapping().addHbefaMappings(network); + network.getLinks().values().iterator().next().getAttributes().removeAttribute(EmissionUtils.HBEFA_ROAD_TYPE); + scenario.setNetwork(network); - var eventsManager = EventsUtils.createEventsManager(); + var eventsManager = EventsUtils.createEventsManager(); - var module = new AbstractModule() { - @Override - public void install() { - bind(Scenario.class).toInstance(scenario); - bind(EventsManager.class).toInstance(eventsManager); - bind(EmissionModule.class); - } - }; + var module = new AbstractModule() { + @Override + public void install() { + bind(Scenario.class).toInstance(scenario); + bind(EventsManager.class).toInstance(eventsManager); + bind(EmissionModule.class); + } + }; - com.google.inject.Injector injector = Injector.createInjector(config, module); - // this call should cause an exception when the consistency check in the constructor of the emission module fails - injector.getInstance(EmissionModule.class); + com.google.inject.Injector injector = Injector.createInjector(config, module); + // this call should cause an exception when the consistency check in the constructor of the emission module fails + injector.getInstance(EmissionModule.class); - fail("Was expecting exception"); - } -} \ No newline at end of file + fail("Was expecting exception"); + }); + } +} diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/OsmHbefaMappingTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/OsmHbefaMappingTest.java index d0bf9433dfa..195fc6e6fcb 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/OsmHbefaMappingTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/OsmHbefaMappingTest.java @@ -1,17 +1,17 @@ package org.matsim.contrib.emissions; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.core.network.NetworkUtils; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class OsmHbefaMappingTest { - @Test - public void testRegularMapping() { + @Test + void testRegularMapping() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("primary", 70 / 3.6); @@ -22,7 +22,7 @@ public void testRegularMapping() { } @Test - public void testMergedLinkTypeMapping() { + void testMergedLinkTypeMapping() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("primary|railway.tram", 70 / 3.6); @@ -32,19 +32,21 @@ public void testMergedLinkTypeMapping() { assertEquals("URB/Trunk-City/70", hbefaType); } - @Test(expected = RuntimeException.class) - public void testUnknownType() { + @Test + void testUnknownType() { + assertThrows(RuntimeException.class, () -> { - var mapping = OsmHbefaMapping.build(); - var link = getTestLink("unknown-tag", 100 / 3.6); + var mapping = OsmHbefaMapping.build(); + var link = getTestLink("unknown-tag", 100 / 3.6); - mapping.determineHebfaType(link); + mapping.determineHebfaType(link); - fail("Expected Runtime Exception."); - } + fail("Expected Runtime Exception."); + }); + } - @Test - public void testFastMotorway() { + @Test + void testFastMotorway() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("motorway", 100 / 3.6); @@ -55,7 +57,7 @@ public void testFastMotorway() { } @Test - public void testMotorwayWithNoExactSpeedTag() { + void testMotorwayWithNoExactSpeedTag() { var mapping = OsmHbefaMapping.build(); @@ -70,7 +72,7 @@ public void testMotorwayWithNoExactSpeedTag() { } @Test - public void testFastMotorwayLink() { + void testFastMotorwayLink() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("motorway_link", 100 / 3.6); @@ -81,7 +83,7 @@ public void testFastMotorwayLink() { } @Test - public void testLivingStreet() { + void testLivingStreet() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("living_street", 50 / 3.6); @@ -90,8 +92,8 @@ public void testLivingStreet() { assertEquals("URB/Access/50", hbefaType); } - @Test - public void testUnclassified() { + @Test + void testUnclassified() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("unclassified", 50 / 3.6); @@ -101,8 +103,8 @@ public void testUnclassified() { assertEquals("URB/Access/50", hbefaType); } - @Test - public void testNoHighwayType() { + @Test + void testNoHighwayType() { var mapping = OsmHbefaMapping.build(); var link = getTestLink(" ", 60 / 3.6); @@ -112,8 +114,8 @@ public void testNoHighwayType() { assertEquals("URB/Local/60", hbefaType); } - @Test - public void testNoAllowedSpeedTag() { + @Test + void testNoAllowedSpeedTag() { var mapping = OsmHbefaMapping.build(); var link = getTestLink("residential", 40 / 3.6); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModule.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModule.java index 57c8636221a..d5d32b96239 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModule.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModule.java @@ -20,9 +20,9 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -70,11 +70,11 @@ public class TestColdEmissionAnalysisModule { private static final Set pollutants = new HashSet<>(Arrays.asList(CO, CO2_TOTAL, FC, HC, NMHC, NOx, NO2,PM, SO2)); private final int numberOfColdEmissions = pollutants.size(); // strings for test cases - + // The material below was confused in the way that strings like "petrol" or "diesel" were given for the // size classes, and "<1,4L" or ">=2L" for the emissions concept. Tried to make it consistent, // but I don't know if it is still testing the original functionality. kai, jul'18 - + // first case: complete data - corresponding entry in average table private static final String petrol_technology = "petrol"; private static final String none_sizeClass = "average"; @@ -95,7 +95,7 @@ public class TestColdEmissionAnalysisModule { private static final Double averagePetrolFactor = .01; private static final double fakeFactor = -1.; - + private boolean excep = false; @@ -104,7 +104,7 @@ public class TestColdEmissionAnalysisModule { * all of them should throw exceptions */ @Test - public void calculateColdEmissionsAndThrowEventTest_Exceptions() { + void calculateColdEmissionsAndThrowEventTest_Exceptions() { ColdEmissionAnalysisModule coldEmissionAnalysisModule = setUp(); List> testCasesExceptions = new ArrayList<>(); @@ -116,7 +116,7 @@ public void calculateColdEmissionsAndThrowEventTest_Exceptions() { testCasesExceptions.add( Id.create( "", VehicleType.class ) ); //case: null id testCasesExceptions.add( null ); - + for ( Id vehicleTypeId : testCasesExceptions ) { String message = "'" + vehicleTypeId + "'" + " was used to calculate cold emissions and generate an emissions event." + "It should instead throw an exception because it is not a valid vehicle information string."; @@ -128,18 +128,18 @@ public void calculateColdEmissionsAndThrowEventTest_Exceptions() { } catch (Exception e) { excep = true; } - Assert.assertTrue(message, excep); + Assertions.assertTrue(excep, message); excep = false; } } @Test - public void calculateColdEmissionsAndThrowEventTest_minimalVehicleInformation() { + void calculateColdEmissionsAndThrowEventTest_minimalVehicleInformation() { ColdEmissionAnalysisModule coldEmissionAnalysisModule = setUp(); excep = false; - + // case: no specifications for technology, size, class, em concept // string has no semicolons as separators - use average values Id vehInfo11 = Id.create("PASSENGER_CAR", VehicleType.class ); @@ -154,17 +154,17 @@ public void calculateColdEmissionsAndThrowEventTest_minimalVehicleInformation() String message = "The expected emissions for an emissions event with vehicle information string '" + vehInfo11 + "' are " + numberOfColdEmissions * averageAverageFactor + " but were " + sumOfEmissions; - Assert.assertEquals( message, numberOfColdEmissions * averageAverageFactor, sumOfEmissions, MatsimTestUtils.EPSILON ); - + Assertions.assertEquals( numberOfColdEmissions * averageAverageFactor, sumOfEmissions, MatsimTestUtils.EPSILON, message ); + } - + private static ColdEmissionAnalysisModule setUp() { Map avgHbefaColdTable = new HashMap<>(); Map detailedHbefaColdTable = new HashMap<>(); - + fillAveragesTable( avgHbefaColdTable ); fillDetailedTable( detailedHbefaColdTable ); - + EventsManager emissionEventManager = new HandlerToTestEmissionAnalysisModules(); EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); @@ -172,7 +172,7 @@ private static ColdEmissionAnalysisModule setUp() { //This represents the previous behavior, which fallbacks to the average table, if values are not found in the detailed table, kmt apr'20 ecg.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); return new ColdEmissionAnalysisModule( avgHbefaColdTable, detailedHbefaColdTable, ecg, pollutants, emissionEventManager ); - + } @@ -196,36 +196,36 @@ private static void fillDetailedTable( Map avgHbefaColdTable ) { // create all needed and one unneeded entry for the average table { // add passenger car entry "average;average;average": HbefaVehicleAttributes vehAtt = ColdEmissionAnalysisModule.createHbefaVehicleAttributes( "average", "average", "average" ) ; - + putIntoHbefaColdTable( avgHbefaColdTable, vehAtt, new HbefaColdEmissionFactor(averageAverageFactor), PASSENGER_CAR ); } { HbefaVehicleAttributes vehAtt = ColdEmissionAnalysisModule.createHbefaVehicleAttributes( petrol_technology, none_sizeClass, none_emConcept ); - + putIntoHbefaColdTable( avgHbefaColdTable, vehAtt, new HbefaColdEmissionFactor( averagePetrolFactor ), PASSENGER_CAR ); } { // duplicate from detailed table, but with different emission factor. // this should not be used but is needed to assure that the detailed table is tried before the average table HbefaVehicleAttributes vehAtt = ColdEmissionAnalysisModule.createHbefaVehicleAttributes( diesel_technology, geq2l_sizeClass, PC_D_Euro_3_emConcept ); - + putIntoHbefaColdTable( avgHbefaColdTable, vehAtt, new HbefaColdEmissionFactor( fakeFactor ), PASSENGER_CAR ); } { // add HGV entry "petrol;none;none". // (pre-existing comment: HEAVY_GOODS_VEHICLE;PC petrol;petrol;none should not be used --???) final HbefaVehicleAttributes vehAtt = ColdEmissionAnalysisModule.createHbefaVehicleAttributes( petrol_technology, none_sizeClass, none_emConcept ); - + putIntoHbefaColdTable( avgHbefaColdTable, vehAtt, new HbefaColdEmissionFactor( fakeFactor ), HEAVY_GOODS_VEHICLE ); } } - + private static void putIntoHbefaColdTable( final Map detailedHbefaColdTable, final HbefaVehicleAttributes vehAtt, final HbefaColdEmissionFactor detColdFactor, final HbefaVehicleCategory hbefaVehicleCategory ) { for ( Pollutant cp : pollutants ) { HbefaColdEmissionFactorKey detColdKey = new HbefaColdEmissionFactorKey(); @@ -237,5 +237,5 @@ private static void putIntoHbefaColdTable( final Map testCase1 = new ArrayList<>(); // first case: complete data @@ -119,7 +119,7 @@ public void calculateColdEmissionsAndThrowEventTest_completeData() { double sumOfEmissions = calculatedPollutants.values().stream().mapToDouble(Double::doubleValue).sum(); String message = "The expected emissions for " + testCase1.toString() + " are " + pollutants.size() * (Double) testCase1.get(4) + " but were " + sumOfEmissions; - Assert.assertEquals(message, pollutants.size() * (Double) testCase1.get(4), sumOfEmissions, MatsimTestUtils.EPSILON); + Assertions.assertEquals(pollutants.size() * (Double) testCase1.get(4), sumOfEmissions, MatsimTestUtils.EPSILON, message); } private static ColdEmissionAnalysisModule setUp() { diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase2.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase2.java index feed9108fb3..c97de7d7ecd 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase2.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase2.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -93,7 +93,7 @@ public class TestColdEmissionAnalysisModuleCase2 { private static final double fakeFactor = -1.; @Test - public void calculateColdEmissionsAndThrowEventTest_completeData() { + void calculateColdEmissionsAndThrowEventTest_completeData() { ColdEmissionAnalysisModule coldEmissionAnalysisModule = setUp(); @@ -112,7 +112,7 @@ public void calculateColdEmissionsAndThrowEventTest_completeData() { double sumOfEmissions = calculatedPollutants.values().stream().mapToDouble(Double::doubleValue).sum(); String message = "The expected emissions for " + testCase2.toString() + " are " + pollutants.size() * (Double) testCase2.get( 4 ) + " but were " + sumOfEmissions; - Assert.assertEquals( message, pollutants.size() * (Double) testCase2.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * (Double) testCase2.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON, message ); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase3.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase3.java index 861850165d5..3da0de0f540 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase3.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase3.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -94,7 +94,7 @@ public class TestColdEmissionAnalysisModuleCase3 { private static final double fakeFactor = -1.; @Test - public void calculateColdEmissionsAndThrowEventTest_completeData() { + void calculateColdEmissionsAndThrowEventTest_completeData() { ColdEmissionAnalysisModule coldEmissionAnalysisModule = setUp(); ArrayList testCase3 = new ArrayList<>(); @@ -116,7 +116,7 @@ public void calculateColdEmissionsAndThrowEventTest_completeData() { double sumOfEmissions = calculatedPollutants.values().stream().mapToDouble(Double::doubleValue).sum(); String message = "The expected emissions for " + testCase3.toString() + " are " + pollutants.size() * (Double) testCase3.get( 4 ) + " but were " + sumOfEmissions; - Assert.assertEquals( message, pollutants.size() * (Double) testCase3.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * (Double) testCase3.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON, message ); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase4.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase4.java index 8664f465e36..726297486d3 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase4.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase4.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -97,9 +97,9 @@ public class TestColdEmissionAnalysisModuleCase4 { private static final double fakeFactor = -1.; - + @Test - public void calculateColdEmissionsAndThrowEventTest_completeData() { + void calculateColdEmissionsAndThrowEventTest_completeData() { /* * test cases with complete input data or input that should be assigned to average/default cases @@ -126,7 +126,7 @@ public void calculateColdEmissionsAndThrowEventTest_completeData() { double sumOfEmissions = calculatedPollutants.values().stream().mapToDouble(Double::doubleValue).sum(); String message = "The expected emissions for " + testCase4.toString() + " are " + pollutants.size() * (Double) testCase4.get( 4 ) + " but were " + sumOfEmissions; - Assert.assertEquals( message, pollutants.size() * (Double) testCase4.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * (Double) testCase4.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON, message ); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase6.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase6.java index 2901ffba8c9..97abfd77803 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase6.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionAnalysisModuleCase6.java @@ -22,8 +22,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -91,9 +91,9 @@ public class TestColdEmissionAnalysisModuleCase6 { private static final double heavyGoodsFactor = -1.; - + @Test - public void calculateColdEmissionsAndThrowEventTest_completeData() { + void calculateColdEmissionsAndThrowEventTest_completeData() { /* * six test cases with complete input data @@ -121,7 +121,7 @@ public void calculateColdEmissionsAndThrowEventTest_completeData() { double sumOfEmissions = calculatedPollutants.values().stream().mapToDouble(Double::doubleValue).sum(); String message = "The expected emissions for " + testCase6.toString() + " are " + pollutants.size() * (Double) testCase6.get( 4 ) + " but were " + sumOfEmissions; - Assert.assertEquals( message, pollutants.size() * (Double) testCase6.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * (Double) testCase6.get( 4 ), sumOfEmissions, MatsimTestUtils.EPSILON, message ); } private ColdEmissionAnalysisModule setUp() { diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionsFallbackBehaviour.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionsFallbackBehaviour.java index 4022a553a46..cef4618571e 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionsFallbackBehaviour.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestColdEmissionsFallbackBehaviour.java @@ -21,8 +21,10 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -80,14 +82,14 @@ public class TestColdEmissionsFallbackBehaviour { * -> should calculate value */ @Test - public void testColdDetailedValueOnlyDetailed() { + void testColdDetailedValueOnlyDetailed() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() .checkVehicleInfoAndCalculateWColdEmissions(vehicleFull.getType(), vehicleFull.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -98,13 +100,15 @@ public void testColdDetailedValueOnlyDetailed() { * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testCold_DetailedElseAbort_ShouldAbort1() { - EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); - - emissionModule.getColdEmissionAnalysisModule() - .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToTechnologyAverage.getType(), - vehicleFallbackToTechnologyAverage.getId(), link.getId(), startTime, parkingDuration, distance); + @Test + void testCold_DetailedElseAbort_ShouldAbort1() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + + emissionModule.getColdEmissionAnalysisModule() + .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToTechnologyAverage.getType(), + vehicleFallbackToTechnologyAverage.getId(), link.getId(), startTime, parkingDuration, distance); + }); } /** @@ -115,13 +119,15 @@ public void testCold_DetailedElseAbort_ShouldAbort1() { * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testCold_DetailedElseAbort_ShouldAbort2() { - EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); - - emissionModule.getColdEmissionAnalysisModule() - .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToTechnologyAverage.getType(), - vehicleFallbackToAverageTable.getId(), link.getId(), startTime, parkingDuration, distance); + @Test + void testCold_DetailedElseAbort_ShouldAbort2() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + + emissionModule.getColdEmissionAnalysisModule() + .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToTechnologyAverage.getType(), + vehicleFallbackToAverageTable.getId(), link.getId(), startTime, parkingDuration, distance); + }); } @@ -134,14 +140,14 @@ public void testCold_DetailedElseAbort_ShouldAbort2() { * ---> should calculate value from detailed value */ @Test - public void testCold_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() { + void testCold_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageElseAbort ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() .checkVehicleInfoAndCalculateWColdEmissions(vehicleFull.getType(), vehicleFull.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -153,7 +159,7 @@ public void testCold_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() * ---> should calculate value from technology average */ @Test - public void testCold_DetailedThenTechnologyAverageElseAbort_FallbackToTechnologyAverage() { + void testCold_DetailedThenTechnologyAverageElseAbort_FallbackToTechnologyAverage() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageElseAbort ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() @@ -161,7 +167,7 @@ public void testCold_DetailedThenTechnologyAverageElseAbort_FallbackToTechnology vehicleFallbackToTechnologyAverage.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_TechnologyAverage, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_TechnologyAverage, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } /** @@ -172,13 +178,15 @@ public void testCold_DetailedThenTechnologyAverageElseAbort_FallbackToTechnology * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testCold_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { - EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); - - emissionModule.getColdEmissionAnalysisModule() - .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToAverageTable.getType(), - vehicleFallbackToAverageTable.getId(), link.getId(), startTime, parkingDuration, distance); + @Test + void testCold_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + + emissionModule.getColdEmissionAnalysisModule() + .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToAverageTable.getType(), + vehicleFallbackToAverageTable.getId(), link.getId(), startTime, parkingDuration, distance); + }); } // --------- DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ----------- @@ -190,14 +198,14 @@ public void testCold_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { * ---> should calculate value from detailed value */ @Test - public void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNeeded() { + void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNeeded() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() .checkVehicleInfoAndCalculateWColdEmissions(vehicleFull.getType(), vehicleFull.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_Detailed, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -209,14 +217,14 @@ public void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNe * ---> should calculate value from technology average */ @Test - public void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackToTechnology() { + void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackToTechnology() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToTechnologyAverage.getType(), vehicleFallbackToTechnologyAverage.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_TechnologyAverage, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_TechnologyAverage, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } /** @@ -229,14 +237,14 @@ public void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackToTec * ---> should calculate value from average table */ @Test - public void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackToAverageTable() { + void testCold_DetailedThenTechnologyAverageThenAverageTable_FallbackToAverageTable() { EmissionModule emissionModule = setUpScenario( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); Map coldEmissions = emissionModule.getColdEmissionAnalysisModule() .checkVehicleInfoAndCalculateWColdEmissions(vehicleFallbackToAverageTable.getType(), vehicleFallbackToAverageTable.getId(), link.getId(), startTime, parkingDuration, distance); - Assert.assertEquals(emissionsFactorInGrammPerKilometer_AverageTable, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(emissionsFactorInGrammPerKilometer_AverageTable, coldEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaColdEmissionFactorKey.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaColdEmissionFactorKey.java index 861d12b5b2b..13efc7bf890 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaColdEmissionFactorKey.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaColdEmissionFactorKey.java @@ -20,10 +20,10 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.matsim.contrib.emissions.Pollutant.CO; import static org.matsim.contrib.emissions.Pollutant.FC; @@ -61,7 +61,7 @@ private void setUp(){ @Test - public final void testEqualsForCompleteKeys() { + final void testEqualsForCompleteKeys() { setUp(); @@ -83,8 +83,8 @@ public final void testEqualsForCompleteKeys() { compare.setVehicleCategory(hbefaVehCategory); String message = "these two objects should be the same but are not: " + normal.toString() + " and " + compare.toString(); - Assert.assertEquals(message, normal, compare); - Assert.assertEquals(message, compare, normal); + Assertions.assertEquals(normal, compare, message); + Assertions.assertEquals(compare, normal, message); } { @@ -101,8 +101,8 @@ public final void testEqualsForCompleteKeys() { different.setVehicleCategory(HbefaVehicleCategory.HEAVY_GOODS_VEHICLE); String message = "these two objects should not be the same: " + normal.toString() + " and " + different.toString(); - assertNotEquals(message, normal, different); - assertNotEquals(message, different, normal); + assertNotEquals(normal, different, message); + assertNotEquals(different, normal, message); } } @@ -113,7 +113,7 @@ public final void testEqualsForCompleteKeys() { //exception: if the vehicleAttributes are set to 'average' by default @Test - public final void testEqualsForIncompleteKeys_vehicleCategory(){ + final void testEqualsForIncompleteKeys_vehicleCategory(){ setUp(); //normal HbefaColdEmissionFactorKey @@ -128,11 +128,11 @@ public final void testEqualsForIncompleteKeys_vehicleCategory(){ noVehCat.setVehicleAttributes(hbefaVehicleAttributes); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noVehCat.toString(); - assertFalse(message, noVehCat.equals(normal)); + assertFalse(noVehCat.equals(normal), message); } @Test - public final void testEqualsForIncompleteKeys_pollutant(){ + final void testEqualsForIncompleteKeys_pollutant(){ // generate a complete HbefaColdEmissionFactorKey: 'normal' // and set some parameters @@ -147,11 +147,11 @@ public final void testEqualsForIncompleteKeys_pollutant(){ noColdPollutant.setVehicleAttributes(hbefaVehicleAttributes); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noColdPollutant.toString(); - assertFalse(message, noColdPollutant.equals(normal)); + assertFalse(noColdPollutant.equals(normal), message); } @Test - public final void testEqualsForIncompleteKeys_parkingTime() { + final void testEqualsForIncompleteKeys_parkingTime() { // generate a complete HbefaColdEmissionFactorKey: 'normal' // and set some parameters @@ -166,11 +166,11 @@ public final void testEqualsForIncompleteKeys_parkingTime() { noParkingTime.setVehicleAttributes(hbefaVehicleAttributes); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noParkingTime.toString(); - assertFalse(message, noParkingTime.equals(normal)); + assertFalse(noParkingTime.equals(normal), message); } @Test - public final void testEqualsForIncompleteKeys_distance() { + final void testEqualsForIncompleteKeys_distance() { // generate a complete HbefaColdEmissionFactorKey: 'normal' // and set some parameters @@ -185,11 +185,11 @@ public final void testEqualsForIncompleteKeys_distance() { noDistance.setVehicleAttributes(hbefaVehicleAttributes); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noDistance.toString(); - assertFalse(message, noDistance.equals(normal)); + assertFalse(noDistance.equals(normal), message); } @Test - public final void testEqualsForIncompleteKeys_emptyKey() { + final void testEqualsForIncompleteKeys_emptyKey() { // generate a complete HbefaColdEmissionFactorKey: 'normal' // and set some parameters @@ -200,11 +200,11 @@ public final void testEqualsForIncompleteKeys_emptyKey() { HbefaColdEmissionFactorKey emptyKey = new HbefaColdEmissionFactorKey(); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + emptyKey.toString(); - assertFalse(message, emptyKey.equals(normal)); + assertFalse(emptyKey.equals(normal), message); } @Test - public final void testEqualsForIncompleteKeys_VehicleAttributes(){ + final void testEqualsForIncompleteKeys_VehicleAttributes(){ //if no vehicle attributes are set manually they are set to 'average' by default // thus, the equals method should not throw nullpointer exceptions but return false or respectively true @@ -227,7 +227,7 @@ public final void testEqualsForIncompleteKeys_VehicleAttributes(){ noVehAtt.setVehicleCategory(hbefaVehCategory); String message = "these two HbefaColdEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noVehAtt.toString(); - assertFalse(message, noVehAtt.equals(normal)); + assertFalse(noVehAtt.equals(normal), message); //set the vehicle attributes of the normal hbefaColdWmissionFactorKey to 'average' @@ -239,7 +239,7 @@ public final void testEqualsForIncompleteKeys_VehicleAttributes(){ hbefaVehicleAttributesAverage.setHbefaTechnology("average"); normal.setVehicleAttributes(hbefaVehicleAttributesAverage); - Assert.assertTrue(message, noVehAtt.equals(normal)); + Assertions.assertTrue(noVehAtt.equals(normal), message); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaVehicleAttributes.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaVehicleAttributes.java index 1709424db79..bb8743783d9 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaVehicleAttributes.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaVehicleAttributes.java @@ -20,8 +20,8 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /* @@ -41,7 +41,7 @@ public class TestHbefaVehicleAttributes { private HbefaVehicleAttributes differentValues; @Test - public final void testEqualsForCompleteAttributes(){ + final void testEqualsForCompleteAttributes(){ //two equal objects - no default values normal = new HbefaVehicleAttributes(); @@ -54,13 +54,13 @@ public final void testEqualsForCompleteAttributes(){ String assertErrorMessage = "These hbefa vehicle attribute objects should have been the same: "; assertErrorMessage += normal.toString() + " and " + compare.toString(); - Assert.assertEquals(assertErrorMessage, normal, compare); - Assert.assertEquals(assertErrorMessage, compare, normal); + Assertions.assertEquals(normal, compare, assertErrorMessage); + Assertions.assertEquals(compare, normal, assertErrorMessage); } @Test - public final void testEqualsForCompleteAttributes_emConcept(){ + final void testEqualsForCompleteAttributes_emConcept(){ //two unequal but complete objects normal = new HbefaVehicleAttributes(); @@ -74,12 +74,12 @@ public final void testEqualsForCompleteAttributes_emConcept(){ differentValues.setHbefaTechnology(technology); assertErrorMessage = "These hbefa vehicle attribute objects should not have been the same: "; assertErrorMessage += normal.toString() + " and " + differentValues.toString(); - Assert.assertNotEquals(assertErrorMessage, normal, differentValues); - Assert.assertNotEquals(assertErrorMessage, differentValues, normal); + Assertions.assertNotEquals(normal, differentValues, assertErrorMessage); + Assertions.assertNotEquals(differentValues, normal, assertErrorMessage); } @Test - public final void testEqualsForCompleteAttributes_sizeClass(){ + final void testEqualsForCompleteAttributes_sizeClass(){ //two unequal but complete objects normal = new HbefaVehicleAttributes(); @@ -92,13 +92,13 @@ public final void testEqualsForCompleteAttributes_sizeClass(){ differentValues.setHbefaTechnology(technology); assertErrorMessage = "These hbefa vehicle attribute objects should not have been the same: "; assertErrorMessage += normal.toString() + " and " + differentValues.toString(); - Assert.assertNotEquals(assertErrorMessage, normal, differentValues); - Assert.assertNotEquals(assertErrorMessage, differentValues, normal); + Assertions.assertNotEquals(normal, differentValues, assertErrorMessage); + Assertions.assertNotEquals(differentValues, normal, assertErrorMessage); } @Test - public final void testEqualsForCompleteAttributes_technologies(){ + final void testEqualsForCompleteAttributes_technologies(){ //two unequal but complete objects normal = new HbefaVehicleAttributes(); @@ -111,8 +111,8 @@ public final void testEqualsForCompleteAttributes_technologies(){ differentValues.setHbefaTechnology("other technology"); assertErrorMessage = "These hbefa vehicle attribute objects should not have been the same: "; assertErrorMessage += normal.toString() + " and " + differentValues.toString(); - Assert.assertNotEquals(assertErrorMessage, normal, differentValues); - Assert.assertNotEquals(assertErrorMessage, differentValues, normal); + Assertions.assertNotEquals(normal, differentValues, assertErrorMessage); + Assertions.assertNotEquals(differentValues, normal, assertErrorMessage); } @@ -121,7 +121,7 @@ public final void testEqualsForCompleteAttributes_technologies(){ // thus, the equals method should not throw nullpointer exceptions but return false or respectively true @Test - public final void testEqualsForIncompleteAttributes_emConcept(){ + final void testEqualsForIncompleteAttributes_emConcept(){ //generate a complete key and set its parameters normal = new HbefaVehicleAttributes(); setToNormal(normal); @@ -131,18 +131,18 @@ public final void testEqualsForIncompleteAttributes_emConcept(){ noEmConcept.setHbefaSizeClass(sizeClass); noEmConcept.setHbefaTechnology(technology); message = "no em concept was set, therefore " + normal.getHbefaEmConcept() + " should not equal " + noEmConcept.getHbefaEmConcept(); - Assert.assertNotEquals(message, noEmConcept, normal); - Assert.assertNotEquals(message, normal, noEmConcept); + Assertions.assertNotEquals(noEmConcept, normal, message); + Assertions.assertNotEquals(normal, noEmConcept, message); normal.setHbefaEmConcept("average"); message = "no em concept was set, therefore " + noEmConcept.getHbefaEmConcept() + "should be set to 'average'"; - Assert.assertEquals(message, noEmConcept, normal); - Assert.assertEquals(message, normal, noEmConcept); + Assertions.assertEquals(noEmConcept, normal, message); + Assertions.assertEquals(normal, noEmConcept, message); } @Test - public final void testEqualsForIncompleteAttributes_technology() { + final void testEqualsForIncompleteAttributes_technology() { // generate a complete key and set its parameters normal = new HbefaVehicleAttributes(); @@ -153,20 +153,20 @@ public final void testEqualsForIncompleteAttributes_technology() { noTechnology.setHbefaEmConcept(concept); noTechnology.setHbefaSizeClass(sizeClass); message = "no technology was set, therefore " + normal.getHbefaTechnology() + " should not equal " + noTechnology.getHbefaTechnology(); - Assert.assertNotEquals(message, noTechnology, normal); - Assert.assertNotEquals(message, normal, noTechnology); + Assertions.assertNotEquals(noTechnology, normal, message); + Assertions.assertNotEquals(normal, noTechnology, message); //set the hbefa technology of the normal vehicle attributes to 'average' //then noTechnology is equal to normal normal.setHbefaTechnology("average"); message = "no em concept was set, therefore " + noTechnology.getHbefaEmConcept() + "should be set to 'average'"; - Assert.assertEquals(message, noTechnology, normal); - Assert.assertEquals(message, normal, noTechnology); + Assertions.assertEquals(noTechnology, normal, message); + Assertions.assertEquals(normal, noTechnology, message); } @Test - public final void testEqualsForIncompleteAttributes_sizeClass(){ + final void testEqualsForIncompleteAttributes_sizeClass(){ //generate a complete key and set its parameters normal = new HbefaVehicleAttributes(); @@ -178,13 +178,13 @@ public final void testEqualsForIncompleteAttributes_sizeClass(){ noSize.setHbefaEmConcept(concept); noSize.setHbefaTechnology(technology); message = "no size class was set, therefore " + normal.getHbefaSizeClass() + " should not equal " + noSize.getHbefaSizeClass(); - Assert.assertNotEquals(message, noSize, normal); - Assert.assertNotEquals(message, normal, noSize); + Assertions.assertNotEquals(noSize, normal, message); + Assertions.assertNotEquals(normal, noSize, message); normal.setHbefaSizeClass("average"); message = "no size class was set, therefore " + noSize.getHbefaEmConcept() + "should be set to 'average'"; - Assert.assertEquals(message, noSize, normal); - Assert.assertEquals(message, normal, noSize); + Assertions.assertEquals(noSize, normal, message); + Assertions.assertEquals(normal, noSize, message); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaWarmEmissionFactorKey.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaWarmEmissionFactorKey.java index 74eb698f206..2ff96fb02bd 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaWarmEmissionFactorKey.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestHbefaWarmEmissionFactorKey.java @@ -22,10 +22,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.matsim.contrib.emissions.Pollutant.CO; import static org.matsim.contrib.emissions.Pollutant.FC; @@ -64,7 +64,7 @@ private void setUp(){ } @Test - public final void testEqualsForCompleteKeys(){ + final void testEqualsForCompleteKeys(){ // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters @@ -80,8 +80,8 @@ public final void testEqualsForCompleteKeys(){ compare.setVehicleCategory(hbefaVehicleCategory); String message = "these two objects should be the same but are not: " + normal.toString() + " and " + compare.toString(); - Assert.assertTrue(message, normal.equals(compare)); - Assert.assertTrue(message, compare.equals(normal)); + Assertions.assertTrue(normal.equals(compare), message); + Assertions.assertTrue(compare.equals(normal), message); //two unequal but complete objects HbefaWarmEmissionFactorKey different = new HbefaWarmEmissionFactorKey(); @@ -97,10 +97,10 @@ public final void testEqualsForCompleteKeys(){ message = "these two objects should not be the same: " + normal.toString() + " and " + different.toString(); - assertFalse(message, different.equals(normal)); - assertFalse(message, normal.equals(different)); + assertFalse(different.equals(normal), message); + assertFalse(normal.equals(different), message); } - + // the following tests each compare a incomplete key to a complete key // wanted result: // completeData.equals(partialData) -> return false @@ -108,7 +108,7 @@ public final void testEqualsForCompleteKeys(){ // exception: if the vehicleAttributes are set to 'average' by default @Test - public final void testEqualsForIncompleteKeys_vehicleCategory() { + final void testEqualsForIncompleteKeys_vehicleCategory() { // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters setUp(); @@ -128,9 +128,9 @@ public final void testEqualsForIncompleteKeys_vehicleCategory() { assertFalse(result); } - + @Test - public final void testEqualsForIncompleteKeys_pollutant() { + final void testEqualsForIncompleteKeys_pollutant() { // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters setUp(); @@ -145,9 +145,9 @@ public final void testEqualsForIncompleteKeys_pollutant() { var result = noPollutant.equals(normal); } - + @Test - public final void testEqualsForIncompleteKeys_roadCategory() { + final void testEqualsForIncompleteKeys_roadCategory() { // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters setUp(); @@ -169,12 +169,12 @@ public final void testEqualsForIncompleteKeys_roadCategory() { String message = "these two HbefaWarmEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noRoadCat.toString(); String message2 = "this key should not be comparable since no road category is set"; - Assert.assertTrue(message2, equalErr); - assertFalse(message, normal.equals(noRoadCat)); + Assertions.assertTrue(equalErr, message2); + assertFalse(normal.equals(noRoadCat), message); } - + @Test - public final void testEqualsForIncompleteKeys_trafficSituation() { + final void testEqualsForIncompleteKeys_trafficSituation() { // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters setUp(); @@ -191,9 +191,9 @@ public final void testEqualsForIncompleteKeys_trafficSituation() { assertFalse(result); } - + @Test - public final void testEqualsForIncompleteKeys_emptyKey() { + final void testEqualsForIncompleteKeys_emptyKey() { // generate a complete HbefaWarmEmissionFactorKey: 'normal' // and set some parameters setUp(); @@ -206,9 +206,9 @@ public final void testEqualsForIncompleteKeys_emptyKey() { assertFalse(result); } - + @Test - public final void testEqualsForIncompleteKeys_vehicleAttributes(){ + final void testEqualsForIncompleteKeys_vehicleAttributes(){ // if no vehicle attributes are set manually they are set to 'average' by default // thus, the equals method should not throw nullpointer exceptions but return false or respectively true @@ -233,11 +233,11 @@ public final void testEqualsForIncompleteKeys_vehicleAttributes(){ } String message = "these two HbefaWarmEmissionFactorKeys should not be the same: " + normal.toString() + " and " + noVehAtt.toString(); - assertFalse(message, noVehAtt.equals(normal)); + assertFalse(noVehAtt.equals(normal), message); assertFalse(equalErr); // veh attributes are allowed to be not initiated // therefore this should not throw a nullpointer but return false - assertFalse(message, normal.equals(noVehAtt)); + assertFalse(normal.equals(noVehAtt), message); //set the vehicle attributes of the normal hbefacoldemissionfactorkey to 'average' //then noVehAtt is equal to normal @@ -248,8 +248,8 @@ public final void testEqualsForIncompleteKeys_vehicleAttributes(){ normal.setVehicleAttributes(hbefaVehicleAttributesAverage); message = "these two HbefaWarmEmissionFactorKeys should be the same: " + normal.toString() + " and " + noVehAtt.toString(); - Assert.assertTrue(message, normal.equals(noVehAtt)); - Assert.assertTrue(message, noVehAtt.equals(normal)); + Assertions.assertTrue(normal.equals(noVehAtt), message); + Assertions.assertTrue(noVehAtt.equals(normal), message); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java index 73ee5c208b5..f1824def7cd 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java @@ -1,8 +1,8 @@ package org.matsim.contrib.emissions; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -18,17 +18,16 @@ import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.ControllerConfigGroup; import org.matsim.core.config.groups.NetworkConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.StrategyConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.events.EventsManagerImpl; import org.matsim.core.events.handler.BasicEventHandler; -import org.matsim.core.events.handler.EventHandler; import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PopulationUtils; import org.matsim.core.population.routes.RouteUtils; @@ -36,7 +35,6 @@ import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; -import org.matsim.facilities.filters.Filter; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.EngineInformation; import org.matsim.vehicles.Vehicle; @@ -45,35 +43,35 @@ import org.matsim.vis.snapshotwriters.PositionEvent; import jakarta.inject.Singleton; + +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import static org.junit.Assert.assertEquals; - public class TestPositionEmissionModule { private static final String configFile = IOUtils.extendUrl( ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv2" ), "config_detailed.xml" ).toString(); // (I changed the above from veh v1 to veh v2 since veh v1 is deprecated, especially for emissions. kai, apr'21) - @Rule - public MatsimTestUtils testUtils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils testUtils = new MatsimTestUtils(); - @Test - @Ignore - public void simpleTest() { + @Test + @Disabled + void simpleTest() { var emissionConfig = new EmissionsConfigGroup(); emissionConfig.setHbefaVehicleDescriptionSource(EmissionsConfigGroup.HbefaVehicleDescriptionSource.fromVehicleTypeDescription); emissionConfig.setDetailedVsAverageLookupBehavior( EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); //This is the previous behaviour var config = ConfigUtils.loadConfig(configFile, emissionConfig); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); config.qsim().setSnapshotPeriod(1); config.qsim().setSnapshotStyle(QSimConfigGroup.SnapshotStyle.queue); - config.controler().setWriteSnapshotsInterval(1); - config.controler().setSnapshotFormat(Set.of(ControlerConfigGroup.SnapshotFormat.positionevents)); + config.controller().setWriteSnapshotsInterval(1); + config.controller().setSnapshotFormat(Set.of(ControllerConfigGroup.SnapshotFormat.positionevents)); var scenario = ScenarioUtils.loadScenario(config); @@ -83,41 +81,41 @@ public void simpleTest() { controler.run(); } - @Test - public void compareToOtherModule_singleVehicleSingleLink() { + @Test + void compareToOtherModule_singleVehicleSingleLink() { var emissionConfig = new EmissionsConfigGroup(); emissionConfig.setHbefaVehicleDescriptionSource(EmissionsConfigGroup.HbefaVehicleDescriptionSource.fromVehicleTypeDescription); emissionConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); var config = ConfigUtils.loadConfig(configFile, emissionConfig); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); - config.controler().setOutputDirectory(testUtils.getOutputDirectory()); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(testUtils.getOutputDirectory()); emissionConfig.setAverageColdEmissionFactorsFile("../sample_41_EFA_ColdStart_vehcat_2020average.csv"); emissionConfig.setAverageWarmEmissionFactorsFile( "../sample_41_EFA_HOT_vehcat_2020average.csv" ); emissionConfig.setHbefaTableConsistencyCheckingLevel( EmissionsConfigGroup.HbefaTableConsistencyCheckingLevel.consistent ); - final PlanCalcScoreConfigGroup.ActivityParams homeParams = new PlanCalcScoreConfigGroup.ActivityParams("home") + final ScoringConfigGroup.ActivityParams homeParams = new ScoringConfigGroup.ActivityParams("home") .setTypicalDuration(20); - config.planCalcScore().addActivityParams(homeParams); - final PlanCalcScoreConfigGroup.ActivityParams workParams = new PlanCalcScoreConfigGroup.ActivityParams("work") + config.scoring().addActivityParams(homeParams); + final ScoringConfigGroup.ActivityParams workParams = new ScoringConfigGroup.ActivityParams("work") .setTypicalDuration(20); - config.planCalcScore().addActivityParams(workParams); + config.scoring().addActivityParams(workParams); - var strategy = new StrategyConfigGroup.StrategySettings(); + var strategy = new ReplanningConfigGroup.StrategySettings(); strategy.setStrategyName("ChangeExpBeta"); strategy.setWeight(1.0); - config.strategy().addParameterSet(strategy); + config.replanning().addParameterSet(strategy); // activate snapshots config.qsim().setSnapshotPeriod(1); config.qsim().setSnapshotStyle(QSimConfigGroup.SnapshotStyle.queue); - config.controler().setWriteSnapshotsInterval(1); - config.controler().setSnapshotFormat(Set.of(ControlerConfigGroup.SnapshotFormat.positionevents)); - config.controler().setFirstIteration(0); - config.controler().setLastIteration(0); + config.controller().setWriteSnapshotsInterval(1); + config.controller().setSnapshotFormat(Set.of(ControllerConfigGroup.SnapshotFormat.positionevents)); + config.controller().setFirstIteration(0); + config.controller().setLastIteration(0); config.qsim().setVehiclesSource(QSimConfigGroup.VehiclesSource.fromVehiclesData); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModule.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModule.java index c65dd54fd27..cd88c087a65 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModule.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModule.java @@ -20,10 +20,12 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.geotools.metadata.iso.quality.TemporalAccuracyImpl; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Node; @@ -38,6 +40,7 @@ import org.matsim.vehicles.VehiclesFactory; import java.util.*; +import java.util.stream.Stream; import static org.matsim.contrib.emissions.Pollutant.*; @@ -48,8 +51,8 @@ /* * test for playground.vsp.emissions.WarmEmissionAnalysisModule * - * WarmEmissionAnalysisModule (weam) - * public methods and corresponding tests: + * WarmEmissionAnalysisModule (weam) + * public methods and corresponding tests: * weamParameter - testWarmEmissionAnalysisParameter * throw warm EmissionEvent - testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent*, testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions * check vehicle info and calculate warm emissions -testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent*, testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions @@ -61,7 +64,7 @@ * get top go km couter - testCounters*() * get warm emission event counter - testCounters*() * - * private methods and corresponding tests: + * private methods and corresponding tests: * rescale warm emissions - rescaleWarmEmissionsTest() * calculate warm emissions - implicitly tested * convert string 2 tuple - implicitly tested @@ -70,7 +73,6 @@ * see test methods for details on the particular test cases **/ -@RunWith(Parameterized.class) public class TestWarmEmissionAnalysisModule { // This used to be one large test class, which had separate table entries for each test, but put them all into the same table. The result was // difficult if not impossible to debug, and the resulting detailed table was inconsistent in the sense that it did not contain all combinations of @@ -78,12 +80,8 @@ public class TestWarmEmissionAnalysisModule { // single class before was so large that I could not fully comprehend it, there may now be errors in the ripped-apart classes. Hopefully, over time, // this will help to sort things out. kai, feb'20 - - - private static final Set pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); static final String HBEFA_ROAD_CATEGORY = "URB"; - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; private boolean excep = false; private static final String PASSENGER_CAR = "PASSENGER_CAR"; @@ -113,25 +111,18 @@ public class TestWarmEmissionAnalysisModule { private final String sgffConcept = "sg ff concept"; private final String sgffSizeClass = "sg ff size class"; - - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - public TestWarmEmissionAnalysisModule( EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; + public static Stream arguments() { + return Stream.of( + EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction, + EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed + ); } - - - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent6(){ + @ParameterizedTest + @MethodSource("arguments") + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent6(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - setUp(); + setUp(emissionsComputationMethod); Id sgffVehicleId = Id.create("vehicle sg equals ff", Vehicle.class); double sgffLinklength = 4000.; @@ -150,25 +141,26 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE catch(RuntimeException re){ exceptionThrown = true; } - Assert.assertTrue("An average speed higher than the free flow speed should throw a runtime exception",exceptionThrown); + Assertions.assertTrue(exceptionThrown,"An average speed higher than the free flow speed should throw a runtime exception"); { //avg=ff=sg -> use ff factors Map warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(sgffVehicle, sgflink, sgffLinklength / AVG_PASSENGER_CAR_SPEED_FF_KMH * 3.6); - Assert.assertEquals(DETAILED_SGFF_FACTOR_FF * sgffLinklength / 1000., warmEmissions.get(NO2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(DETAILED_SGFF_FACTOR_FF * sgffLinklength / 1000., warmEmissions.get(NO2), MatsimTestUtils.EPSILON); } { //avg use sg factors Map warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(sgffVehicle, sgflink, 2*sgffLinklength/ AVG_PASSENGER_CAR_SPEED_FF_KMH *3.6 ); - Assert.assertEquals( DETAILED_SGFF_FACTOR_SG *sgffLinklength/1000., warmEmissions.get(NO2 ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( DETAILED_SGFF_FACTOR_SG *sgffLinklength/1000., warmEmissions.get(NO2 ), MatsimTestUtils.EPSILON ); } } - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions1(){ + @ParameterizedTest + @MethodSource("arguments") + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions1(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - setUp(); + setUp(emissionsComputationMethod); // case 5 - no entry in any table - must be different to other test case's strings //With the bug fix to handle missing values - this test should no longer throw an error - jm oct'18 @@ -192,15 +184,16 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE }catch(Exception e){ excep = true; } - Assert.assertFalse(excep); + Assertions.assertFalse(excep); excep=false; } - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions2(){ + @ParameterizedTest + @MethodSource("arguments") + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions2(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - setUp(); + setUp(emissionsComputationMethod); // no vehicle information given Id noeVehicleId = Id.create("veh 6", Vehicle.class); @@ -219,15 +212,16 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE }catch(Exception e){ excep = true; } - Assert.assertTrue(excep); excep=false; + Assertions.assertTrue(excep); excep=false; } - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions3(){ + @ParameterizedTest + @MethodSource("arguments") + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions3(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - setUp(); + setUp(emissionsComputationMethod); - // empty vehicle information + // empty vehicle information Id noeVehicleId = Id.create("veh 7", Vehicle.class); Id noeVehicleTypeId = Id.create(";;;", VehicleType.class); VehiclesFactory vehFac = VehicleUtils.getFactory(); @@ -243,13 +237,14 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE }catch(Exception e){ excep = true; } - Assert.assertTrue(excep); excep=false; + Assertions.assertTrue(excep); excep=false; } - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions4(){ + @ParameterizedTest + @MethodSource("arguments") + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions4(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - setUp(); + setUp(emissionsComputationMethod); // vehicle information string is 'null' Id noeVehicleId = Id.create("veh 8", Vehicle.class); VehiclesFactory vehFac = VehicleUtils.getFactory(); @@ -265,13 +260,14 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE }catch(Exception e){ excep = true; } - Assert.assertTrue(excep); excep=false; + Assertions.assertTrue(excep); excep=false; } - @Test - public void testCounters7(){ - setUp(); + @ParameterizedTest + @MethodSource("arguments") + void testCounters7(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ + setUp(emissionsComputationMethod); emissionsModule.reset(); // case 10 - data in detailed table, stop go speed > free flow speed @@ -286,30 +282,30 @@ public void testCounters7(){ // ff < avg < ff+1 - handled like free flow double travelTime = tableLinkLength/(AVG_PASSENGER_CAR_SPEED_FF_KMH +0.5)*3.6; emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(tableVehicle, tableLink, travelTime ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(tableLinkLength/1000., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(tableLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(tableLinkLength/1000., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(tableLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // ff < sg < avg - handled like free flow as well - no additional test needed - // avg < ff < sg - handled like stop go + // avg < ff < sg - handled like stop go emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(tableVehicle, tableLink, 2* tableLinkLength/(AVG_PASSENGER_CAR_SPEED_FF_KMH)*3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(tableLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(tableLinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(tableLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(tableLinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); } - private void setUp() { + private void setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); @@ -323,7 +319,7 @@ private void setUp() { EventsManager emissionEventManager = new HandlerToTestEmissionAnalysisModules(); EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); + ecg.setEmissionsComputationMethod( emissionsComputationMethod ); ecg.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); emissionsModule = new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); @@ -452,7 +448,7 @@ static void addDetailedRecordsToTestSpeedsTable( } - - + + diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModuleCase1.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModuleCase1.java index ae5a6ed5d28..2bc080b1bc3 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModuleCase1.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestWarmEmissionAnalysisModuleCase1.java @@ -20,10 +20,12 @@ package org.matsim.contrib.emissions; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; @@ -36,6 +38,7 @@ import org.matsim.vehicles.VehiclesFactory; import java.util.*; +import java.util.stream.Stream; import static org.matsim.contrib.emissions.Pollutant.CO2_TOTAL; import static org.matsim.contrib.emissions.TestWarmEmissionAnalysisModule.HBEFA_ROAD_CATEGORY; @@ -55,8 +58,8 @@ /* * test for playground.vsp.emissions.WarmEmissionAnalysisModule * - * WarmEmissionAnalysisModule (weam) - * public methods and corresponding tests: + * WarmEmissionAnalysisModule (weam) + * public methods and corresponding tests: * weamParameter - testWarmEmissionAnalysisParameter * throw warm EmissionEvent - testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent*, testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions * check vehicle info and calculate warm emissions -testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent*, testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent_Exceptions @@ -68,7 +71,7 @@ * get top go km couter - testCounters*() * get warm emission event counter - testCounters*() * - * private methods and corresponding tests: + * private methods and corresponding tests: * rescale warm emissions - rescaleWarmEmissionsTest() * calculate warm emissions - implicitly tested * convert string 2 tuple - implicitly tested @@ -77,7 +80,6 @@ * see test methods for details on the particular test cases **/ -@RunWith(Parameterized.class) public class TestWarmEmissionAnalysisModuleCase1{ // This used to be one large test class, which had separate table entries for each test, but put them all into the same table. The result was // difficult if not impossible to debug, and the resulting detailed table was inconsistent in the sense that it did not contain all combinations of @@ -89,7 +91,6 @@ public class TestWarmEmissionAnalysisModuleCase1{ private static final Set pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); private static final int leaveTime = 0; - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; private static final String PASSENGER_CAR = "PASSENGER_CAR"; @@ -104,20 +105,7 @@ public class TestWarmEmissionAnalysisModuleCase1{ private static final Double PETROL_SPEED_FF = 20.; //km/h private static final Double PETROL_SPEED_SG = 10.; //km/h - - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - public TestWarmEmissionAnalysisModuleCase1( EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - - private WarmEmissionAnalysisModule setUp() { + private WarmEmissionAnalysisModule setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); TestWarmEmissionAnalysisModule.fillAverageTable( avgHbefaWarmTable ); @@ -128,19 +116,20 @@ private WarmEmissionAnalysisModule setUp() { EventsManager emissionEventManager = TestWarmEmissionAnalysisModuleCase1.emissionEventManager; EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); + ecg.setEmissionsComputationMethod( emissionsComputationMethod ); ecg.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); return new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); } - + //this test method creates a mock link and mock vehicle with a complete vehicleTypId --> detailed values are used //the CO2_TOTAL warm Emissions are compared to a given value --> computed by using detailed Petrol and traffic state freeflow //the "Sum" of all emissions is tested - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent1(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent1(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - WarmEmissionAnalysisModule warmEmissionAnalysisModule = setUp(); + WarmEmissionAnalysisModule warmEmissionAnalysisModule = setUp(emissionsComputationMethod); // case 1 - data in both tables -> use detailed Id vehicleId = Id.create("veh 1", Vehicle.class); double linkLength = 200.; @@ -150,26 +139,27 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE Vehicle vehicle = vehFac.createVehicle(vehicleId, vehFac.createVehicleType(vehicleTypeId)); Map warmEmissions = warmEmissionAnalysisModule.checkVehicleInfoAndCalculateWarmEmissions( vehicle, mockLink, linkLength / PETROL_SPEED_FF * 3.6 ); - Assert.assertEquals(DETAILED_PETROL_FACTOR_FF *linkLength/1000., warmEmissions.get( CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(DETAILED_PETROL_FACTOR_FF *linkLength/1000., warmEmissions.get( CO2_TOTAL ), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); warmEmissionAnalysisModule.throwWarmEmissionEvent(leaveTime, mockLink.getId(), vehicleId, warmEmissions ); - Assert.assertEquals( pollutants.size() * DETAILED_PETROL_FACTOR_FF *linkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * DETAILED_PETROL_FACTOR_FF *linkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); warmEmissions.clear(); } - - + + /* * this test method creates a mock link and mock vehicle (petrol technology) with a complete vehicleTypId --> detailed values are used * the counters for all possible combinations of avg, stop go and free flow speed are tested * for the cases: > s&g speed, s&g speed, ff speed @@ -249,7 +239,7 @@ public void testCounters1(){ }catch(RuntimeException re){ exceptionThrown = true; } - Assert.assertTrue("An average speed higher than the free flow speed should throw a runtime exception", exceptionThrown); + Assertions.assertTrue(exceptionThrown, "An average speed higher than the free flow speed should throw a runtime exception"); warmEmissionAnalysisModule.reset(); } @@ -261,10 +251,11 @@ public void testCounters1(){ * for the case average speed equals wrong free flow speed the counters are tested */ - @Test - public void testCounters5(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters5(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 1 - data in both tables -> use detailed // free flow velocity inconsistent -> different value in table @@ -282,37 +273,37 @@ public void testCounters5(){ switch( emissionsComputationMethod ) { case StopAndGoFraction: - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); break; case AverageSpeed: - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); break; default: throw new IllegalStateException( "Unexpected value: " + emissionsComputationMethod ); } - Assert.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // average speed equals wrong free flow speed emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(inconffVehicle, inconLink, inconff / inconffavgSpeed * 3.6); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); //@KMT is there the need for adding a test here? emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(inconffVehicle, inconLink, 2 * inconff / (PETROL_SPEED_FF + PETROL_SPEED_SG) * 3.6); } + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters1fractional(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - @Test - public void testCounters1fractional(){ - - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); emissionsModule.getEcg().setEmissionsComputationMethod(StopAndGoFraction ); // yyyyyy !!!!!! @@ -332,50 +323,50 @@ public void testCounters1fractional(){ // s&g speed, ff speed @@ -385,7 +376,7 @@ public void testCounters1fractional(){ }catch(RuntimeException re){ exceptionThrown = true; } - Assert.assertTrue("An average speed higher than the free flow speed should throw a runtime exception", exceptionThrown); + Assertions.assertTrue(exceptionThrown, "An average speed higher than the free flow speed should throw a runtime exception"); emissionsModule.reset(); emissionsModule.getEcg().setEmissionsComputationMethod(AverageSpeed ); @@ -395,10 +386,11 @@ public void testCounters1fractional(){ } - @Test - public void testCounters6(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters6(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); emissionsModule.getEcg().setEmissionsComputationMethod(StopAndGoFraction ); // case 1 - data in both tables -> use detailed @@ -414,28 +406,29 @@ public void testCounters6(){ // average speed equals free flow speed from table emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(inconffVehicle, inconLink, inconff / PETROL_SPEED_FF * 3.6); - Assert.assertEquals(1, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(1, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // average speed equals wrong free flow speed emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(inconffVehicle, inconLink, inconff / inconffavgSpeed * 3.6); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(inconff/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(inconffVehicle, inconLink, 2 * inconff / (PETROL_SPEED_FF + PETROL_SPEED_SG) * 3.6); } - @Test - public void testCounters8(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters8(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // test summing up of counters @@ -449,13 +442,13 @@ public void testCounters8(){ Link pcLink = createMockLink("link table", linkLength, PETROL_SPEED_FF / 3.6 ); emissionsModule.reset(); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), 1e-7 ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(0., emissionsModule.getKmCounter(), 1e-7 ); - Assert.assertEquals(0., emissionsModule.getStopGoKmCounter(), 1e-7 ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(0, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), 1e-7 ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(0., emissionsModule.getKmCounter(), 1e-7 ); + Assertions.assertEquals(0., emissionsModule.getStopGoKmCounter(), 1e-7 ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(0, emissionsModule.getWarmEmissionEventCounter() ); // < s&g speed emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime * 3.6); @@ -517,7 +510,7 @@ private static void fillDetailedTable( Map pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); static final String HBEFA_ROAD_CATEGORY = "URB"; private static final int leaveTime = 0; - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; private static final String PASSENGER_CAR = "PASSENGER_CAR"; @@ -106,30 +106,17 @@ public class TestWarmEmissionAnalysisModuleCase2{ private static final Double PCSG_VELOCITY_KMH = 10.; //km/h private static final double DETAILED_PC_FACTOR_FF = .0001; - - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - public TestWarmEmissionAnalysisModuleCase2( EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - - /* * this test method creates a mock link and mock vehicle with a complete vehicleTypId --> lookUpBehaviour: tryDetailedThenTechnologyAverageThenAverageTable * for two speed cases: avg speed = free flow speed & avg speed = stop go speed the NMHC warm emissions and emissions sum are computed using the two emissionsComputationMethods StopAndGoFraction & AverageSpeed */ - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent2(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent2(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 2 - free flow entry in both tables, stop go entry in average table -> use average // see (*) below. kai, jan'20 @@ -158,11 +145,11 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE // After discussion with Kai N. we decided to let it as it is for the time being. I will add a log.info in the consistency checker. KMT Jul'20 //results should be equal here, because in both cases only the freeflow value is relevant (100% freeflow, 0% stop&go). - Assert.assertEquals( 0.1, warmEmissions.get( NMHC ), MatsimTestUtils.EPSILON ); //(*#) + Assertions.assertEquals( 0.1, warmEmissions.get( NMHC ), MatsimTestUtils.EPSILON ); //(*#) // throw and test corresponding event: emissionsModule.throwWarmEmissionEvent( leaveTime, pclink.getId(), pcVehicleId, warmEmissions ); - Assert.assertEquals( 2.3, emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); //seems to be (0.1 (g/km -- see expected values a few lines above(*#) * number of entries in enum Pollutant) + Assertions.assertEquals( 2.3, emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); //seems to be (0.1 (g/km -- see expected values a few lines above(*#) * number of entries in enum Pollutant) emissionEventManager.reset(); warmEmissions.clear(); @@ -171,10 +158,10 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE // sub case avg speed = stop go speed { warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions( pcVehicle, pclink, pclinkLength / PCSG_VELOCITY_KMH * 3.6 ); - Assert.assertEquals( AVG_PC_FACTOR_SG * pclinkLength / 1000., warmEmissions.get( NMHC ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( AVG_PC_FACTOR_SG * pclinkLength / 1000., warmEmissions.get( NMHC ), MatsimTestUtils.EPSILON ); emissionsModule.throwWarmEmissionEvent( leaveTime, pclink.getId(), pcVehicleId, warmEmissions ); - Assert.assertEquals(pollutants.size() * AVG_PC_FACTOR_SG * pclinkLength / 1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(pollutants.size() * AVG_PC_FACTOR_SG * pclinkLength / 1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); emissionsModule.reset(); warmEmissions.clear(); } @@ -185,10 +172,11 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE * for three cases: "current speed equals free flow speed" & "current speed equals stop go speed" & "current speed equals stop go speed" the counters are tested * average values are used */ - @Test - public void testCounters3(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters3(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 2 - free flow entry in both tables, stop go entry in average table -> use average Id pcVehicleId = Id.create("vehicle 2", Vehicle.class); @@ -200,28 +188,28 @@ public void testCounters3(){ // sub case: current speed equals free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(pcVehicle,pclink, pclinkLength/ PC_FREE_VELOCITY_KMH *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(pclinkLength/1000, emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(pclinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(pclinkLength/1000, emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(pclinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // sub case: current speed equals stop go speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(pcVehicle, pclink, pclinkLength/ PCSG_VELOCITY_KMH *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(pclinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(pclinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(pclinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(pclinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); } - private WarmEmissionAnalysisModule setUp() { + private WarmEmissionAnalysisModule setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); @@ -234,7 +222,7 @@ private WarmEmissionAnalysisModule setUp() { EventsManager emissionEventManager = this.emissionEventManager; EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); + ecg.setEmissionsComputationMethod( emissionsComputationMethod ); ecg.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); return new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); @@ -331,7 +319,7 @@ private void fillDetailedTable( Map pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); static final String HBEFA_ROAD_CATEGORY = "URB"; private static final int leaveTime = 0; - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; private static final String PASSENGER_CAR = "PASSENGER_CAR"; private Map warmEmissions; @@ -99,27 +99,16 @@ public class TestWarmEmissionAnalysisModuleCase3{ private final String dieselSizeClass = "diesel"; private final String dieselConcept = ">=2L"; - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - public TestWarmEmissionAnalysisModuleCase3( EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - /* * this test method creates a diesel vehicle and mock link * for two cases: "avg speed = free flow speed" & "avg speed = stop go speed" the average values are used to calculate the PM warm emissions */ - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent3(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent3(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ //-- set up tables, event handler, parameters, module - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 3 - stop go entry in both tables, free flow entry in average table -> use average Id dieselVehicleId = Id.create("veh 3", Vehicle.class); @@ -133,19 +122,19 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE // sub case avg speed = free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(dieselVehicle, diesellink, dieselLinkLength/ TestWarmEmissionAnalysisModule.AVG_PASSENGER_CAR_SPEED_FF_KMH *3.6 ); - Assert.assertEquals( AVG_PC_FACTOR_FF *dieselLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( AVG_PC_FACTOR_FF *dieselLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); emissionsModule.throwWarmEmissionEvent(leaveTime, diesellink.getId(), dieselVehicleId, warmEmissions ); - Assert.assertEquals( pollutants.size() * AVG_PC_FACTOR_FF *dieselLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * AVG_PC_FACTOR_FF *dieselLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); warmEmissions.clear(); // sub case avg speed = stop go speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(dieselVehicle, diesellink, dieselLinkLength/ TestWarmEmissionAnalysisModule.AVG_PASSENGER_CAR_SPEED_SG_KMH *3.6 ); - Assert.assertEquals( AVG_PC_FACTOR_SG *dieselLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( AVG_PC_FACTOR_SG *dieselLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); emissionsModule.throwWarmEmissionEvent(leaveTime, diesellink.getId(), dieselVehicleId, warmEmissions ); - Assert.assertEquals( pollutants.size() * AVG_PC_FACTOR_SG *dieselLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * AVG_PC_FACTOR_SG *dieselLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); warmEmissions.clear(); } @@ -154,10 +143,11 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE * this test method creates a diesel vehicle and mock link * for two cases: "current speed equals free flow speed" & "current speed equals stop go speed" the counters are tested */ - @Test - public void testCounters4(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters4(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 3 - stop go entry in both tables, free flow entry in average table -> use average Id dieselVehicleId = Id.create("vehicle 3", Vehicle.class); @@ -170,28 +160,28 @@ public void testCounters4(){ // sub case: current speed equals free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(dieselVehicle, diesellink, dieselLinkLength/ TestWarmEmissionAnalysisModule.AVG_PASSENGER_CAR_SPEED_FF_KMH *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(dieselLinkLength/1000., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(dieselLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(dieselLinkLength/1000., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(dieselLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // sub case: current speed equals stop go speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(dieselVehicle, diesellink, dieselLinkLength/ TestWarmEmissionAnalysisModule.AVG_PASSENGER_CAR_SPEED_SG_KMH *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(dieselLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(dieselLinkLength/1000., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(dieselLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(dieselLinkLength/1000., emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); } - private WarmEmissionAnalysisModule setUp() { + private WarmEmissionAnalysisModule setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); @@ -204,7 +194,7 @@ private WarmEmissionAnalysisModule setUp() { EventsManager emissionEventManager = this.emissionEventManager; EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); + ecg.setEmissionsComputationMethod( emissionsComputationMethod ); ecg.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); return new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); @@ -286,7 +276,7 @@ private void fillDetailedTable( Map pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); private static final String HBEFA_ROAD_CATEGORY = "URB"; private static final int leaveTime = 0; - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; private static final String PASSENGER_CAR = "PASSENGER_CAR"; private Map warmEmissions; @@ -105,29 +103,17 @@ public class TestWarmEmissionAnalysisModuleCase4{ private static final Double SPEED_FF = 20.; //km/h private static final Double SPEED_SG = 10.; //km/h - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add(new Object[]{EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction}); - list.add(new Object[]{EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed}); - return list; - } - - public TestWarmEmissionAnalysisModuleCase4(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - - /* * this test method creates a vehicle (lpg properties) and a mock link * for two cases: "avg speed = stop go speed" & "avg speed = free flow speed" the PM warm Emissions and the Emissions "sum" are tested * average values are used */ - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent4() { + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent4(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { //-- set up tables, event handler, parameters, module - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 4 - data in average table Id lpgVehicleId = Id.create("veh 4", Vehicle.class); @@ -139,19 +125,19 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE // sub case avg speed = stop go speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(lpgVehicle, lpglink, lpgLinkLength/ SPEED_SG *3.6 ); - Assert.assertEquals( AVG_PC_FACTOR_SG *lpgLinkLength/1000., warmEmissions.get(PM), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( AVG_PC_FACTOR_SG *lpgLinkLength/1000., warmEmissions.get(PM), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); emissionsModule.throwWarmEmissionEvent(leaveTime, lpglink.getId(), lpgVehicleId, warmEmissions ); - Assert.assertEquals( pollutants.size() * AVG_PC_FACTOR_SG *lpgLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * AVG_PC_FACTOR_SG *lpgLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); warmEmissions.clear(); // sub case avg speed = free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(lpgVehicle, lpglink, lpgLinkLength/ SPEED_FF *3.6 ); - Assert.assertEquals( AVG_PC_FACTOR_FF *lpgLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( AVG_PC_FACTOR_FF *lpgLinkLength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); emissionEventManager.reset(); emissionsModule.throwWarmEmissionEvent(leaveTime, lpglink.getId(), lpgVehicleId, warmEmissions ); - Assert.assertEquals( pollutants.size() * AVG_PC_FACTOR_FF *lpgLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( pollutants.size() * AVG_PC_FACTOR_FF *lpgLinkLength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); warmEmissions.clear(); } @@ -161,9 +147,10 @@ public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionE * for two cases: "avg speed = stop go speed" & "avg speed = free flow speed" the PM warm Emissions are tested * average values are used */ - @Test - public void testCounters2(){ - WarmEmissionAnalysisModule emissionsModule = setUp(); + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + void testCounters2(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod){ + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // ff und sg not part of the detailed table -> use average table Id vehicleId = Id.create("vehicle 4", Vehicle.class); @@ -176,28 +163,28 @@ public void testCounters2(){ // sub case: current speed equals free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(vehicle, lpgLink, lpgLinkLength/ SPEED_FF *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(lpgLinkLength/1000, emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(lpgLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(.0, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(lpgLinkLength/1000, emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(lpgLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(.0, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); emissionsModule.reset(); // sub case: current speed equals free flow speed warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(vehicle, lpgLink, lpgLinkLength/ SPEED_SG *3.6 ); - Assert.assertEquals(0, emissionsModule.getFractionOccurences() ); - Assert.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); - Assert.assertEquals(lpgLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(lpgLinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); - Assert.assertEquals(1, emissionsModule.getStopGoOccurences() ); - Assert.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); + Assertions.assertEquals(0, emissionsModule.getFractionOccurences() ); + Assertions.assertEquals(0., emissionsModule.getFreeFlowKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(0, emissionsModule.getFreeFlowOccurences() ); + Assertions.assertEquals(lpgLinkLength/1000, emissionsModule.getKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(lpgLinkLength/1000, emissionsModule.getStopGoKmCounter(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(1, emissionsModule.getStopGoOccurences() ); + Assertions.assertEquals(1, emissionsModule.getWarmEmissionEventCounter() ); } - private WarmEmissionAnalysisModule setUp() { + private WarmEmissionAnalysisModule setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); @@ -209,7 +196,7 @@ private WarmEmissionAnalysisModule setUp() { EventsManager emissionEventManager = this.emissionEventManager; EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource(EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId); - ecg.setEmissionsComputationMethod(this.emissionsComputationMethod); + ecg.setEmissionsComputationMethod(emissionsComputationMethod); ecg.setDetailedVsAverageLookupBehavior(DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); return new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); @@ -289,7 +276,7 @@ private void fillDetailedTable(Map pollutants = new HashSet<>( Arrays.asList( Pollutant.values() )); - private final EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod; + private static final Set pollutants = new HashSet<>(Arrays.asList(Pollutant.values())); private static final String PASSENGER_CAR = "PASSENGER_CAR"; - - private static final Double DETAILED_ZERO_FACTOR_FF = .0011; + private static final Double DETAILED_ZERO_FACTOR_FF = .0011; + private final HandlerToTestEmissionAnalysisModules emissionEventManager = new HandlerToTestEmissionAnalysisModules(); // vehicle information for regular test cases - // case 5 - data in detailed table, stop go speed zero private final String zeroRoadCategory = "URB_case6"; private final String zeroTechnology = "zero technology"; @@ -99,76 +101,65 @@ public class TestWarmEmissionAnalysisModuleCase5{ private final Double zeroFreeVelocity = 20.; //km/h private final Double zeroSgVelocity = 0.; //km/h - - - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsConfigGroup.EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - public TestWarmEmissionAnalysisModuleCase5( EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - /* * this test method creates a vehicle and a mock link (both zero properties) * the free flow factor is used to calculate and test the PM warm Emissions and HandlerToTestEmissionAnalysisModules Sum * detailed values are used */ - @Test - public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent5(){ + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + public void testCheckVehicleInfoAndCalculateWarmEmissions_and_throwWarmEmissionEvent5(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { //-- set up tables, event handler, parameters, module - WarmEmissionAnalysisModule emissionsModule = setUp(); + WarmEmissionAnalysisModule emissionsModule = setUp(emissionsComputationMethod); // case 6 - data in detailed table, stop go speed zero // use free flow factor to calculate emissions Id zeroVehicleId = Id.create("vehicle zero", Vehicle.class); double zeroLinklength = 3000.; - Link zerolink = TestWarmEmissionAnalysisModule.createMockLink("link zero", zeroLinklength, zeroFreeVelocity / 3.6 ); + Link zerolink = TestWarmEmissionAnalysisModule.createMockLink("link zero", zeroLinklength, zeroFreeVelocity / 3.6); Id lpgLinkId = zerolink.getId(); EmissionUtils.setHbefaRoadType(zerolink, zeroRoadCategory); Id zeroVehicleTypeId = Id.create( - PASSENGER_CAR + ";"+ zeroTechnology + ";" + zeroSizeClass + ";" + zeroConcept, VehicleType.class ); + PASSENGER_CAR + ";" + zeroTechnology + ";" + zeroSizeClass + ";" + zeroConcept, VehicleType.class); VehiclesFactory vehFac = VehicleUtils.getFactory(); Vehicle zeroVehicle = vehFac.createVehicle(zeroVehicleId, vehFac.createVehicleType(zeroVehicleTypeId)); - Map warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(zeroVehicle, zerolink, 2 * zeroLinklength / (zeroFreeVelocity + zeroSgVelocity) * 3.6); - Assert.assertEquals( DETAILED_ZERO_FACTOR_FF *zeroLinklength/1000., warmEmissions.get(PM ), MatsimTestUtils.EPSILON ); + Map warmEmissions = emissionsModule.checkVehicleInfoAndCalculateWarmEmissions(zeroVehicle, zerolink, + 2 * zeroLinklength / (zeroFreeVelocity + zeroSgVelocity) * 3.6); + Assertions.assertEquals(DETAILED_ZERO_FACTOR_FF * zeroLinklength / 1000., warmEmissions.get(PM), MatsimTestUtils.EPSILON); emissionsModule.throwWarmEmissionEvent(22., lpgLinkId, zeroVehicleId, warmEmissions); - Assert.assertEquals( pollutants.size() * DETAILED_ZERO_FACTOR_FF *zeroLinklength/1000., emissionEventManager.getSum(), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(pollutants.size() * DETAILED_ZERO_FACTOR_FF * zeroLinklength / 1000., emissionEventManager.getSum(), + MatsimTestUtils.EPSILON); warmEmissions.clear(); } - - private WarmEmissionAnalysisModule setUp() { + private WarmEmissionAnalysisModule setUp(EmissionsConfigGroup.EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); - TestWarmEmissionAnalysisModule.fillAverageTable( avgHbefaWarmTable ); - fillDetailedTable( detailedHbefaWarmTable ); + TestWarmEmissionAnalysisModule.fillAverageTable(avgHbefaWarmTable); + fillDetailedTable(detailedHbefaWarmTable); Map> hbefaRoadTrafficSpeeds = EmissionUtils.createHBEFASpeedsTable( - avgHbefaWarmTable ); - TestWarmEmissionAnalysisModule.addDetailedRecordsToTestSpeedsTable( hbefaRoadTrafficSpeeds, detailedHbefaWarmTable ); + avgHbefaWarmTable); + TestWarmEmissionAnalysisModule.addDetailedRecordsToTestSpeedsTable(hbefaRoadTrafficSpeeds, detailedHbefaWarmTable); EventsManager emissionEventManager = this.emissionEventManager; EmissionsConfigGroup ecg = new EmissionsConfigGroup(); - ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); - ecg.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); + ecg.setHbefaVehicleDescriptionSource(EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId); + ecg.setEmissionsComputationMethod(emissionsComputationMethod); + ecg.setDetailedVsAverageLookupBehavior(DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); - return new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); + return new WarmEmissionAnalysisModule(avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, + ecg); } - private void fillDetailedTable( Map detailedHbefaWarmTable) { + private void fillDetailedTable(Map detailedHbefaWarmTable) { //entries for zero case { @@ -204,7 +195,3 @@ private void fillDetailedTable( Map pollutants = new HashSet<>( Arrays.asList( Pollutant.values() ) ); private static final String hbefaRoadCategory = "URB"; - private final EmissionsComputationMethod emissionsComputationMethod; private final String passengercar= "PASSENGER_CAR"; private WarmEmissionAnalysisModule weam; @@ -84,20 +85,7 @@ public class TestWarmEmissionAnalysisModuleTrafficSituations { private static final String pcConcept = "<1,4L"; private static final double[] avgPetrolFactor = {20, 200, 2000, 20000, 200000}; - public TestWarmEmissionAnalysisModuleTrafficSituations( EmissionsComputationMethod emissionsComputationMethod ) { - this.emissionsComputationMethod = emissionsComputationMethod; - } - - @Parameterized.Parameters( name = "{index}: ComputationMethod={0}") - public static Collection createCombinations() { - List list = new ArrayList<>(); - list.add( new Object [] {EmissionsComputationMethod.StopAndGoFraction} ) ; - list.add( new Object [] {EmissionsComputationMethod.AverageSpeed} ) ; - return list; - } - - @Before - public void setUp() { + public void setUp(EmissionsComputationMethod emissionsComputationMethod) { Map avgHbefaWarmTable = new HashMap<>(); Map detailedHbefaWarmTable = new HashMap<>(); @@ -110,7 +98,7 @@ public void setUp() { EventsManager emissionEventManager = new HandlerToTestEmissionAnalysisModules(); EmissionsConfigGroup ecg = new EmissionsConfigGroup(); ecg.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.usingVehicleTypeId ); - ecg.setEmissionsComputationMethod( this.emissionsComputationMethod ); + ecg.setEmissionsComputationMethod( emissionsComputationMethod ); ecg.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); //declare using detailed values weam = new WarmEmissionAnalysisModule( avgHbefaWarmTable, detailedHbefaWarmTable, hbefaRoadTrafficSpeeds, pollutants, emissionEventManager, ecg ); @@ -120,8 +108,10 @@ public void setUp() { //Test to check that vehicles not found in the detailed table revert back to average table - ie detailed (petrol, 1,2,3), average (petrol), search pet 4 - @Test - public void testFallBackToAverageTable() { + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + public void testFallBackToAverageTable(EmissionsComputationMethod emissionsComputationMethod) { + setUp(emissionsComputationMethod); Id vehicleId = Id.create("vehicle 1", Vehicle.class); double linkLength = 2*1000.; //in meter Id vehicleTypeId = Id.create(passengercar+ ";"+petrolTechnology+";"+petrolSizeClass+";"+petrolConcept, VehicleType.class); @@ -134,18 +124,20 @@ public void testFallBackToAverageTable() { //allow fallback to average table weam.getEcg().setDetailedVsAverageLookupBehavior( EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); - Assert.assertEquals(detailedPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); vehicleTypeId = Id.create(passengercar+ ";"+pcTechnology+";"+pcSizeClass+";"+pcConcept, VehicleType.class); vehicle = vehFac.createVehicle(vehicleId, vehFac.createVehicleType(vehicleTypeId)); warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); - Assert.assertEquals(avgPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(avgPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); } //using the different computation methods, the NOx warm Emissions are calculated for the diffrent trafic Situations (FF;HEAVY;SAT;SG) - @Test - public void testTrafficSituations() { + @ParameterizedTest + @EnumSource(EmissionsConfigGroup.EmissionsComputationMethod.class) + public void testTrafficSituations(EmissionsComputationMethod emissionsComputationMethod) { + setUp(emissionsComputationMethod); Id vehicleId = Id.create("vehicle 1", Vehicle.class); double linkLength = 2*1000.; //in meter Id vehicleTypeId = Id.create(passengercar+ ";"+petrolTechnology+";"+petrolSizeClass+";"+petrolConcept, VehicleType.class); @@ -159,17 +151,17 @@ public void testTrafficSituations() { double actualSpeed = avgPassengerCarSpeed[FF_INDEX]; double travelTime = linkLength/actualSpeed; warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); - Assert.assertEquals(detailedPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[FF_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); actualSpeed = avgPassengerCarSpeed[HEAVY_INDEX]; travelTime = linkLength/actualSpeed; warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); switch( emissionsComputationMethod ) { case StopAndGoFraction: - Assert.assertEquals( 1360.1219512195123, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 1360.1219512195123, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; case AverageSpeed: - Assert.assertEquals(detailedPetrolFactor[HEAVY_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[HEAVY_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; default: throw new IllegalStateException( "Unexpected value: " + emissionsComputationMethod ); @@ -180,10 +172,10 @@ public void testTrafficSituations() { warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); switch( emissionsComputationMethod ) { case StopAndGoFraction: - Assert.assertEquals( 3431.219512195123, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( 3431.219512195123, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; case AverageSpeed: - Assert.assertEquals(detailedPetrolFactor[SAT_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[SAT_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; default: throw new IllegalStateException( "Unexpected value: " + emissionsComputationMethod ); @@ -192,18 +184,18 @@ public void testTrafficSituations() { actualSpeed = avgPassengerCarSpeed[SG_INDEX]; travelTime = linkLength/actualSpeed; warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); - Assert.assertEquals(detailedPetrolFactor[SG_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[SG_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); actualSpeed = avgPassengerCarSpeed[SG_INDEX] + 5; travelTime = linkLength/actualSpeed; warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime*3.6); switch( emissionsComputationMethod ) { case StopAndGoFraction: - Assert.assertEquals(11715.609756097561, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(11715.609756097561, warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; case AverageSpeed: - Assert.assertEquals(detailedPetrolFactor[SAT_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(detailedPetrolFactor[SAT_INDEX]*(linkLength/1000.), warmEmissions.get( NOx ), MatsimTestUtils.EPSILON ); break; default: throw new IllegalStateException( "Unexpected value: " + emissionsComputationMethod ); @@ -214,10 +206,10 @@ public void testTrafficSituations() { actualSpeed = avgPassengerCarSpeed[SG_INDEX] - 5; travelTime = linkLength / actualSpeed; warmEmissions = weam.checkVehicleInfoAndCalculateWarmEmissions(vehicle, pcLink, travelTime * 3.6); - Assert.assertEquals(detailedPetrolFactor[SG_INDEX] * (linkLength / 1000.), warmEmissions.get(NOx), MatsimTestUtils.EPSILON); + Assertions.assertEquals(detailedPetrolFactor[SG_INDEX] * (linkLength / 1000.), warmEmissions.get(NOx), MatsimTestUtils.EPSILON); //results should be equal here, because in both cases only the s&g value is relevant (0% freeflow, 100% stop&go). - Assert.assertEquals(20000, warmEmissions.get(NOx), MatsimTestUtils.EPSILON); + Assertions.assertEquals(20000, warmEmissions.get(NOx), MatsimTestUtils.EPSILON); } } @@ -257,7 +249,7 @@ private void fillDetailedTable( Map avgHbefaWarmTable) { @@ -282,7 +274,7 @@ private void fillAverageTable( Map should calculate value */ @Test - public void testWarmDetailedValueOnlyDetailed() { + void testWarmDetailedValueOnlyDetailed() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFull, link, travelTimeOnLink); double expectedValue = 30.34984742; // = 200m * 151.7492371 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -85,12 +87,14 @@ public void testWarmDetailedValueOnlyDetailed() { * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testWarm_DetailedElseAbort_ShouldAbort1() { - EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + @Test + void testWarm_DetailedElseAbort_ShouldAbort1() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); - double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s - emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToTechnologyAverage, link, travelTimeOnLink); + double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s + emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToTechnologyAverage, link, travelTimeOnLink); + }); } /** @@ -101,15 +105,17 @@ public void testWarm_DetailedElseAbort_ShouldAbort1() { * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testWarm_DetailedElseAbort_ShouldAbort2() { - EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + @Test + void testWarm_DetailedElseAbort_ShouldAbort2() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); - double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s - emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToAverageTable, link, travelTimeOnLink); + double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s + emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToAverageTable, link, travelTimeOnLink); + }); } - + // --------- DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageElseAbort) ----------- /** * vehicles information is complete @@ -119,14 +125,14 @@ public void testWarm_DetailedElseAbort_ShouldAbort2() { * ---> should calculate value from detailed value */ @Test - public void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() { + void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageElseAbort); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFull, link, travelTimeOnLink); double expectedValue = 30.34984742; // = 200m * 151.7492371 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -138,14 +144,14 @@ public void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackNotNeeded() * ---> should calculate value from technology average */ @Test - public void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackToTechnologyAverage() { + void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackToTechnologyAverage() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageElseAbort); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToTechnologyAverage, link, travelTimeOnLink); double expectedValue = 31.53711548; // = 200m * 157.6855774 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } /** @@ -156,12 +162,14 @@ public void testWarm_DetailedThenTechnologyAverageElseAbort_FallbackToTechnology * * -> should abort --> RuntimeException */ - @Test(expected=RuntimeException.class) - public void testWarm_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { - EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); + @Test + void testWarm_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { + assertThrows(RuntimeException.class, () -> { + EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort); - double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s - emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToAverageTable, link, travelTimeOnLink); + double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s + emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToAverageTable, link, travelTimeOnLink); + }); } // --------- DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ----------- @@ -173,14 +181,14 @@ public void testWarm_DetailedThenTechnologyAverageElseAbort_ShouldAbort() { * ---> should calculate value from detailed value */ @Test - public void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNeeded() { + void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNeeded() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFull, link, travelTimeOnLink); double expectedValue = 30.34984742; // = 200m * 151.7492371 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } @@ -192,14 +200,14 @@ public void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackNotNe * ---> should calculate value from technology average */ @Test - public void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackToTechnology() { + void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackToTechnology() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToTechnologyAverage, link, travelTimeOnLink); double expectedValue = 31.53711548; // = 200m * 157.6855774 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } /** @@ -212,14 +220,14 @@ public void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackToTec * ---> should calculate value from average table */ @Test - public void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackToAverageTable() { + void testWarm_DetailedThenTechnologyAverageThenAverageTable_FallbackToAverageTable() { EmissionModule emissionModule = setUpScenario(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); double travelTimeOnLink = 21; //sec. approx freeSpeed of link12 is : (200 m) / (9.72.. m/s) approx 20.57 s Map warmEmissions = emissionModule.getWarmEmissionAnalysisModule().checkVehicleInfoAndCalculateWarmEmissions(vehicleFallbackToAverageTable, link, travelTimeOnLink); double expectedValue = 31.1947174; // = 200m * 155.973587 g/km - Assert.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals( expectedValue, warmEmissions.get(Pollutant.CO2_TOTAL ), MatsimTestUtils.EPSILON ); } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/VspHbefaRoadTypeMappingTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/VspHbefaRoadTypeMappingTest.java index c46b4a65ac6..f0164d11e86 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/VspHbefaRoadTypeMappingTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/VspHbefaRoadTypeMappingTest.java @@ -1,17 +1,17 @@ package org.matsim.contrib.emissions; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.core.network.NetworkUtils; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class VspHbefaRoadTypeMappingTest { - @Test - public void testSimpleMapping() { + @Test + void testSimpleMapping() { var mapper = new VspHbefaRoadTypeMapping(); var link = getTestLink("", 70 / 3.6); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionGridAnalyzerTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionGridAnalyzerTest.java index 3f764cd6b88..d9614bd3dea 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionGridAnalyzerTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionGridAnalyzerTest.java @@ -3,8 +3,8 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; @@ -32,13 +32,13 @@ import java.util.Map; import java.util.UUID; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.matsim.contrib.emissions.Pollutant.*; public class EmissionGridAnalyzerTest { - @Rule - public MatsimTestUtils testUtils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils testUtils = new MatsimTestUtils(); private Geometry createRect(double maxX, double maxY) { return new GeometryFactory().createPolygon(new Coordinate[]{ @@ -49,21 +49,23 @@ private Geometry createRect(double maxX, double maxY) { new Coordinate(0, 0)}); } - @Test(expected = IllegalArgumentException.class) - public void initialize_invalidGridSizeToSmoothingRadiusRatio_exception() { + @Test + void initialize_invalidGridSizeToSmoothingRadiusRatio_exception() { + assertThrows(IllegalArgumentException.class, () -> { - new EmissionGridAnalyzer.Builder() - .withSmoothingRadius(1) - .withGridSize(1000) - .withNetwork(NetworkUtils.createNetwork()) - .withTimeBinSize(1) - .build(); + new EmissionGridAnalyzer.Builder() + .withSmoothingRadius(1) + .withGridSize(1000) + .withNetwork(NetworkUtils.createNetwork()) + .withTimeBinSize(1) + .build(); - fail("invalid grid size to smoothing radius ratio should cause exception"); - } + fail("invalid grid size to smoothing radius ratio should cause exception"); + }); + } - @Test - public void process() { + @Test + void process() { final Pollutant pollutant = HC; final double pollutionPerEvent = 1; @@ -87,8 +89,8 @@ public void process() { }); } - @Test - public void process_singleLinkWithOneEvent() { + @Test + void process_singleLinkWithOneEvent() { final Pollutant pollutant = CO; final double pollutionPerEvent = 1000; @@ -126,8 +128,8 @@ public void process_singleLinkWithOneEvent() { bin.getValue().getCells().forEach(cell -> assertTrue(cell.getValue().get(pollutant) <= valueOfCellWithLink)); } - @Test - public void process_singleLinkWithTwoEvents() { + @Test + void process_singleLinkWithTwoEvents() { final Pollutant pollutant = CO; final double pollutionPerEvent = 1000; @@ -165,8 +167,8 @@ public void process_singleLinkWithTwoEvents() { bin.getValue().getCells().forEach(cell -> assertTrue(cell.getValue().get(pollutant) <= valueOfCellWithLink)); } - @Test - public void process_twoLinksWithOneEventEach() { + @Test + void process_twoLinksWithOneEventEach() { final Pollutant pollutant = CO; final double pollutionPerEvent = 1000; @@ -207,8 +209,8 @@ public void process_twoLinksWithOneEventEach() { bin.getValue().getCells().forEach(cell -> assertTrue(cell.getValue().get(pollutant) <= valueOfCellWithLink + 0.1)); } - @Test - public void process_twoLinksWithTwoEventsEach() { + @Test + void process_twoLinksWithTwoEventsEach() { final Pollutant pollutant = NOx; final double pollutionPerEvent = 1000; @@ -249,8 +251,8 @@ public void process_twoLinksWithTwoEventsEach() { bin.getValue().getCells().forEach(cell -> assertTrue(cell.getValue().get(pollutant) <= valueOfCellWithLink + 0.1)); } - @Test - public void process_withBoundaries() { + @Test + void process_withBoundaries() { final double pollutionPerEvent = 1; Path eventsFile = Paths.get(testUtils.getOutputDirectory()).resolve(UUID.randomUUID().toString() + ".xml"); @@ -274,8 +276,8 @@ public void process_withBoundaries() { assertEquals(25, bin.getValue().getCells().size()); } - @Test - public void processToJson() { + @Test + void processToJson() { final double pollutionPerEvent = 1; final int time = 1; @@ -295,8 +297,8 @@ public void processToJson() { assertNotNull(json); } - @Test - public void processToJsonFile() throws IOException { + @Test + void processToJsonFile() throws IOException { final double pollutionPerEvent = 1; final int time = 1; @@ -319,8 +321,8 @@ public void processToJsonFile() throws IOException { assertTrue(jsonFileData.length > 0); } - @Test - public void process_regression() throws IOException { + @Test + void process_regression() throws IOException { var scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario" ); var configUrl = IOUtils.extendUrl( scenarioUrl, "config_empty.xml" ); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsByPollutantTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsByPollutantTest.java index f4a970526ad..635affd8832 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsByPollutantTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsByPollutantTest.java @@ -1,7 +1,7 @@ package org.matsim.contrib.emissions.analysis; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.matsim.contrib.emissions.Pollutant.CO; import static org.matsim.contrib.emissions.Pollutant.NO2; @@ -9,19 +9,19 @@ import java.util.LinkedHashMap; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.contrib.emissions.Pollutant; import org.matsim.contrib.emissions.utils.EmissionUtilsTest; public class EmissionsByPollutantTest { - // The EmissionsByPollutant potentially adds up the same emissions coming from cold and warm. Thus, this cannot be combined into the enum approach - // without some thinking. kai, jan'20 - // Quite possibly, should just combine them into an enum "pollutant"?! There is, anyways, the JM map of those emissions that are actually present in the - // input file. kai, jan'20 + // The EmissionsByPollutant potentially adds up the same emissions coming from cold and warm. Thus, this cannot be combined into the enum approach + // without some thinking. kai, jan'20 + // Quite possibly, should just combine them into an enum "pollutant"?! There is, anyways, the JM map of those emissions that are actually present in the + // input file. kai, jan'20 - @Test - public void initialize() { + @Test + void initialize() { Map emissions = EmissionUtilsTest.createEmissions(); @@ -38,8 +38,8 @@ public void initialize() { }); } - @Test - public void addEmission() { + @Test + void addEmission() { Map emissions = EmissionUtilsTest.createEmissions(); final double valueToAdd = 5; @@ -58,8 +58,8 @@ public void addEmission() { assertEquals(expectedValue, retrievedResult, 0); } - @Test - public void addEmission_PollutantNotPresentYet() { + @Test + void addEmission_PollutantNotPresentYet() { Map initialPollutants = new HashMap<>(); initialPollutants.put(CO, Math.random()); @@ -74,8 +74,8 @@ public void addEmission_PollutantNotPresentYet() { assertEquals(valueToAdd, retrievedResult, 0); } - @Test - public void addEmissions() { + @Test + void addEmissions() { Map emissions = EmissionUtilsTest.createEmissions(); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsOnLinkEventHandlerTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsOnLinkEventHandlerTest.java index 9013c08e763..fe8c91a53ab 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsOnLinkEventHandlerTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/EmissionsOnLinkEventHandlerTest.java @@ -1,6 +1,6 @@ package org.matsim.contrib.emissions.analysis; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.matsim.contrib.emissions.Pollutant.HC; import java.util.ArrayList; @@ -10,7 +10,7 @@ import java.util.UUID; import java.util.stream.Collectors; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.analysis.time.TimeBinMap; @@ -37,8 +37,8 @@ private static Collection createWarmEmissionEvents(Id l return result; } - @Test - public void handleWarmEmissionsEvent() { + @Test + void handleWarmEmissionsEvent() { Id linkId = Id.createLinkId(UUID.randomUUID().toString()); Id vehicleId = Id.createVehicleId(UUID.randomUUID().toString()); @@ -66,8 +66,8 @@ public void handleWarmEmissionsEvent() { emissions.forEach((key, value) -> assertEquals(value, link2pollutantsMap.get(linkId).get(key), 0.0001)); } - @Test - public void handleColdEmissionEvent() { + @Test + void handleColdEmissionEvent() { Id linkId = Id.createLinkId(UUID.randomUUID().toString()); Id vehicleId = Id.createVehicleId(UUID.randomUUID().toString()); @@ -89,8 +89,8 @@ public void handleColdEmissionEvent() { emissions.forEach((key, value) -> assertEquals(value, link2pollutantsMap.get(linkId).get(key), 0.0001)); } - @Test - public void handleMultipleEvents() { + @Test + void handleMultipleEvents() { final Id linkId = Id.createLinkId(UUID.randomUUID().toString()); final int numberOfEvents = 1000; @@ -121,8 +121,8 @@ public void handleMultipleEvents() { assertEquals(3 * numberOfEvents * emissionValue, value, 0.0001)); } - @Test - public void handleSingleLinkWithSingleEvent() { + @Test + void handleSingleLinkWithSingleEvent() { Id linkId = Id.createLinkId(UUID.randomUUID().toString()); Id vehicleId = Id.createVehicleId(UUID.randomUUID().toString()); @@ -144,8 +144,8 @@ public void handleSingleLinkWithSingleEvent() { link2pollutantsMap.get(linkId).forEach((pollutant, value) -> assertEquals(emissionValue, value, 0.0001)); } - @Test - public void handleSingleLinkWithMultipleEvents() { + @Test + void handleSingleLinkWithMultipleEvents() { Id linkId = Id.createLinkId(UUID.randomUUID().toString()); Id vehicleId = Id.createVehicleId(UUID.randomUUID().toString()); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/FastEmissionGridAnalyzerTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/FastEmissionGridAnalyzerTest.java index ceb4b2a093d..423131e4f6f 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/FastEmissionGridAnalyzerTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/FastEmissionGridAnalyzerTest.java @@ -1,7 +1,7 @@ package org.matsim.contrib.emissions.analysis; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.contrib.emissions.Pollutant; @@ -15,16 +15,16 @@ import java.nio.file.Paths; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class FastEmissionGridAnalyzerTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - @Test - public void rasterNetwork_singleLink() { + @Test + void rasterNetwork_singleLink() { final var cellSize = 10.; final var cellArea = cellSize * cellSize; @@ -50,8 +50,8 @@ public void rasterNetwork_singleLink() { raster.forEachIndex((xi, yi, value) -> assertEquals(emissionPerLink / expectedCellNumber / cellArea, value, 0.00000001)); } - @Test - public void rasterNetwork_singleLinkWithBackwardsOrientation() { + @Test + void rasterNetwork_singleLinkWithBackwardsOrientation() { final var cellSize = 10.; final var cellArea = cellSize * cellSize; @@ -77,8 +77,8 @@ public void rasterNetwork_singleLinkWithBackwardsOrientation() { raster.forEachIndex((xi, yi, value) -> assertEquals(emissionPerLink / expectedCellNumber / cellArea, value, 0.00000001)); } - @Test - public void rasterNetwork_twoLinks() { + @Test + void rasterNetwork_twoLinks() { final var cellSize = 10.; final var cellArea = cellSize * cellSize; @@ -121,8 +121,8 @@ public void rasterNetwork_twoLinks() { } - @Test - public void blur_rasterWithSingleValue() { + @Test + void blur_rasterWithSingleValue() { final var initialValue = 10.; final var EPSILON = 0.000000001; @@ -150,8 +150,8 @@ public void blur_rasterWithSingleValue() { }); } - @Test - public void processLinkEmissions_twoLinks() { + @Test + void processLinkEmissions_twoLinks() { var network = NetworkUtils.createNetwork(new NetworkConfigGroup()); var node1 = network.getFactory().createNode(Id.createNodeId("node1"), new Coord(0, 49)); @@ -182,8 +182,8 @@ public void processLinkEmissions_twoLinks() { }); } - @Test - public void processEventsFile() { + @Test + void processEventsFile() { final var networkUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("equil"), "network.xml"); final var emissionEvents = Paths.get(utils.getOutputDirectory()).resolve("emission.events.xml.gz"); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RasterTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RasterTest.java index ee57b97cb2d..7e6b360020d 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RasterTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RasterTest.java @@ -1,14 +1,14 @@ package org.matsim.contrib.emissions.analysis; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import org.junit.jupiter.api.Test; public class RasterTest { - @Test - public void test() { + @Test + void test() { var bounds = new Raster.Bounds(10, 10, 100, 100); var raster = new Raster(bounds, 10); @@ -38,8 +38,8 @@ public void test() { } } - @Test - public void testInsertion() { + @Test + void testInsertion() { var bounds = new Raster.Bounds(4, 5, 123, 244); var raster = new Raster(bounds, 10); @@ -50,8 +50,8 @@ public void testInsertion() { raster.forEachIndex((x, y, value) -> assertEquals(10, value, 0.000001)); } - @Test - public void testIterationByIndex() { + @Test + void testIterationByIndex() { var bounds = new Raster.Bounds(4, 5, 123, 244); var raster = new Raster(bounds, 10); @@ -68,8 +68,8 @@ public void testIterationByIndex() { }); } - @Test - public void testIterationByCoord() { + @Test + void testIterationByCoord() { var bounds = new Raster.Bounds(4, 5, 123, 244); var raster = new Raster(bounds, 10); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RawEmissionEventsReaderTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RawEmissionEventsReaderTest.java index 3eda5f417e8..4592d26ec17 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RawEmissionEventsReaderTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/analysis/RawEmissionEventsReaderTest.java @@ -1,7 +1,7 @@ package org.matsim.contrib.emissions.analysis; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.contrib.emissions.Pollutant; import org.matsim.contrib.emissions.utils.TestUtils; @@ -12,15 +12,15 @@ import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicInteger; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class RawEmissionEventsReaderTest { - @Rule - public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension + public MatsimTestUtils utils = new MatsimTestUtils(); - @Test - public void handleNonEventNode() { + @Test + void handleNonEventNode() { // read in an xml file which doesn't have events. It will parse the whole file but will not handle any of the // parsed nodes @@ -33,8 +33,8 @@ public void handleNonEventNode() { // this test passes if the in the callback 'fail()' is not reached. } - @Test - public void handleNonEmissionEvent() { + @Test + void handleNonEmissionEvent() { // read in events file wihtout emission events. Those events should be ignored var eventsUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("equil"), "output_events.xml.gz"); @@ -46,8 +46,8 @@ public void handleNonEmissionEvent() { // this test passes if the in the callback 'fail()' is not reached. } - @Test - public void handleColdEmissionEvent() { + @Test + void handleColdEmissionEvent() { final double expectedValue = 10; final int expectedTime = 1; @@ -71,8 +71,8 @@ public void handleColdEmissionEvent() { assertEquals(expectedEventsCount, counter.get()); } - @Test - public void handleWarmEmissionEvent() { + @Test + void handleWarmEmissionEvent() { final double expectedValue = 10; final int expectedTime = 1; @@ -95,4 +95,4 @@ public void handleWarmEmissionEvent() { assertEquals(expectedEventsCount, counter.get()); } -} \ No newline at end of file +} diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestColdEmissionEventImpl.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestColdEmissionEventImpl.java index 5be0e9e9ca6..022265df9f0 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestColdEmissionEventImpl.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestColdEmissionEventImpl.java @@ -21,8 +21,8 @@ package org.matsim.contrib.emissions.events; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.Pollutant; @@ -55,7 +55,7 @@ public class TestColdEmissionEventImpl { private final Set coldPollutants = new HashSet<>(Arrays.asList(CO, FC, HC, NMHC, NOx, NO2,PM)); @Test - public final void testGetAttributesForCompleteEmissionMaps(){ + final void testGetAttributesForCompleteEmissionMaps(){ //test normal functionality //create a normal event impl @@ -64,20 +64,13 @@ public final void testGetAttributesForCompleteEmissionMaps(){ ColdEmissionEvent ce = new ColdEmissionEvent(0.0, linkId, vehicleId, coldEmissionsMap); Map ceg = ce.getAttributes(); - Assert.assertEquals("the CO value of this cold emission event was "+ Double.parseDouble(ceg.get(CO.name()))+ "but should have been "+ co, - Double.parseDouble(ceg.get(CO.name())), co, MatsimTestUtils.EPSILON); - Assert.assertEquals("the FC value of this cold emission event was "+ Double.parseDouble(ceg.get(FC.name()))+ "but should have been "+ fc, - Double.parseDouble(ceg.get(FC.name())), fc, MatsimTestUtils.EPSILON); - Assert.assertEquals("the HC value of this cold emission event was "+ Double.parseDouble(ceg.get(HC.name()))+ "but should have been "+ hc, - Double.parseDouble(ceg.get(HC.name())), hc, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NMHC value of this cold emission event was "+ Double.parseDouble(ceg.get(NMHC.name()))+ "but should have been "+ nm, - Double.parseDouble(ceg.get(NMHC.name())), nm, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NO2 value of this cold emission event was "+ Double.parseDouble(ceg.get(NO2.name()))+ "but should have been "+ n2, - Double.parseDouble(ceg.get(NO2.name())), n2, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NOx value of this cold emission event was "+ Double.parseDouble(ceg.get(NOx.name()))+ "but should have been "+ nx, - Double.parseDouble(ceg.get(NOx.name())), nx, MatsimTestUtils.EPSILON); - Assert.assertEquals("the PM value of this cold emission event was "+ Double.parseDouble(ceg.get(PM.name()))+ "but should have been "+ pm, - Double.parseDouble(ceg.get(PM.name())), pm, MatsimTestUtils.EPSILON); + Assertions.assertEquals(Double.parseDouble(ceg.get(CO.name())), co, MatsimTestUtils.EPSILON, "the CO value of this cold emission event was "+ Double.parseDouble(ceg.get(CO.name()))+ "but should have been "+ co); + Assertions.assertEquals(Double.parseDouble(ceg.get(FC.name())), fc, MatsimTestUtils.EPSILON, "the FC value of this cold emission event was "+ Double.parseDouble(ceg.get(FC.name()))+ "but should have been "+ fc); + Assertions.assertEquals(Double.parseDouble(ceg.get(HC.name())), hc, MatsimTestUtils.EPSILON, "the HC value of this cold emission event was "+ Double.parseDouble(ceg.get(HC.name()))+ "but should have been "+ hc); + Assertions.assertEquals(Double.parseDouble(ceg.get(NMHC.name())), nm, MatsimTestUtils.EPSILON, "the NMHC value of this cold emission event was "+ Double.parseDouble(ceg.get(NMHC.name()))+ "but should have been "+ nm); + Assertions.assertEquals(Double.parseDouble(ceg.get(NO2.name())), n2, MatsimTestUtils.EPSILON, "the NO2 value of this cold emission event was "+ Double.parseDouble(ceg.get(NO2.name()))+ "but should have been "+ n2); + Assertions.assertEquals(Double.parseDouble(ceg.get(NOx.name())), nx, MatsimTestUtils.EPSILON, "the NOx value of this cold emission event was "+ Double.parseDouble(ceg.get(NOx.name()))+ "but should have been "+ nx); + Assertions.assertEquals(Double.parseDouble(ceg.get(PM.name())), pm, MatsimTestUtils.EPSILON, "the PM value of this cold emission event was "+ Double.parseDouble(ceg.get(PM.name()))+ "but should have been "+ pm); } @@ -91,9 +84,9 @@ private void setColdEmissions( Map coldEmissionsMap ) { coldEmissionsMap.put(PM, pm); } - + @Test - public final void testGetAttributesForIncompleteMaps(){ + final void testGetAttributesForIncompleteMaps(){ //the getAttributesMethod should // - return null if the emission map is empty // - throw NullPointerExceptions if the emission values are not set @@ -124,7 +117,7 @@ public final void testGetAttributesForIncompleteMaps(){ for(Pollutant cp : coldPollutants){ //empty map - Assert.assertNull(emptyMapEvent.getAttributes().get(cp)); + Assertions.assertNull(emptyMapEvent.getAttributes().get(cp)); //values not set try{ @@ -142,8 +135,8 @@ public final void testGetAttributesForIncompleteMaps(){ noMapNullPointers++; } } - Assert.assertEquals(numberOfColdPollutants, valNullPointers); - Assert.assertEquals(numberOfColdPollutants, noMapNullPointers); + Assertions.assertEquals(numberOfColdPollutants, valNullPointers); + Assertions.assertEquals(numberOfColdPollutants, noMapNullPointers); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestWarmEmissionEventImpl.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestWarmEmissionEventImpl.java index c1ca71ad628..62691c3670f 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestWarmEmissionEventImpl.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/TestWarmEmissionEventImpl.java @@ -28,8 +28,8 @@ * 3 test the number of attributes returned */ -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.contrib.emissions.Pollutant; @@ -59,7 +59,7 @@ public class TestWarmEmissionEventImpl { @Test - public final void testGetAttributesForCompleteEmissionMaps(){ + final void testGetAttributesForCompleteEmissionMaps(){ //test normal functionality //create a normal event impl @@ -82,28 +82,19 @@ public final void testGetAttributesForCompleteEmissionMaps(){ WarmEmissionEvent we = new WarmEmissionEvent(0.0, linkId, vehicleId, map); Map weg = we.getAttributes(); - Assert.assertEquals("the CO value of this warm emission event was "+ Double.parseDouble(weg.get(CO.name()))+ "but should have been "+ co, - Double.parseDouble(weg.get(CO.name())), co, MatsimTestUtils.EPSILON); - Assert.assertEquals("the CO2 value of this warm emission event was "+ Double.parseDouble(weg.get(CO2_TOTAL.name()))+ "but should have been "+ c2, - Double.parseDouble(weg.get(CO2_TOTAL.name())), c2, MatsimTestUtils.EPSILON); - Assert.assertEquals("the FC value of this warm emission event was "+ Double.parseDouble(weg.get(FC.name()))+ "but should have been "+ fc, - Double.parseDouble(weg.get(FC.name())), fc, MatsimTestUtils.EPSILON); - Assert.assertEquals("the HC value of this warm emission event was "+ Double.parseDouble(weg.get(HC.name()))+ "but should have been "+ hc, - Double.parseDouble(weg.get(HC.name())), hc, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NMHC value of this warm emission event was "+ Double.parseDouble(weg.get(NMHC.name()))+ "but should have been "+ nm, - Double.parseDouble(weg.get(NMHC.name())), nm, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NO2 value of this warm emission event was "+ Double.parseDouble(weg.get(NO2.name()))+ "but should have been "+ n2, - Double.parseDouble(weg.get(NO2.name())), n2, MatsimTestUtils.EPSILON); - Assert.assertEquals("the NOx value of this warm emission event was "+ Double.parseDouble(weg.get(NOx.name()))+ "but should have been "+ nx, - Double.parseDouble(weg.get(NOx.name())), nx, MatsimTestUtils.EPSILON); - Assert.assertEquals("the PM value of this warm emission event was "+ Double.parseDouble(weg.get(PM.name()))+ "but should have been "+ pm, - Double.parseDouble(weg.get(PM.name())), pm, MatsimTestUtils.EPSILON); - Assert.assertEquals("the SO2 value of this warm emission event was "+ Double.parseDouble(weg.get(SO2.name()))+ "but should have been "+ so, - Double.parseDouble(weg.get(SO2.name())), so, MatsimTestUtils.EPSILON); + Assertions.assertEquals(Double.parseDouble(weg.get(CO.name())), co, MatsimTestUtils.EPSILON, "the CO value of this warm emission event was "+ Double.parseDouble(weg.get(CO.name()))+ "but should have been "+ co); + Assertions.assertEquals(Double.parseDouble(weg.get(CO2_TOTAL.name())), c2, MatsimTestUtils.EPSILON, "the CO2 value of this warm emission event was "+ Double.parseDouble(weg.get(CO2_TOTAL.name()))+ "but should have been "+ c2); + Assertions.assertEquals(Double.parseDouble(weg.get(FC.name())), fc, MatsimTestUtils.EPSILON, "the FC value of this warm emission event was "+ Double.parseDouble(weg.get(FC.name()))+ "but should have been "+ fc); + Assertions.assertEquals(Double.parseDouble(weg.get(HC.name())), hc, MatsimTestUtils.EPSILON, "the HC value of this warm emission event was "+ Double.parseDouble(weg.get(HC.name()))+ "but should have been "+ hc); + Assertions.assertEquals(Double.parseDouble(weg.get(NMHC.name())), nm, MatsimTestUtils.EPSILON, "the NMHC value of this warm emission event was "+ Double.parseDouble(weg.get(NMHC.name()))+ "but should have been "+ nm); + Assertions.assertEquals(Double.parseDouble(weg.get(NO2.name())), n2, MatsimTestUtils.EPSILON, "the NO2 value of this warm emission event was "+ Double.parseDouble(weg.get(NO2.name()))+ "but should have been "+ n2); + Assertions.assertEquals(Double.parseDouble(weg.get(NOx.name())), nx, MatsimTestUtils.EPSILON, "the NOx value of this warm emission event was "+ Double.parseDouble(weg.get(NOx.name()))+ "but should have been "+ nx); + Assertions.assertEquals(Double.parseDouble(weg.get(PM.name())), pm, MatsimTestUtils.EPSILON, "the PM value of this warm emission event was "+ Double.parseDouble(weg.get(PM.name()))+ "but should have been "+ pm); + Assertions.assertEquals(Double.parseDouble(weg.get(SO2.name())), so, MatsimTestUtils.EPSILON, "the SO2 value of this warm emission event was "+ Double.parseDouble(weg.get(SO2.name()))+ "but should have been "+ so); } @Test - public final void testGetAttributesForIncompleteMaps(){ + final void testGetAttributesForIncompleteMaps(){ //the getAttributesMethod should // - return null if the emission map is empty // - throw NullPointerExceptions if the emission values are not set @@ -140,7 +131,7 @@ public final void testGetAttributesForIncompleteMaps(){ String wp=wpEnum.name(); //empty map - Assert.assertNull(emptyMapEvent.getAttributes().get(wp)); + Assertions.assertNull(emptyMapEvent.getAttributes().get(wp)); //values not set try{ @@ -158,8 +149,8 @@ public final void testGetAttributesForIncompleteMaps(){ noMapNullPointers++; } } - Assert.assertEquals(numberOfWarmPollutants, valuesNotSetNullPointers); - Assert.assertEquals(numberOfWarmPollutants, noMapNullPointers); + Assertions.assertEquals(numberOfWarmPollutants, valuesNotSetNullPointers); + Assertions.assertEquals(numberOfWarmPollutants, noMapNullPointers); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/VehicleLeavesTrafficEventTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/VehicleLeavesTrafficEventTest.java index e8a0513f36a..2858e572d58 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/VehicleLeavesTrafficEventTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/events/VehicleLeavesTrafficEventTest.java @@ -1,8 +1,8 @@ package org.matsim.contrib.emissions.events; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.EmissionModule; import org.matsim.contrib.emissions.VspHbefaRoadTypeMapping; @@ -36,10 +36,10 @@ */ public class VehicleLeavesTrafficEventTest { - @Rule public MatsimTestUtils utils = new MatsimTestUtils(); + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); - @Test - public final void testRareEventsFromBerlinScenario (){ + @Test + final void testRareEventsFromBerlinScenario(){ final String emissionEventsFileName = "smallBerlinSample.emissions.events.offline.xml.gz"; final String resultingEvents = utils.getOutputDirectory() + emissionEventsFileName; @@ -82,7 +82,7 @@ public void install(){ } final String expected = utils.getClassInputDirectory() + emissionEventsFileName; EventsFileComparator.Result result = EventsUtils.compareEventsFiles(expected, resultingEvents); - Assert.assertEquals( EventsFileComparator.Result.FILES_ARE_EQUAL, result); + Assertions.assertEquals( EventsFileComparator.Result.FILES_ARE_EQUAL, result); } -} \ No newline at end of file +} diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExampleIT.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExampleIT.java index fbe73cb8d24..951ed2fb237 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExampleIT.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunAverageEmissionToolOfflineExampleIT.java @@ -18,9 +18,9 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contrib.emissions.EmissionUtils; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup.HbefaVehicleDescriptionSource; @@ -30,7 +30,6 @@ import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; -import org.matsim.utils.eventsfilecomparison.EventsFileComparator; import org.matsim.utils.eventsfilecomparison.EventsFileComparator.Result; import java.net.URL; @@ -40,17 +39,17 @@ * */ public class RunAverageEmissionToolOfflineExampleIT{ - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; @Test - public final void testAverage_vehTypeV1() { + final void testAverage_vehTypeV1() { RunAverageEmissionToolOfflineExample offlineExample = new RunAverageEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv1/config_average.xml"); URL scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv1" ); URL configUrl = IOUtils.extendUrl( scenarioUrl, "config_average.xml" ); Config config = offlineExample.prepareConfig( new String [] {configUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( HbefaVehicleDescriptionSource.fromVehicleTypeDescription ); @@ -60,18 +59,18 @@ public final void testAverage_vehTypeV1() { String expected = utils.getInputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; String actual = utils.getOutputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; Result result = EventsUtils.compareEventsFiles( expected, actual ); - Assert.assertEquals( Result.FILES_ARE_EQUAL, result); + Assertions.assertEquals( Result.FILES_ARE_EQUAL, result); } @Test - public final void testAverage_vehTypeV2() { + final void testAverage_vehTypeV2() { RunAverageEmissionToolOfflineExample offlineExample = new RunAverageEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv2/config_average.xml"); URL scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv2" ); URL configUrl = IOUtils.extendUrl( scenarioUrl, "config_average.xml" ); Config config = offlineExample.prepareConfig( new String [] {configUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( HbefaVehicleDescriptionSource.asEngineInformationAttributes ); @@ -82,7 +81,7 @@ public final void testAverage_vehTypeV2() { String expected = utils.getInputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; String actual = utils.getOutputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; Result result = EventsUtils.compareEventsFiles( expected, actual ); - Assert.assertEquals( Result.FILES_ARE_EQUAL, result); + Assertions.assertEquals( Result.FILES_ARE_EQUAL, result); } /** @@ -91,14 +90,14 @@ public final void testAverage_vehTypeV2() { * where this is used, has no way to know which file format was originally read. See some discussion there. :-( */ @Test - public final void testAverage_vehTypeV2b() { + final void testAverage_vehTypeV2b() { RunAverageEmissionToolOfflineExample offlineExample = new RunAverageEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv2/config_average.xml"); URL scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv2" ); URL configUrl = IOUtils.extendUrl( scenarioUrl, "config_average.xml" ); Config config = offlineExample.prepareConfig( new String [] {configUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( HbefaVehicleDescriptionSource.fromVehicleTypeDescription ); @@ -108,19 +107,19 @@ public final void testAverage_vehTypeV2b() { String expected = utils.getInputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; String actual = utils.getOutputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; Result result = EventsUtils.compareEventsFiles( expected, actual ); - Assert.assertEquals( Result.FILES_ARE_EQUAL, result); + Assertions.assertEquals( Result.FILES_ARE_EQUAL, result); } @Test - public final void testAverage_vehTypeV2_HBEFA4() { + final void testAverage_vehTypeV2_HBEFA4() { RunAverageEmissionToolOfflineExample offlineExample = new RunAverageEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv2/config_average.xml"); URL scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv2" ); URL configUrl = IOUtils.extendUrl( scenarioUrl, "config_average.xml" ); Config config = offlineExample.prepareConfig( new String [] {configUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setAverageColdEmissionFactorsFile("../sample_41_EFA_ColdStart_vehcat_2020average.csv"); @@ -132,6 +131,6 @@ public final void testAverage_vehTypeV2_HBEFA4() { String expected = utils.getInputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; String actual = utils.getOutputDirectory() + RunAverageEmissionToolOfflineExample.emissionEventsFilename; Result result = EventsUtils.compareEventsFiles( expected, actual ); - Assert.assertEquals( Result.FILES_ARE_EQUAL, result); + Assertions.assertEquals( Result.FILES_ARE_EQUAL, result); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExampleIT.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExampleIT.java index 7c8c842941a..e2ed6c54bba 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExampleIT.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOfflineExampleIT.java @@ -18,13 +18,12 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup.DetailedVsAverageLookupBehavior; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup.HbefaVehicleDescriptionSource; -import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.utils.io.IOUtils; import org.matsim.examples.ExamplesUtils; @@ -35,7 +34,7 @@ * */ public class RunDetailedEmissionToolOfflineExampleIT { - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; /* * @@ -46,7 +45,7 @@ public class RunDetailedEmissionToolOfflineExampleIT { // Expecting RuntimeException, because requested values are only in average file. Without fallback it has to fail! // @Test(expected=RuntimeException.class) @Test - public final void testDetailed_vehTypeV1() { + final void testDetailed_vehTypeV1() { boolean gotAnException = false ; try { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); @@ -59,19 +58,19 @@ public final void testDetailed_vehTypeV1() { EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( HbefaVehicleDescriptionSource.fromVehicleTypeDescription ); emissionsConfig.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); - config.controler().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); offlineExample.run(); } catch (Exception ee ) { gotAnException = true ; } - Assert.assertTrue( gotAnException ); + Assertions.assertTrue( gotAnException ); } // Expecting RuntimeException, because requested values are only in average file. Without fallback it has to fail! // @Test(expected=RuntimeException.class) @Test - public final void testDetailed_vehTypeV2() { + final void testDetailed_vehTypeV2() { boolean gotAnException = false ; try { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); @@ -83,19 +82,19 @@ public final void testDetailed_vehTypeV2() { EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); offlineExample.run(); } catch (Exception ee ) { gotAnException = true ; } - Assert.assertTrue( gotAnException ); + Assertions.assertTrue( gotAnException ); } // Expecting RuntimeException, because requested values are only in average file. Without fallback it has to fail! // @Test(expected=RuntimeException.class) @Test - public final void testDetailed_vehTypeV2_HBEFA4() { + final void testDetailed_vehTypeV2_HBEFA4() { boolean gotAnException = false ; try { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); @@ -110,12 +109,12 @@ public final void testDetailed_vehTypeV2_HBEFA4() { emissionsConfig.setDetailedColdEmissionFactorsFile("../sample_41_EFA_ColdStart_SubSegm_2020detailed.csv"); emissionsConfig.setDetailedWarmEmissionFactorsFile("../sample_41_EFA_HOT_SubSegm_2020detailed.csv"); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); offlineExample.run(); } catch (Exception ee ) { gotAnException = true ; } - Assert.assertTrue( gotAnException ); + Assertions.assertTrue( gotAnException ); } @@ -127,7 +126,7 @@ public final void testDetailed_vehTypeV2_HBEFA4() { * */ @Test - public final void testDetailed_vehTypeV1_FallbackToAverage() { + final void testDetailed_vehTypeV1_FallbackToAverage() { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv1/config_detailed.xml"); @@ -135,7 +134,7 @@ public final void testDetailed_vehTypeV1_FallbackToAverage() { var cfUrl = IOUtils.extendUrl( scUrl, "config_detailed.xml" ); var config = offlineExample.prepareConfig( new String [] {cfUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setAverageColdEmissionFactorsFile("../sample_41_EFA_ColdStart_vehcat_2020average.csv"); @@ -148,7 +147,7 @@ public final void testDetailed_vehTypeV1_FallbackToAverage() { } @Test - public final void testDetailed_vehTypeV2_FallbackToAverage() { + final void testDetailed_vehTypeV2_FallbackToAverage() { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv2/config_detailed.xml"); @@ -156,7 +155,7 @@ public final void testDetailed_vehTypeV2_FallbackToAverage() { var cfUrl = IOUtils.extendUrl( scUrl, "config_detailed.xml" ); var config = offlineExample.prepareConfig( new String [] {cfUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setAverageColdEmissionFactorsFile("../sample_41_EFA_ColdStart_vehcat_2020average.csv"); @@ -168,7 +167,7 @@ public final void testDetailed_vehTypeV2_FallbackToAverage() { } @Test - public final void testDetailed_vehTypeV2_HBEFA4_FallbackToAverage() { + final void testDetailed_vehTypeV2_HBEFA4_FallbackToAverage() { RunDetailedEmissionToolOfflineExample offlineExample = new RunDetailedEmissionToolOfflineExample(); // Config config = offlineExample.prepareConfig("./scenarios/sampleScenario/testv2_Vehv2/config_detailed.xml"); @@ -176,7 +175,7 @@ public final void testDetailed_vehTypeV2_HBEFA4_FallbackToAverage() { var cfUrl = IOUtils.extendUrl( scUrl, "config_detailed.xml" ); var config = offlineExample.prepareConfig( new String [] {cfUrl.toString()} ); - config.controler().setOutputDirectory(utils.getOutputDirectory()); + config.controller().setOutputDirectory(utils.getOutputDirectory()); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1.java index 0315a625693..1c16db00fa9 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1.java @@ -18,24 +18,22 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.junit.Assert.fail; - /** * @author nagel * */ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV1 { - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; /** * Test method for {@link RunDetailedEmissionToolOnlineExample#main(String[])}. @@ -48,15 +46,15 @@ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV1 { * * */ // @Test(expected=RuntimeException.class) // Expecting RuntimeException, because requested values are only in average file. Without fallback it has to fail! - @Ignore //Ignore this test, because the thrown exception during events handling does not always leads to an abort of the Simulation ->> Maybe a problem in @link{ParallelEventsManagerImpl.class}? + @Disabled //Ignore this test, because the thrown exception during events handling does not always leads to an abort of the Simulation ->> Maybe a problem in @link{ParallelEventsManagerImpl.class}? @Test - public final void testDetailed_vehTypeV1() { + final void testDetailed_vehTypeV1() { boolean gotAnException = false ; try { RunDetailedEmissionToolOnlineExample onlineExample = new RunDetailedEmissionToolOnlineExample(); Config config = onlineExample.prepareConfig( new String[]{"./scenarios/sampleScenario/testv2_Vehv1/config_detailed.xml"} ) ; - config.controler().setOutputDirectory( utils.getOutputDirectory() ); - config.controler().setLastIteration( 1 ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setLastIteration( 1 ); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.fromVehicleTypeDescription ); emissionsConfig.setDetailedVsAverageLookupBehavior( EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); @@ -65,7 +63,7 @@ public final void testDetailed_vehTypeV1() { } catch (Exception ee ) { gotAnException = true ; } - Assert.assertTrue( gotAnException ); + Assertions.assertTrue( gotAnException ); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage.java index 12eed58acea..8715b4525ed 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage.java @@ -18,8 +18,10 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Rule; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.config.Config; @@ -28,14 +30,12 @@ import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.junit.Assert.fail; - /** * @author nagel * */ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage { - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; /** * Test method for {@link RunDetailedEmissionToolOnlineExample#main(java.lang.String[])}. @@ -48,15 +48,15 @@ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV1FallbackToAverage { * * */ @Test - public final void testDetailed_vehTypeV1_FallbackToAverage() { + final void testDetailed_vehTypeV1_FallbackToAverage() { try { // Config config = onlineExample.prepareConfig( new String[]{"./scenarios/sampleScenario/testv2_Vehv1/config_detailed.xml"} ) ; var scenarioUrl = ExamplesUtils.getTestScenarioURL( "emissions-sampleScenario/testv2_Vehv1" ); var configUrl = IOUtils.extendUrl( scenarioUrl, "config_detailed.xml" ); Config config = RunDetailedEmissionToolOnlineExample.prepareConfig( new String [] { configUrl.toString() } ); - config.controler().setOutputDirectory( utils.getOutputDirectory() ); - config.controler().setLastIteration( 1 ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setLastIteration( 1 ); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setHbefaVehicleDescriptionSource( EmissionsConfigGroup.HbefaVehicleDescriptionSource.fromVehicleTypeDescription ); emissionsConfig.setDetailedVsAverageLookupBehavior( diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2.java index 42caf0ed295..95cbc87199b 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2.java @@ -18,39 +18,37 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.junit.Assert.fail; - /** * @author nagel * */ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV2 { - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; /** * Test method for {@link RunDetailedEmissionToolOnlineExample#main(String[])}. */ // @Test(expected=RuntimeException.class) // Expecting RuntimeException, because requested values are only in average file. Without fallback it has to fail! - @Ignore //Ignore this test, because the thrown exception during events handling does not always leads to an abort of the Simulation ->> Maybe a problem in @link{ParallelEventsManagerImpl.class}? + @Disabled //Ignore this test, because the thrown exception during events handling does not always leads to an abort of the Simulation ->> Maybe a problem in @link{ParallelEventsManagerImpl.class}? @Test - public final void testDetailed_vehTypeV2() { + final void testDetailed_vehTypeV2() { boolean gotAnException = false ; try { RunDetailedEmissionToolOnlineExample onlineExample = new RunDetailedEmissionToolOnlineExample(); Config config = onlineExample.prepareConfig( new String[]{"./scenarios/sampleScenario/testv2_Vehv2/config_detailed.xml"} ) ; - config.controler().setOutputDirectory( utils.getOutputDirectory() ); - config.controler().setLastIteration( 1 ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setLastIteration( 1 ); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setDetailedVsAverageLookupBehavior( EmissionsConfigGroup.DetailedVsAverageLookupBehavior.onlyTryDetailedElseAbort ); Scenario scenario = onlineExample.prepareScenario( config ) ; @@ -58,7 +56,7 @@ public final void testDetailed_vehTypeV2() { } catch (Exception ee ) { gotAnException = true ; } - Assert.assertTrue( gotAnException ); + Assertions.assertTrue( gotAnException ); } } diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2FallbackToAverage.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2FallbackToAverage.java index 5afbeb1337e..ef667425698 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2FallbackToAverage.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/example/RunDetailedEmissionToolOnlineExampleIT_vehTypeV2FallbackToAverage.java @@ -18,8 +18,10 @@ * *********************************************************************** */ package org.matsim.contrib.emissions.example; -import org.junit.Rule; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup.DetailedVsAverageLookupBehavior; @@ -29,20 +31,18 @@ import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; -import static org.junit.Assert.fail; - /** * @author nagel * */ public class RunDetailedEmissionToolOnlineExampleIT_vehTypeV2FallbackToAverage { - @Rule public MatsimTestUtils utils = new MatsimTestUtils() ; + @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils() ; /** * Test method for {@link RunDetailedEmissionToolOnlineExample#main(String[])}. */ @Test - public final void testDetailed_vehTypeV2_FallbackToAverage() { + final void testDetailed_vehTypeV2_FallbackToAverage() { try { // RunDetailedEmissionToolOnlineExample onlineExample = new RunDetailedEmissionToolOnlineExample(); @@ -51,8 +51,8 @@ public final void testDetailed_vehTypeV2_FallbackToAverage() { var configUrl = IOUtils.extendUrl( scenarioUrl, "config_detailed.xml" ); Config config = RunDetailedEmissionToolOnlineExample.prepareConfig( new String [] { configUrl.toString() } ); - config.controler().setOutputDirectory( utils.getOutputDirectory() ); - config.controler().setLastIteration( 1 ); + config.controller().setOutputDirectory( utils.getOutputDirectory() ); + config.controller().setLastIteration( 1 ); EmissionsConfigGroup emissionsConfig = ConfigUtils.addOrGetModule( config, EmissionsConfigGroup.class ); emissionsConfig.setDetailedVsAverageLookupBehavior( DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable ); //This is the previous behaviour -> Test only passes if falling back to average table :( diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/utils/EmissionUtilsTest.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/utils/EmissionUtilsTest.java index 77aca8075f1..4f20dfbf78f 100644 --- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/utils/EmissionUtilsTest.java +++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/utils/EmissionUtilsTest.java @@ -20,8 +20,8 @@ package org.matsim.contrib.emissions.utils; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -43,6 +43,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.matsim.contrib.emissions.Pollutant.*; @@ -80,7 +81,7 @@ public static Map createUntypedEmissions() { } @Test - public final void testSumUpEmissions() { + final void testSumUpEmissions() { // test the method EmissionUtils.sumUpEmissions for a complete list of pollutants // missing data is not tested here @@ -123,19 +124,19 @@ public final void testSumUpEmissions() { Double pmv = sum.get( PM ); Double sov = sum.get(SO2); - Assert.assertEquals("Value of CO should be " + (wcov + ccov), cov, wcov + ccov, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of CO2_TOTAL should be " + wc2v, c2v, wc2v, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of FC should be " + (wfcv + cfcv), fcv, wfcv + cfcv, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of HC should be " + (whcv + chcv), hcv, whcv + chcv, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of NMHC should be " + (wnmv + cnmv), nmv, wnmv + cnmv, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of NO2 should be " + (wn2v + cn2v), n2v, wn2v + cn2v, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of NOx should be " + (wnxv + cnxv), nxv, wnxv + cnxv, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of PM should be ." + (wpmv + cpmv), pmv, wpmv + cpmv, MatsimTestUtils.EPSILON); - Assert.assertEquals("Value of SO2 should be " + wsov, sov, wsov, MatsimTestUtils.EPSILON); + Assertions.assertEquals(cov, wcov + ccov, MatsimTestUtils.EPSILON, "Value of CO should be " + (wcov + ccov)); + Assertions.assertEquals(c2v, wc2v, MatsimTestUtils.EPSILON, "Value of CO2_TOTAL should be " + wc2v); + Assertions.assertEquals(fcv, wfcv + cfcv, MatsimTestUtils.EPSILON, "Value of FC should be " + (wfcv + cfcv)); + Assertions.assertEquals(hcv, whcv + chcv, MatsimTestUtils.EPSILON, "Value of HC should be " + (whcv + chcv)); + Assertions.assertEquals(nmv, wnmv + cnmv, MatsimTestUtils.EPSILON, "Value of NMHC should be " + (wnmv + cnmv)); + Assertions.assertEquals(n2v, wn2v + cn2v, MatsimTestUtils.EPSILON, "Value of NO2 should be " + (wn2v + cn2v)); + Assertions.assertEquals(nxv, wnxv + cnxv, MatsimTestUtils.EPSILON, "Value of NOx should be " + (wnxv + cnxv)); + Assertions.assertEquals(pmv, wpmv + cpmv, MatsimTestUtils.EPSILON, "Value of PM should be ." + (wpmv + cpmv)); + Assertions.assertEquals(sov, wsov, MatsimTestUtils.EPSILON, "Value of SO2 should be " + wsov); } @Test - public final void testSumUpEmissionsPerId() { + final void testSumUpEmissionsPerId() { Map, Map> warmEmissions = new HashMap<>(); Map, Map> coldEmissions = new HashMap<>(); @@ -234,39 +235,42 @@ public final void testSumUpEmissionsPerId() { double a2so = sums.get(Id.create("id2", Person.class)).get(SO2); //assures simultaneously that persons/ids are distinguished correctly - Assert.assertEquals("CO value of person 1 should be" +e1co +"but is ", e1co, a1co, MatsimTestUtils.EPSILON); - Assert.assertEquals("CO2 value of person 1 should be" + e1c2 + "but is ", e1c2, a1c2, MatsimTestUtils.EPSILON); - Assert.assertEquals("FC value of person 1 should be" + e1fc + "but is ", e1fc, a1fc, MatsimTestUtils.EPSILON); - Assert.assertEquals("HC value of person 1 should be" + e1hc + "but is ", e1hc, a1hc, MatsimTestUtils.EPSILON); - Assert.assertEquals("NMHC value of person 1 should be" + e1nm + "but is ", e1nm, a1nm, MatsimTestUtils.EPSILON); - Assert.assertEquals("NO2 value of person 1 should be" + e1n2 + "but is ", e1n2, a1n2, MatsimTestUtils.EPSILON); - Assert.assertEquals("NOx value of person 1 should be" + e1nx + "but is ", e1nx, a1nx, MatsimTestUtils.EPSILON); - Assert.assertEquals("PM value of person 1 should be" + e1pm + "but is ", e1pm, a1pm, MatsimTestUtils.EPSILON); - Assert.assertEquals("SO value of person 1 should be" + e1so + "but is ", e1so, a1so, MatsimTestUtils.EPSILON); - - Assert.assertEquals("CO value of person 2 should be" + e2co + "but is ", e2co, a2co, MatsimTestUtils.EPSILON); - Assert.assertEquals("CO2 value of person 2 should be" + e2c2 + "but is ", e2c2, a2c2, MatsimTestUtils.EPSILON); - Assert.assertEquals("FC value of person 2 should be" + e2fc + "but is ", e2fc, a2fc, MatsimTestUtils.EPSILON); - Assert.assertEquals("HC value of person 2 should be" + e2hc + "but is ", e2hc, a2hc, MatsimTestUtils.EPSILON); - Assert.assertEquals("NMHC value of person 2 should be" + e2nm + "but is ", e2nm, a2nm, MatsimTestUtils.EPSILON); - Assert.assertEquals("NO2 value of person 2 should be" + e2n2 + "but is ", e2n2, a2n2, MatsimTestUtils.EPSILON); - Assert.assertEquals("NOx value of person 2 should be" + e2nx + "but is ", e2nx, a2nx, MatsimTestUtils.EPSILON); - Assert.assertEquals("PM value of person 2 should be" + e2pm + "but is ", e2pm, a2pm, MatsimTestUtils.EPSILON); - Assert.assertEquals("SO value of person 2 should be" + e2so + "but is ", e2so, a2so, MatsimTestUtils.EPSILON); + Assertions.assertEquals(e1co, a1co, MatsimTestUtils.EPSILON, "CO value of person 1 should be" +e1co +"but is "); + Assertions.assertEquals(e1c2, a1c2, MatsimTestUtils.EPSILON, "CO2 value of person 1 should be" + e1c2 + "but is "); + Assertions.assertEquals(e1fc, a1fc, MatsimTestUtils.EPSILON, "FC value of person 1 should be" + e1fc + "but is "); + Assertions.assertEquals(e1hc, a1hc, MatsimTestUtils.EPSILON, "HC value of person 1 should be" + e1hc + "but is "); + Assertions.assertEquals(e1nm, a1nm, MatsimTestUtils.EPSILON, "NMHC value of person 1 should be" + e1nm + "but is "); + Assertions.assertEquals(e1n2, a1n2, MatsimTestUtils.EPSILON, "NO2 value of person 1 should be" + e1n2 + "but is "); + Assertions.assertEquals(e1nx, a1nx, MatsimTestUtils.EPSILON, "NOx value of person 1 should be" + e1nx + "but is "); + Assertions.assertEquals(e1pm, a1pm, MatsimTestUtils.EPSILON, "PM value of person 1 should be" + e1pm + "but is "); + Assertions.assertEquals(e1so, a1so, MatsimTestUtils.EPSILON, "SO value of person 1 should be" + e1so + "but is "); + + Assertions.assertEquals(e2co, a2co, MatsimTestUtils.EPSILON, "CO value of person 2 should be" + e2co + "but is "); + Assertions.assertEquals(e2c2, a2c2, MatsimTestUtils.EPSILON, "CO2 value of person 2 should be" + e2c2 + "but is "); + Assertions.assertEquals(e2fc, a2fc, MatsimTestUtils.EPSILON, "FC value of person 2 should be" + e2fc + "but is "); + Assertions.assertEquals(e2hc, a2hc, MatsimTestUtils.EPSILON, "HC value of person 2 should be" + e2hc + "but is "); + Assertions.assertEquals(e2nm, a2nm, MatsimTestUtils.EPSILON, "NMHC value of person 2 should be" + e2nm + "but is "); + Assertions.assertEquals(e2n2, a2n2, MatsimTestUtils.EPSILON, "NO2 value of person 2 should be" + e2n2 + "but is "); + Assertions.assertEquals(e2nx, a2nx, MatsimTestUtils.EPSILON, "NOx value of person 2 should be" + e2nx + "but is "); + Assertions.assertEquals(e2pm, a2pm, MatsimTestUtils.EPSILON, "PM value of person 2 should be" + e2pm + "but is "); + Assertions.assertEquals(e2so, a2so, MatsimTestUtils.EPSILON, "SO value of person 2 should be" + e2so + "but is "); } - @Test(expected = NullPointerException.class) - public final void testGetTotalEmissions_nullInput() { + @Test + final void testGetTotalEmissions_nullInput() { + assertThrows(NullPointerException.class, () -> { + + @SuppressWarnings("ConstantConditions") + SortedMap totalEmissions = EmissionUtils.getTotalEmissions(null); + Assertions.fail("Expected NullPointerException, got none."); - @SuppressWarnings("ConstantConditions") - SortedMap totalEmissions = EmissionUtils.getTotalEmissions(null); - Assert.fail("Expected NullPointerException, got none."); + }); } @Test - public final void testGetTotalEmissions_emptyList() { + final void testGetTotalEmissions_emptyList() { //test an empty list as input SortedMap totalEmissions; @@ -274,11 +278,11 @@ public final void testGetTotalEmissions_emptyList() { //test empty list as input totalEmissions = EmissionUtils.getTotalEmissions(persons2emissions); - Assert.assertEquals("this map should be empty", 0, totalEmissions.size()); + Assertions.assertEquals(0, totalEmissions.size(), "this map should be empty"); } @Test - public final void testGetTotalEmissions_completeData() { + final void testGetTotalEmissions_completeData() { //test getTotalEmissions for complete data Set pollsFromEU = new HashSet<>(Arrays.asList(CO, CO2_TOTAL, FC, HC, NMHC, NOx, NO2, PM, SO2)); @@ -338,27 +342,27 @@ public final void testGetTotalEmissions_completeData() { persons2emissions.put(p3Id, allEmissionsp3); totalEmissions = EmissionUtils.getTotalEmissions(persons2emissions); - Assert.assertEquals(CO + " values are not correct", p1co + p2co + p3co, totalEmissions.get(CO), MatsimTestUtils.EPSILON); - Assert.assertEquals(CO2_TOTAL + " values are not correct", p1c2 + p2c2 + p3c2, totalEmissions.get(CO2_TOTAL), MatsimTestUtils.EPSILON); - Assert.assertEquals(FC + " values are not correct", p1fc + p2fc + p3fc, totalEmissions.get(FC), MatsimTestUtils.EPSILON); - Assert.assertEquals(HC + " values are not correct", p1hc + p2hc + p3hc, totalEmissions.get(HC), MatsimTestUtils.EPSILON); - Assert.assertEquals(NMHC + " values are not correct", p1nm + p2nm + p3nm, totalEmissions.get(NMHC), MatsimTestUtils.EPSILON); - Assert.assertEquals(NO2 + " values are not correct", p1n2 + p2n2 + p3n2, totalEmissions.get(NO2), MatsimTestUtils.EPSILON); - Assert.assertEquals(NOx + " values are not correct", p1nx + p2nx + p3nx, totalEmissions.get(NOx), MatsimTestUtils.EPSILON); - Assert.assertEquals(PM + " values are not correct", p1pm + p2pm + p3pm, totalEmissions.get(PM), MatsimTestUtils.EPSILON); - Assert.assertEquals(SO2 + " values are not correct", p1so + p2so + p3so, totalEmissions.get(SO2), MatsimTestUtils.EPSILON); + Assertions.assertEquals(p1co + p2co + p3co, totalEmissions.get(CO), MatsimTestUtils.EPSILON, CO + " values are not correct"); + Assertions.assertEquals(p1c2 + p2c2 + p3c2, totalEmissions.get(CO2_TOTAL), MatsimTestUtils.EPSILON, CO2_TOTAL + " values are not correct"); + Assertions.assertEquals(p1fc + p2fc + p3fc, totalEmissions.get(FC), MatsimTestUtils.EPSILON, FC + " values are not correct"); + Assertions.assertEquals(p1hc + p2hc + p3hc, totalEmissions.get(HC), MatsimTestUtils.EPSILON, HC + " values are not correct"); + Assertions.assertEquals(p1nm + p2nm + p3nm, totalEmissions.get(NMHC), MatsimTestUtils.EPSILON, NMHC + " values are not correct"); + Assertions.assertEquals(p1n2 + p2n2 + p3n2, totalEmissions.get(NO2), MatsimTestUtils.EPSILON, NO2 + " values are not correct"); + Assertions.assertEquals(p1nx + p2nx + p3nx, totalEmissions.get(NOx), MatsimTestUtils.EPSILON, NOx + " values are not correct"); + Assertions.assertEquals(p1pm + p2pm + p3pm, totalEmissions.get(PM), MatsimTestUtils.EPSILON, PM + " values are not correct"); + Assertions.assertEquals(p1so + p2so + p3so, totalEmissions.get(SO2), MatsimTestUtils.EPSILON, SO2 + " values are not correct"); // assume that all maps are complete for (Pollutant emission : pollsFromEU) { - Assert.assertTrue(totalEmissions.containsKey(emission)); + Assertions.assertTrue(totalEmissions.containsKey(emission)); } // nothing else in the list - Assert.assertEquals("this list should be as long as number of pollutants", totalEmissions.keySet().size(), pollsFromEU.size()); + Assertions.assertEquals(totalEmissions.keySet().size(), pollsFromEU.size(), "this list should be as long as number of pollutants"); } - + @Test - public final void testSetNonCalculatedEmissionsForPopulation_completeData(){ + final void testSetNonCalculatedEmissionsForPopulation_completeData(){ //test setNonCalculatedEmissionsForPopulation for three persons with complete lists of emissions //check values @@ -417,57 +421,56 @@ public final void testSetNonCalculatedEmissionsForPopulation_completeData(){ Map, SortedMap> finalMap = EmissionUtils.setNonCalculatedEmissionsForPopulation(pop, totalEmissions, pollsFromEU); //check: all persons added to the population are contained in the finalMap - Assert.assertTrue("the calculated map should contain person 1", finalMap.containsKey(idp1)); - Assert.assertTrue("the calculated map should contain person 2", finalMap.containsKey(idp2)); + Assertions.assertTrue(finalMap.containsKey(idp1), "the calculated map should contain person 1"); + Assertions.assertTrue(finalMap.containsKey(idp2), "the calculated map should contain person 2"); //nothing else in the finalMap - Assert.assertEquals("the calculated map should contain two persons but contains "+ - finalMap.size() + "persons." ,pop.getPersons().keySet().size(), finalMap.size()); + Assertions.assertEquals(pop.getPersons().keySet().size(), finalMap.size(), "the calculated map should contain two persons but contains "+ + finalMap.size() + "persons."); //check: all values for person 1 and 2 are not null or zero // and of type double for(Object id : finalMap.keySet()) { - Assert.assertTrue(id instanceof Id); + Assertions.assertTrue(id instanceof Id); for (Object pollutant : finalMap.get(id).values()) { - Assert.assertSame(pollutant.getClass(), Double.class); - Assert.assertNotSame(0.0, pollutant); - Assert.assertNotNull(pollutant); + Assertions.assertSame(pollutant.getClass(), Double.class); + Assertions.assertNotSame(0.0, pollutant); + Assertions.assertNotNull(pollutant); } //check: all emission types appear for (Pollutant emission : pollsFromEU) { - Assert.assertTrue(finalMap.get(id).containsKey(emission)); + Assertions.assertTrue(finalMap.get(id).containsKey(emission)); } //nothing else in the list int numOfPolls = pollsFromEU.size(); - Assert.assertEquals("the number of pullutants is " + finalMap.get(id).keySet().size() + " but should be" + numOfPolls, - numOfPolls, finalMap.get(id).keySet().size()); + Assertions.assertEquals(numOfPolls, finalMap.get(id).keySet().size(), "the number of pullutants is " + finalMap.get(id).keySet().size() + " but should be" + numOfPolls); } //check: values for all emissions are correct -person 1 - Assert.assertEquals("CO value for person 1 is not correct", cov1, finalMap.get(idp1).get( CO ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("CO2 value for person 1 is not correct", c2v1, finalMap.get(idp1).get( CO2_TOTAL ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("FC value for person 1 is not correct", fcv1, finalMap.get(idp1).get( FC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("HC value for person 1 is not correct", hcv1, finalMap.get(idp1).get( HC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NMHC value for person 1 is not correct", nmv1, finalMap.get(idp1).get( NMHC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NO2 value for person 1 is not correct", n2v1, finalMap.get(idp1).get( NO2 ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NOx value for person 1 is not correct", nxv1, finalMap.get(idp1).get( NOx ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("PM value for person 1 is not correct", pmv1, finalMap.get(idp1).get( PM ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("SO value for person 1 is not correct", sov1, finalMap.get(idp1).get( SO2 ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(cov1, finalMap.get(idp1).get( CO ), MatsimTestUtils.EPSILON, "CO value for person 1 is not correct" ); + Assertions.assertEquals(c2v1, finalMap.get(idp1).get( CO2_TOTAL ), MatsimTestUtils.EPSILON, "CO2 value for person 1 is not correct" ); + Assertions.assertEquals(fcv1, finalMap.get(idp1).get( FC ), MatsimTestUtils.EPSILON, "FC value for person 1 is not correct" ); + Assertions.assertEquals(hcv1, finalMap.get(idp1).get( HC ), MatsimTestUtils.EPSILON, "HC value for person 1 is not correct" ); + Assertions.assertEquals(nmv1, finalMap.get(idp1).get( NMHC ), MatsimTestUtils.EPSILON, "NMHC value for person 1 is not correct" ); + Assertions.assertEquals(n2v1, finalMap.get(idp1).get( NO2 ), MatsimTestUtils.EPSILON, "NO2 value for person 1 is not correct" ); + Assertions.assertEquals(nxv1, finalMap.get(idp1).get( NOx ), MatsimTestUtils.EPSILON, "NOx value for person 1 is not correct" ); + Assertions.assertEquals(pmv1, finalMap.get(idp1).get( PM ), MatsimTestUtils.EPSILON, "PM value for person 1 is not correct" ); + Assertions.assertEquals(sov1, finalMap.get(idp1).get( SO2 ), MatsimTestUtils.EPSILON, "SO value for person 1 is not correct" ); //check: values for all emissions are correct -person 2 - Assert.assertEquals("CO value for person 2 is not correct", cov2, finalMap.get(idp2).get( CO ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("CO2 value for person 2 is not correct", c2v2, finalMap.get(idp2).get( CO2_TOTAL ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("FC value for person 2 is not correct", fcv2, finalMap.get(idp2).get( FC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("HC value for person 2 is not correct", hcv2, finalMap.get(idp2).get( HC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NMHC value for person 2 is not correct", nmv2, finalMap.get(idp2).get( NMHC ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NO2 value for person 2 is not correct", n2v2, finalMap.get(idp2).get( NO2 ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("NOx value for person 2 is not correct", nxv2, finalMap.get(idp2).get( NOx ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("PM value for person 2 is not correct", pmv2, finalMap.get(idp2).get( PM ), MatsimTestUtils.EPSILON ); - Assert.assertEquals("SO value for person 2 is not correct", sov2, finalMap.get(idp2).get( SO2 ), MatsimTestUtils.EPSILON ); + Assertions.assertEquals(cov2, finalMap.get(idp2).get( CO ), MatsimTestUtils.EPSILON, "CO value for person 2 is not correct" ); + Assertions.assertEquals(c2v2, finalMap.get(idp2).get( CO2_TOTAL ), MatsimTestUtils.EPSILON, "CO2 value for person 2 is not correct" ); + Assertions.assertEquals(fcv2, finalMap.get(idp2).get( FC ), MatsimTestUtils.EPSILON, "FC value for person 2 is not correct" ); + Assertions.assertEquals(hcv2, finalMap.get(idp2).get( HC ), MatsimTestUtils.EPSILON, "HC value for person 2 is not correct" ); + Assertions.assertEquals(nmv2, finalMap.get(idp2).get( NMHC ), MatsimTestUtils.EPSILON, "NMHC value for person 2 is not correct" ); + Assertions.assertEquals(n2v2, finalMap.get(idp2).get( NO2 ), MatsimTestUtils.EPSILON, "NO2 value for person 2 is not correct" ); + Assertions.assertEquals(nxv2, finalMap.get(idp2).get( NOx ), MatsimTestUtils.EPSILON, "NOx value for person 2 is not correct" ); + Assertions.assertEquals(pmv2, finalMap.get(idp2).get( PM ), MatsimTestUtils.EPSILON, "PM value for person 2 is not correct" ); + Assertions.assertEquals(sov2, finalMap.get(idp2).get( SO2 ), MatsimTestUtils.EPSILON, "SO value for person 2 is not correct" ); } - + @Test - public final void testSetNonCalculatedEmissionsForPopulation_missingMap() { + final void testSetNonCalculatedEmissionsForPopulation_missingMap() { setUpForNonCaculatedEmissions(); @@ -478,25 +481,25 @@ public final void testSetNonCalculatedEmissionsForPopulation_missingMap() { Map, SortedMap> finalMap = EmissionUtils.setNonCalculatedEmissionsForPopulation(pop, totalEmissions, pollsFromEU); //check: person 3 is contained in the finalMap - Assert.assertTrue("the calculated map should contain person 3", finalMap.containsKey(idp3)); + Assertions.assertTrue(finalMap.containsKey(idp3), "the calculated map should contain person 3"); //nothing else in the finalMap message = "the calculated map should contain " + pop.getPersons().size() + " person(s) but contains " + finalMap.keySet().size() + "person(s)."; - Assert.assertEquals(message, pop.getPersons().keySet().size(), finalMap.keySet().size()); + Assertions.assertEquals(pop.getPersons().keySet().size(), finalMap.keySet().size(), message); //check: all values for the this person are zero and of type double for (Object pollutant : finalMap.get(idp3).values()) { - Assert.assertSame(pollutant.getClass(), Double.class); - Assert.assertEquals(0.0, (Double) pollutant, MatsimTestUtils.EPSILON); - Assert.assertNotNull(pollutant); + Assertions.assertSame(pollutant.getClass(), Double.class); + Assertions.assertEquals(0.0, (Double) pollutant, MatsimTestUtils.EPSILON); + Assertions.assertNotNull(pollutant); } //check: all types of emissions appear for (Pollutant emission : pollsFromEU) { - Assert.assertTrue(finalMap.get(idp3).containsKey(emission)); + Assertions.assertTrue(finalMap.get(idp3).containsKey(emission)); } //nothing else in the list int numOfPolls = pollsFromEU.size(); message = "the number of pullutants is " + finalMap.get(idp3).keySet().size() + " but should be" + numOfPolls; - Assert.assertEquals(message, numOfPolls, finalMap.get(idp3).keySet().size()); + Assertions.assertEquals(numOfPolls, finalMap.get(idp3).keySet().size(), message); } @@ -512,7 +515,7 @@ private void setUpForNonCaculatedEmissions() { } @Test - public final void testSetNonCalculatedEmissionsForPopulation_missingPerson() { + final void testSetNonCalculatedEmissionsForPopulation_missingPerson() { setUpForNonCaculatedEmissions(); @@ -538,15 +541,15 @@ public final void testSetNonCalculatedEmissionsForPopulation_missingPerson() { Map, SortedMap> finalMap = EmissionUtils.setNonCalculatedEmissionsForPopulation(pop, totalEmissions, pollsFromEU); //check: all persons added to the population are contained in the finalMap - Assert.assertFalse("the calculated map should not contain person 4", finalMap.containsKey(idp4)); + Assertions.assertFalse(finalMap.containsKey(idp4), "the calculated map should not contain person 4"); //nothing else in the finalMap message = "the calculated map should contain " + pop.getPersons().size() + " person(s) but contains " + finalMap.keySet().size() + "person(s)."; - Assert.assertEquals(message, pop.getPersons().keySet().size(), finalMap.keySet().size()); + Assertions.assertEquals(pop.getPersons().keySet().size(), finalMap.keySet().size(), message); } - + @Test - public final void testSetNonCalculatedEmissionsForPopulation_nullEmissions(){ + final void testSetNonCalculatedEmissionsForPopulation_nullEmissions(){ //test setNonCalculatedEmissionsForPopulation with 'null' // throw nullpointer exception setUpForNonCaculatedEmissions(); @@ -564,11 +567,11 @@ public final void testSetNonCalculatedEmissionsForPopulation_nullEmissions(){ } catch (NullPointerException e) { nullPointerEx = true; } - Assert.assertTrue(nullPointerEx); + Assertions.assertTrue(nullPointerEx); } - + @Test - public final void testSetNonCalculatedEmissionsForPopulation_emptyPopulation(){ + final void testSetNonCalculatedEmissionsForPopulation_emptyPopulation(){ // test setNonCalculatedEmissionsForPopulation with an empty population // empty list should be returned setUpForNonCaculatedEmissions(); @@ -594,12 +597,12 @@ public final void testSetNonCalculatedEmissionsForPopulation_emptyPopulation(){ //nothing in the finalMap message = "the calculated map should contain " + pop.getPersons().size() + " person(s) but contains " + finalMap.keySet().size() + "person(s)."; - Assert.assertEquals(message, pop.getPersons().keySet().size(), finalMap.keySet().size()); + Assertions.assertEquals(pop.getPersons().keySet().size(), finalMap.keySet().size(), message); } @Test - public final void testSetNonCalculatedEmissionsForPopulation_emptyEmissionMap() { + final void testSetNonCalculatedEmissionsForPopulation_emptyEmissionMap() { //test setNonCalculatedEmissionsForPopulation with an empty emission map setUpForNonCaculatedEmissions(); @@ -614,28 +617,26 @@ public final void testSetNonCalculatedEmissionsForPopulation_emptyEmissionMap() Map, SortedMap> finalMap = EmissionUtils.setNonCalculatedEmissionsForPopulation(pop, totalEmissions, pollsFromEU); //check: all persons added to the population are contained in the finalMap - Assert.assertTrue("the calculated map should contain person 5", finalMap.containsKey(idp5)); - Assert.assertTrue("the calculated map should contain person 6", finalMap.containsKey(idp6)); + Assertions.assertTrue(finalMap.containsKey(idp5), "the calculated map should contain person 5"); + Assertions.assertTrue(finalMap.containsKey(idp6), "the calculated map should contain person 6"); //nothing else in the finalMap message = "the calculated map should contain " + pop.getPersons().size() + " person(s) but contains " + finalMap.keySet().size() + "person(s)."; - Assert.assertEquals(message, pop.getPersons().keySet().size(), finalMap.keySet().size()); + Assertions.assertEquals(pop.getPersons().keySet().size(), finalMap.keySet().size(), message); //check: all values for all persons are zero and of type double for (Id id : finalMap.keySet()) { for (Object pollutant : finalMap.get(id).values()) { - Assert.assertSame(pollutant.getClass(), Double.class); - Assert.assertEquals("map of pollutants was missing. Therefore all values should be set to zero.", - 0.0, (Double) pollutant, MatsimTestUtils.EPSILON); - Assert.assertNotNull(pollutant); + Assertions.assertSame(pollutant.getClass(), Double.class); + Assertions.assertEquals(0.0, (Double) pollutant, MatsimTestUtils.EPSILON, "map of pollutants was missing. Therefore all values should be set to zero."); + Assertions.assertNotNull(pollutant); } //check: alle types of emissions appear for (Pollutant emission : pollsFromEU) { - Assert.assertTrue(finalMap.get(id).containsKey(emission)); + Assertions.assertTrue(finalMap.get(id).containsKey(emission)); } //nothing else in the list int numOfPolls = pollsFromEU.size(); - Assert.assertEquals("the number of pullutants is " + finalMap.get(id).keySet().size() + " but should be" + numOfPolls, - numOfPolls, finalMap.get(id).keySet().size()); + Assertions.assertEquals(numOfPolls, finalMap.get(id).keySet().size(), "the number of pullutants is " + finalMap.get(id).keySet().size() + " but should be" + numOfPolls); } @@ -643,7 +644,7 @@ public final void testSetNonCalculatedEmissionsForPopulation_emptyEmissionMap() } @Test - public final void testSetNonCalculatedEmissionsForNetwork() { + final void testSetNonCalculatedEmissionsForNetwork() { //test setNonCalculatedEmissionsForNetwork // network consists of four nodes 1,2,3,4 // and six links 12, 13, 14, 23, 24, 34 @@ -728,64 +729,64 @@ public final void testSetNonCalculatedEmissionsForNetwork() { Id linkId = link.getId(); - Assert.assertTrue(totalEmissionsFilled.containsKey(linkId)); + Assertions.assertTrue(totalEmissionsFilled.containsKey(linkId)); SortedMap emissionMapForLink = totalEmissionsFilled.get(linkId); for (Pollutant pollutant : pollsFromEU) { System.out.println("pollutant: " + pollutant + "; linkId: " + linkId); - Assert.assertTrue(pollutant + "not found for link " + linkId.toString(), - emissionMapForLink.containsKey(pollutant)); - Assert.assertEquals(Double.class, emissionMapForLink.get(pollutant).getClass()); + Assertions.assertTrue(emissionMapForLink.containsKey(pollutant), + pollutant + "not found for link " + linkId.toString()); + Assertions.assertEquals(Double.class, emissionMapForLink.get(pollutant).getClass()); } } //check values //link 12 and 13 - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( CO2_TOTAL ), c2link12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( CO ), colink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( FC ), fclink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( HC ), hclink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( NMHC ), nmlink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( NO2 ), n2link12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( NOx ), nxlink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( PM ), pmlink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link12id).get( SO2 ), solink12v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( CO2_TOTAL ), c2link13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( CO ), colink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( FC ), fclink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( HC ), hclink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( NMHC ), nmlink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( NO2 ), n2link13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( NOx ), nxlink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( PM ), pmlink13v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link13id).get( SO2 ), solink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( CO2_TOTAL ), c2link12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( CO ), colink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( FC ), fclink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( HC ), hclink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( NMHC ), nmlink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( NO2 ), n2link12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( NOx ), nxlink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( PM ), pmlink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link12id).get( SO2 ), solink12v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( CO2_TOTAL ), c2link13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( CO ), colink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( FC ), fclink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( HC ), hclink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( NMHC ), nmlink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( NO2 ), n2link13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( NOx ), nxlink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( PM ), pmlink13v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link13id).get( SO2 ), solink13v, MatsimTestUtils.EPSILON ); //link 14 and 34 for(Pollutant pollutant: pollsFromEU){ - Assert.assertEquals(totalEmissionsFilled.get(link14id).get(pollutant), .0, MatsimTestUtils.EPSILON); - Assert.assertEquals(totalEmissionsFilled.get(link34id).get(pollutant), .0, MatsimTestUtils.EPSILON); + Assertions.assertEquals(totalEmissionsFilled.get(link14id).get(pollutant), .0, MatsimTestUtils.EPSILON); + Assertions.assertEquals(totalEmissionsFilled.get(link34id).get(pollutant), .0, MatsimTestUtils.EPSILON); } //link 23 - partial - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( CO2_TOTAL ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( CO ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( FC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( HC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( NMHC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( NO2 ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( NOx ), nxlink23v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( PM ), pmlink23v, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link23id).get( SO2 ), solink23v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( CO2_TOTAL ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( CO ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( FC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( HC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( NMHC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( NO2 ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( NOx ), nxlink23v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( PM ), pmlink23v, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link23id).get( SO2 ), solink23v, MatsimTestUtils.EPSILON ); //link 24 - empty - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( CO2_TOTAL ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( CO ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( FC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( HC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( NMHC ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( NO2 ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( NOx ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( PM ), .0, MatsimTestUtils.EPSILON ); - Assert.assertEquals(totalEmissionsFilled.get(link24id).get( SO2 ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( CO2_TOTAL ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( CO ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( FC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( HC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( NMHC ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( NO2 ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( NOx ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( PM ), .0, MatsimTestUtils.EPSILON ); + Assertions.assertEquals(totalEmissionsFilled.get(link24id).get( SO2 ), .0, MatsimTestUtils.EPSILON ); } public static Map createEmissions() { diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/EvConfigGroup.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/EvConfigGroup.java index bbd9df9b87a..e7b96ab3ce7 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/EvConfigGroup.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/EvConfigGroup.java @@ -48,6 +48,11 @@ public static EvConfigGroup get(Config config) { @Comment("Minimum activity duration for charging. Used in EvNetwork Routing.") public int minimumChargeTime = 1200; + @Parameter("enforceChargingInteractionDuration") + @Comment("If true, prolongs the charging interaction for the amount of time waiting in the charger queue (plus 1 second), i.e." + + "enforces that charging interactions are undertaken as long as initially planned (by EVNetworkRoutingModule). Default is false.") + public boolean enforceChargingInteractionDuration = false; + @Parameter @Comment("Location of the chargers file") @NotNull diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/EvModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/EvModule.java index d788a7823bd..233f3556bce 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/EvModule.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/EvModule.java @@ -19,6 +19,7 @@ package org.matsim.contrib.ev; +import com.google.inject.Inject; import com.google.inject.Singleton; import org.matsim.contrib.ev.charging.VehicleChargingHandler; import org.matsim.core.controler.AbstractModule; @@ -27,6 +28,9 @@ public class EvModule extends AbstractModule { public static final String EV_COMPONENT = "EV_COMPONENT"; + @Inject + private EvConfigGroup evCfg; + public EvModule(){} @Override @@ -36,7 +40,12 @@ public void install() { // this is not for DynVehicles. Does that mean that we cannot combine charging for normal vehicles with charging for eTaxis? Can't say ... kai, dec'22 installQSimModule(new AbstractQSimModule() { @Override protected void configureQSim() { - addMobsimScopeEventHandlerBinding().to( VehicleChargingHandler.class ).in( Singleton.class ); + bind(VehicleChargingHandler.class).in(Singleton.class); + addMobsimScopeEventHandlerBinding().to( VehicleChargingHandler.class); + if(evCfg.enforceChargingInteractionDuration){ + this.addQSimComponentBinding(EvModule.EV_COMPONENT).to(VehicleChargingHandler.class); + addMobsimListenerBinding().to(VehicleChargingHandler.class); + } } }); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingEventSequenceCollector.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingEventSequenceCollector.java index 29fdb95d679..efc703d7fc0 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingEventSequenceCollector.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingEventSequenceCollector.java @@ -20,20 +20,14 @@ package org.matsim.contrib.ev.charging; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import javax.annotation.Nullable; - +import com.google.common.base.Preconditions; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdMap; -import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.vehicles.Vehicle; -import com.google.common.base.Preconditions; +import javax.annotation.Nullable; +import java.util.*; +import java.util.stream.Collectors; /** * @author Michal Maciejewski (michalm) @@ -44,7 +38,11 @@ public class ChargingEventSequenceCollector public static class ChargingSequence { @Nullable //null if no queueing occurred private final QueuedAtChargerEvent queuedAtCharger; + @Nullable //null if queue was never quit early, i.e. if chargingStartEvent != null; + private QuitQueueAtChargerEvent quitQueueEvent; + @Nullable //null if queue was quit early, i.e. if QuitQueueAtChargerEvent != null; private ChargingStartEvent chargingStartEvent; + @Nullable //null if quitQueueEvent != null OR if charging was never completed private ChargingEndEvent chargingEndEvent; public ChargingSequence(@Nullable QueuedAtChargerEvent queuedAtCharger) { @@ -56,12 +54,19 @@ public Optional getQueuedAtCharger() { return Optional.ofNullable(queuedAtCharger); } - public ChargingStartEvent getChargingStart() { - return chargingStartEvent; + @Nullable + public Optional getQuitQueueAtChargerEvent() { + return Optional.ofNullable(quitQueueEvent); } - public ChargingEndEvent getChargingEnd() { - return chargingEndEvent; + @Nullable + public Optional getChargingStart() { + return Optional.ofNullable(chargingStartEvent); + } + + @Nullable + public Optional getChargingEnd() { + return Optional.ofNullable(chargingEndEvent); } } @@ -72,6 +77,10 @@ public List getCompletedSequences() { return Collections.unmodifiableList(completedSequences); } + public Set getOnGoingSequences() { + return ongoingSequences.values().stream().collect(Collectors.toUnmodifiableSet()); + } + @Override public void handleEvent(QueuedAtChargerEvent event) { Preconditions.checkState(ongoingSequences.put(event.getVehicleId(), new ChargingSequence(event)) == null, @@ -87,6 +96,7 @@ public void handleEvent(QuitQueueAtChargerEvent event) { event.getVehicleId(), event.getChargerId()); Preconditions.checkState(sequence.chargingStartEvent == null, "Vehicle (%s) is already plugged", event.getVehicleId(), event.getChargerId()); + sequence.quitQueueEvent = event; completedSequences.add(sequence); } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java index 5a5d829ee32..8cf57733532 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/ChargingWithQueueingLogic.java @@ -19,23 +19,15 @@ package org.matsim.contrib.ev.charging; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; - +import com.google.common.base.Preconditions; import org.matsim.api.core.v01.Id; import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.contrib.ev.infrastructure.ChargerSpecification; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.vehicles.Vehicle; -import com.google.common.base.Preconditions; +import java.util.*; +import java.util.concurrent.LinkedBlockingQueue; public class ChargingWithQueueingLogic implements ChargingLogic { protected final ChargerSpecification charger; @@ -73,6 +65,11 @@ public void chargeVehicles(double chargePeriod, double now) { } } + int queuedToPluggedCount = Math.min(queuedVehicles.size(), charger.getPlugCount() - pluggedVehicles.size()); + for (int i = 0; i < queuedToPluggedCount; i++) { + plugVehicle(queuedVehicles.poll(), now); + } + var arrivingVehiclesIter = arrivingVehicles.iterator(); while (arrivingVehiclesIter.hasNext()) { var ev = arrivingVehiclesIter.next(); @@ -83,11 +80,6 @@ public void chargeVehicles(double chargePeriod, double now) { } arrivingVehiclesIter.remove(); } - - int queuedToPluggedCount = Math.min(queuedVehicles.size(), charger.getPlugCount() - pluggedVehicles.size()); - for (int i = 0; i < queuedToPluggedCount; i++) { - plugVehicle(queuedVehicles.poll(), now); - } } @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java index d450afb6d24..196e3fd1b52 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java @@ -23,12 +23,9 @@ * This is an events based approach to trigger vehicle charging. Vehicles will be charged as soon as a person begins a charging activity. */ -import java.util.HashMap; -import java.util.List; -import java.util.Map; - +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableListMultimap; import jakarta.inject.Inject; - import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.ActivityEndEvent; import org.matsim.api.core.v01.events.ActivityStartEvent; @@ -37,17 +34,26 @@ import org.matsim.api.core.v01.events.handler.ActivityStartEventHandler; import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler; import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contrib.ev.EvConfigGroup; import org.matsim.contrib.ev.fleet.ElectricFleet; import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.contrib.ev.infrastructure.Charger; import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure; -import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; +import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils; +import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.events.MobsimScopeEventHandler; +import org.matsim.core.mobsim.framework.MobsimAgent; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; +import org.matsim.core.mobsim.qsim.QSim; +import org.matsim.core.mobsim.qsim.agents.WithinDayAgentUtils; import org.matsim.vehicles.Vehicle; -import com.google.common.collect.ImmutableListMultimap; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * This is an events based approach to trigger vehicle charging. Vehicles will be charged as soon as a person begins a charging activity. @@ -56,24 +62,29 @@ * (It may work together, but that would need to be tested. kai based on michal, dec'22) */ public class VehicleChargingHandler - implements ActivityStartEventHandler, ActivityEndEventHandler, PersonLeavesVehicleEventHandler, - ChargingEndEventHandler, MobsimScopeEventHandler { + implements ActivityStartEventHandler, ActivityEndEventHandler, PersonLeavesVehicleEventHandler, QueuedAtChargerEventHandler, ChargingStartEventHandler, + ChargingEndEventHandler, QuitQueueAtChargerEventHandler, + MobsimBeforeSimStepListener, MobsimScopeEventHandler { public static final String CHARGING_IDENTIFIER = " charging"; - public static final String CHARGING_INTERACTION = PlanCalcScoreConfigGroup.createStageActivityType( + public static final String CHARGING_INTERACTION = ScoringConfigGroup.createStageActivityType( CHARGING_IDENTIFIER); private final Map, Id> lastVehicleUsed = new HashMap<>(); + private final Map, Id> lastDriver = new HashMap<>(); private final Map, Id> vehiclesAtChargers = new HashMap<>(); + private final Set> agentsInChargerQueue = ConcurrentHashMap.newKeySet(); private final ChargingInfrastructure chargingInfrastructure; private final ElectricFleet electricFleet; private final ImmutableListMultimap, Charger> chargersAtLinks; + private final EvConfigGroup evCfg; @Inject - VehicleChargingHandler(ChargingInfrastructure chargingInfrastructure, ElectricFleet electricFleet) { + VehicleChargingHandler(ChargingInfrastructure chargingInfrastructure, ElectricFleet electricFleet, EvConfigGroup evConfigGroup) { this.chargingInfrastructure = chargingInfrastructure; this.electricFleet = electricFleet; - chargersAtLinks = ChargingInfrastructures.getChargersAtLinks(chargingInfrastructure); + this.evCfg = evConfigGroup; + chargersAtLinks = ChargingInfrastructureUtils.getChargersAtLinks(chargingInfrastructure ); } /** @@ -119,11 +130,78 @@ public void handleEvent(ActivityEndEvent event) { @Override public void handleEvent(PersonLeavesVehicleEvent event) { lastVehicleUsed.put(event.getPersonId(), event.getVehicleId()); + lastDriver.put(event.getVehicleId(), event.getPersonId()); } @Override public void handleEvent(ChargingEndEvent event) { - vehiclesAtChargers.remove(event.getVehicleId()); //Charging has ended before activity ends + vehiclesAtChargers.remove(event.getVehicleId()); + agentsInChargerQueue.remove(lastDriver.get(event.getVehicleId())); + } + + @Override + public void handleEvent(ChargingStartEvent event) { + agentsInChargerQueue.remove(event.getVehicleId()); + } + + @Override + public void handleEvent(QueuedAtChargerEvent event) { + //vehiclesAtChargers should normally already contain the vehicle, but assure this nevertheless + vehiclesAtChargers.put(event.getVehicleId(), event.getChargerId()); + Id driver = lastDriver.get(event.getVehicleId()); + agentsInChargerQueue.add(driver); + } + + /** + * This method tries to extend the charging activity as long as the agent is still in the waiting queue. This aims to model + * charging for a fixed predefined time (that does not include waiting). + * It is inspired by org.matsim.freight.carriers.controler.WithinDayActivityReScheduling + * @param e + */ + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + //TODO only do this every seconds ?? (because + + //not sure how we should best get the MobsimAgent in some other way + //as PopulationAgentSource does not provide a collection of MobsimAgents and injecting the qsim into this class did not seem like a better solution to me + //tschlenther, nov' 23 + QSim qsim = (QSim) e.getQueueSimulation(); + for (Id agentId : agentsInChargerQueue) { + MobsimAgent mobsimAgent = qsim.getAgents().get(agentId); + + //ideally, we would have an instance of EditPlans and then call rescheduleCurrentActivityEndtime + //but I don't see an easy way to instantiate EditPlans right now,because it needs EditTrips, which needs a lot of heavy-weight infrastructure.. + PlanElement currentPlanElement = WithinDayAgentUtils.getCurrentPlanElement(mobsimAgent); + if (currentPlanElement instanceof Activity act) { + Preconditions.checkState(act.getType().endsWith(CHARGING_INTERACTION), + "agent " + agentId + " is registered as waiting in a charger queue but the currentPlanElement is not an activity of type " + CHARGING_INTERACTION + "!"); + //EvNetworkRoutingModule models the charging activity with a maximum duration and does not set an end time + //This means, we just have to call WithinDayAgentUtils.resetCaches, because this triggers recalculation of the activity end time + //based on the duration and the _current_ simulation time. This means, an adjustment of act.maximumDuration is not needed but rather obsolete and would need to too long extension! + //I am not sure, whether this causes some problems later, because the actual activity duration might then be longer than the act.maximumDuration... + //tschlenther, nov' 23 +// act.setMaximumDuration(act.getMaximumDuration().orElseThrow(IllegalStateException::new) + 1d); + WithinDayAgentUtils.resetCaches(mobsimAgent); + WithinDayAgentUtils.rescheduleActivityEnd(mobsimAgent, qsim); + } else { + throw new IllegalStateException("agent " + agentId + " is registered as waiting in a charger queue but the currentPlanElement is not an activity!"); + } + } + } + + + @Override + public void handleEvent(QuitQueueAtChargerEvent event) { + if(evCfg.enforceChargingInteractionDuration){ + //this could actually happen when combining with edrt/etaxi/evrp + throw new RuntimeException("should currently not happen, as queue is only quit by the agent if the charging activity ended" + + " and this should not happen with fixed charging activity duration.\n" + + "If you run evrp together with conventional (preplanned) EV, please refer to VSP."); + } else { + //Charging has ended before activity ends + vehiclesAtChargers.remove(event.getVehicleId()); + agentsInChargerQueue.remove(lastDriver.get(event.getVehicleId())); + } } } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java index c36f95635a9..473def02fcf 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java @@ -20,30 +20,32 @@ package org.matsim.contrib.ev.discharging; -import com.google.inject.Singleton; import org.matsim.contrib.ev.EvModule; import org.matsim.contrib.ev.temperature.TemperatureService; import org.matsim.core.controler.AbstractModule; import org.matsim.core.mobsim.qsim.AbstractQSimModule; +import com.google.inject.Singleton; + /** * @author Michal Maciejewski (michalm) */ -public class DischargingModule extends AbstractModule { +public final class DischargingModule extends AbstractModule { @Override public void install() { bind(DriveEnergyConsumption.Factory.class).toInstance(ev -> new OhdeSlaskiDriveEnergyConsumption()); bind(TemperatureService.class).toInstance(linkId -> 15);// XXX fixed temperature 15 oC - bind(AuxEnergyConsumption.Factory.class).to(OhdeSlaskiAuxEnergyConsumption.Factory.class).in( Singleton.class ); + bind(AuxEnergyConsumption.Factory.class).to(OhdeSlaskiAuxEnergyConsumption.Factory.class).in(Singleton.class); installQSimModule(new AbstractQSimModule() { @Override protected void configureQSim() { - this.bind(DriveDischargingHandler.class).in( Singleton.class ); + this.bind(DriveDischargingHandler.class).in(Singleton.class); addMobsimScopeEventHandlerBinding().to(DriveDischargingHandler.class); + this.addQSimComponentBinding(EvModule.EV_COMPONENT).to(DriveDischargingHandler.class); // event handlers are not qsim components - this.bind(IdleDischargingHandler.class).in( Singleton.class ); + this.bind(IdleDischargingHandler.class).in(Singleton.class); addMobsimScopeEventHandlerBinding().to(IdleDischargingHandler.class); this.addQSimComponentBinding(EvModule.EV_COMPONENT).to(IdleDischargingHandler.class); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java index eae4a115384..1f87d091b7b 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java @@ -19,10 +19,15 @@ package org.matsim.contrib.ev.discharging; -import java.util.HashMap; import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.Event; +import org.matsim.api.core.v01.events.HasLinkId; +import org.matsim.api.core.v01.events.HasVehicleId; import org.matsim.api.core.v01.events.LinkLeaveEvent; import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent; @@ -35,6 +40,8 @@ import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.events.MobsimScopeEventHandler; +import org.matsim.core.mobsim.qsim.InternalInterface; +import org.matsim.core.mobsim.qsim.interfaces.MobsimEngine; import org.matsim.vehicles.Vehicle; import com.google.inject.Inject; @@ -44,8 +51,9 @@ * calculating the drive-related energy consumption. However, the time spent on the first link is used by the time-based * idle discharge process (see {@link IdleDischargingHandler}). */ -public class DriveDischargingHandler - implements LinkLeaveEventHandler, VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler, MobsimScopeEventHandler { +public final class DriveDischargingHandler + implements LinkLeaveEventHandler, VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler, MobsimScopeEventHandler, MobsimEngine { + private static class EvDrive { private final Id vehicleId; private final ElectricVehicle ev; @@ -67,12 +75,15 @@ private boolean isOnFirstLink() { private final Map, ? extends ElectricVehicle> eVehicles; private final Map, EvDrive> evDrives; + private final Queue linkLeaveEvents = new ConcurrentLinkedQueue<>(); + private final Queue trafficLeaveEvents = new ConcurrentLinkedQueue<>(); + @Inject DriveDischargingHandler(ElectricFleet data, Network network, EventsManager eventsManager) { this.network = network; this.eventsManager = eventsManager; eVehicles = data.getElectricVehicles(); - evDrives = new HashMap<>(eVehicles.size() / 10); + evDrives = new ConcurrentHashMap<>(eVehicles.size() / 10); } @Override @@ -86,37 +97,72 @@ public void handleEvent(VehicleEntersTrafficEvent event) { @Override public void handleEvent(LinkLeaveEvent event) { - EvDrive evDrive = dischargeVehicle(event.getVehicleId(), event.getLinkId(), event.getTime()); - if (evDrive != null) { - evDrive.movedOverNodeTime = event.getTime(); + if (evDrives.containsKey(event.getVehicleId())) {// handle only our EVs + linkLeaveEvents.add(event); } } @Override public void handleEvent(VehicleLeavesTrafficEvent event) { - EvDrive evDrive = dischargeVehicle(event.getVehicleId(), event.getLinkId(), event.getTime()); - if (evDrive != null) { - evDrives.remove(evDrive.vehicleId); + if (evDrives.containsKey(event.getVehicleId())) {// handle only our EVs + trafficLeaveEvents.add(event); + } + } + + @Override + public void onPrepareSim() { + } + + @Override + public void afterSim() { + // process remaining events + doSimStep(Double.POSITIVE_INFINITY); + } + + @Override + public void setInternalInterface(InternalInterface internalInterface) { + } + + @Override + public void doSimStep(double time) { + handleQueuedEvents(linkLeaveEvents, time, false); + handleQueuedEvents(trafficLeaveEvents, time, true); + } + + private void handleQueuedEvents(Queue queue, double time, boolean leftTraffic) { + // We want to process events in the main thread (instead of the event handling threads). + // This is to eliminate race conditions, where the battery is read/modified by many threads without proper synchronisation + while (!queue.isEmpty()) { + var event = queue.peek(); + if (event.getTime() == time) { + // There is a potential race condition wrt processing events between doSimStep() and handleEvent(). + // To ensure a deterministic behaviour, we only process events from the previous time step. + break; + } + + var evDrive = dischargeVehicle(event.getVehicleId(), event.getLinkId(), event.getTime(), time); + if (leftTraffic) { + evDrives.remove(evDrive.vehicleId); + } else { + evDrive.movedOverNodeTime = event.getTime(); + } + queue.remove(); } } - //XXX The current implementation is thread-safe because no other EventHandler modifies battery charge - // (for instance, AUX discharging and battery charging modifies charge outside event handling - // (as MobsimAfterSimStepListeners) - //TODO In the long term, it will be safer to move the discharging procedure to a MobsimAfterSimStepListener - private EvDrive dischargeVehicle(Id vehicleId, Id linkId, double eventTime) { + private EvDrive dischargeVehicle(Id vehicleId, Id linkId, double eventTime, double now) { EvDrive evDrive = evDrives.get(vehicleId); - if (evDrive != null && !evDrive.isOnFirstLink()) {// handle only our EVs, except for the first link + if (!evDrive.isOnFirstLink()) {// skip the first link Link link = network.getLinks().get(linkId); double tt = eventTime - evDrive.movedOverNodeTime; ElectricVehicle ev = evDrive.ev; double energy = ev.getDriveEnergyConsumption().calcEnergyConsumption(link, tt, eventTime - tt) + ev.getAuxEnergyConsumption() - .calcEnergyConsumption(eventTime - tt, tt, linkId); + .calcEnergyConsumption(eventTime - tt, tt, linkId); //Energy consumption may be negative on links with negative slope ev.getBattery() - .dischargeEnergy(energy, - missingEnergy -> eventsManager.processEvent(new MissingEnergyEvent(eventTime, ev.getId(), link.getId(), missingEnergy))); - eventsManager.processEvent(new DrivingEnergyConsumptionEvent(eventTime, vehicleId, linkId, energy, ev.getBattery().getCharge())); + .dischargeEnergy(energy, + missingEnergy -> eventsManager.processEvent(new MissingEnergyEvent(now, ev.getId(), link.getId(), missingEnergy))); + eventsManager.processEvent(new DrivingEnergyConsumptionEvent(now, vehicleId, linkId, energy, ev.getBattery().getCharge())); } return evDrive; } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java index f00009b3e7a..3289446a72e 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java @@ -27,7 +27,7 @@ /** * @author Michal Maciejewski (michalm) */ -public class DrivingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent { +public final class DrivingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent { public static final String EVENT_TYPE = "drivingEnergyConsumption"; public DrivingEnergyConsumptionEvent(double time, Id vehicleId, Id linkId, double energy, double endCharge) { diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java index da6fab88948..20a90c08e13 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java @@ -45,7 +45,7 @@ * VehicleProvider is responsible to decide if AUX discharging applies to a given vehicle based on information from * ActivityStartEvent. */ -public class IdleDischargingHandler +public final class IdleDischargingHandler implements MobsimAfterSimStepListener, ActivityStartEventHandler, ActivityEndEventHandler, MobsimScopeEventHandler { public interface VehicleProvider { /** diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java index d992dc363f5..fcb625ad7b6 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java @@ -27,7 +27,7 @@ /** * @author Michal Maciejewski (michalm) */ -public class IdlingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent { +public final class IdlingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent { public static final String EVENT_TYPE = "idlingEnergyConsumption"; public IdlingEnergyConsumptionEvent(double time, Id vehicleId, Id linkId, double energy, double endCharge) { diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java index afc8d17d93a..ea20f84a484 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java @@ -32,7 +32,7 @@ import com.google.common.primitives.Doubles; -public class LTHDriveEnergyConsumption implements DriveEnergyConsumption { +public final class LTHDriveEnergyConsumption implements DriveEnergyConsumption { private final PiecewiseBicubicSplineInterpolatingFunction function; diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java index a85c043522d..ef120c09fa9 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java @@ -26,7 +26,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.vehicles.Vehicle; -public class MissingEnergyEvent extends Event { +public final class MissingEnergyEvent extends Event { public static final String EVENT_TYPE = "missing_energy"; public static final String ATTRIBUTE_VEHICLE = "vehicle"; public static final String ATTRIBUTE_ENERGY = "energy"; diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java index 39d93db41c0..b344474bf9d 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java @@ -27,7 +27,7 @@ import com.google.common.base.Preconditions; import com.google.inject.Inject; -public class OhdeSlaskiAuxEnergyConsumption implements AuxEnergyConsumption { +public final class OhdeSlaskiAuxEnergyConsumption implements AuxEnergyConsumption { private static final double a = 1.3;// [W] private static final double b = -63.4;// [W] private static final double c = 1748.1;// [W] @@ -46,7 +46,7 @@ private static double calcPower(double temp) { private final TemperatureService temperatureService; - public OhdeSlaskiAuxEnergyConsumption(TemperatureService temperatureService) { + OhdeSlaskiAuxEnergyConsumption(TemperatureService temperatureService) { this.temperatureService = temperatureService; } @@ -59,7 +59,7 @@ public static class Factory implements AuxEnergyConsumption.Factory { private final TemperatureService temperatureService; @Inject - public Factory(TemperatureService temperatureService) { + Factory(TemperatureService temperatureService) { this.temperatureService = temperatureService; } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java index dafad6d76d1..44b62145719 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java @@ -30,7 +30,7 @@ * https://www.researchgate.net/profile/Michal-Maciejewski-3/publication/312393169_Statistical_analysis_of_real-world_urban_driving_cycles_for_modelling_energy_consumption_of_electric_vehicles/links/59b7a17faca2722453a5fc7f/Statistical-analysis-of-real-world-urban-driving-cycles-for-modelling-energy-consumption-of-electric-vehicles.pdf * TODO Add (dis-)charging efficiency relative to SOC, temperature, etc... */ -public class OhdeSlaskiDriveEnergyConsumption implements DriveEnergyConsumption { +public final class OhdeSlaskiDriveEnergyConsumption implements DriveEnergyConsumption { private static final double g = 9.81; // g [m/s^2] private static final double m = 1525; // vehicle mass [kg] private static final double m_s = m + 100; // vehicle mass + extra mass [kg] diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java index b905a6f881e..4310d786b80 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java @@ -29,7 +29,7 @@ import org.matsim.contrib.ev.fleet.ElectricVehicle; import org.matsim.vehicles.VehicleType; -public class VehicleTypeSpecificDriveEnergyConsumptionFactory implements DriveEnergyConsumption.Factory { +public final class VehicleTypeSpecificDriveEnergyConsumptionFactory implements DriveEnergyConsumption.Factory { private final Map, DriveEnergyConsumption.Factory> consumptionMap = new HashMap<>(); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java index 698dfe32e5c..e4980391db6 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java @@ -23,7 +23,6 @@ import java.io.File; import java.io.IOException; -import java.net.URL; import java.util.Arrays; import org.apache.logging.log4j.LogManager; @@ -32,14 +31,12 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.ev.EvConfigGroup; import org.matsim.contrib.ev.EvModule; -import org.matsim.contrib.ev.charging.VehicleChargingHandler; import org.matsim.contrib.ev.routing.EvNetworkRoutingProvider; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.mobsim.qsim.AbstractQSimModule; import org.matsim.core.scenario.ScenarioUtils; public class RunEvExample { @@ -66,7 +63,7 @@ public static void main(String[] args) throws IOException { public void run( String[] args ) { Config config = ConfigUtils.loadConfig(args, new EvConfigGroup()); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); Scenario scenario = ScenarioUtils.loadScenario(config); Controler controler = new Controler(scenario); controler.addOverridingModule( new AbstractModule(){ @@ -74,8 +71,11 @@ public void run( String[] args ) { install( new EvModule() ); addRoutingModuleBinding( TransportMode.car ).toProvider(new EvNetworkRoutingProvider(TransportMode.car) ); - // a router that inserts charging activities when the battery is run empty. there may be some other way to insert - // charging activities, based on the situation. kai, dec'22 + // a router that inserts charging activities INTO THE ROUTE when the battery is run empty. This assumes that a full + // charge at the start of the route is not sufficient to drive the route. There are other settings where the + // situation is different, e.g. urban, where there may be a CHAIN of activities, and charging in general is done in + // parallel with some of these activities. That second situation is adressed by some "ev" code in the vsp contrib. + // kai, dec'22 } } ); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java index 86db1f4478a..024bc2e4c54 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java @@ -24,7 +24,6 @@ import java.io.File; import java.io.IOException; -import java.net.URL; import java.util.Arrays; import org.apache.logging.log4j.LogManager; @@ -34,7 +33,6 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.ev.EvConfigGroup; import org.matsim.contrib.ev.EvModule; -import org.matsim.contrib.ev.charging.VehicleChargingHandler; import org.matsim.contrib.ev.discharging.AuxEnergyConsumption; import org.matsim.contrib.ev.discharging.DriveEnergyConsumption; import org.matsim.contrib.ev.discharging.VehicleTypeSpecificDriveEnergyConsumptionFactory; @@ -46,7 +44,6 @@ import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.mobsim.qsim.AbstractQSimModule; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.vehicles.VehicleType; @@ -79,7 +76,7 @@ public static void main(String[] args) throws IOException { public void run( String[] args ) { Config config = ConfigUtils.loadConfig(args, new EvConfigGroup()); - config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); // === @@ -92,7 +89,7 @@ public void run( String[] args ) { VehicleTypeSpecificDriveEnergyConsumptionFactory driveEnergyConsumptionFactory = new VehicleTypeSpecificDriveEnergyConsumptionFactory(); var vehicleType = Id.create( "EV_65.0kWh", VehicleType.class ); driveEnergyConsumptionFactory.addEnergyConsumptionModelFactory( vehicleType, - new LTHConsumptionModelReader( vehicleType ).readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) ) ); + new LTHConsumptionModelReader().readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) ) ); controler.addOverridingModule( new EvModule() ); controler.addOverridingModule( new AbstractModule(){ @@ -109,6 +106,7 @@ public void install(){ } ); } + controler.run(); } } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java new file mode 100644 index 00000000000..eacaba778ad --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java @@ -0,0 +1,137 @@ +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2016 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.contrib.ev.example; +/* + * created by jbischoff, 19.03.2019 + */ + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.ev.EvConfigGroup; +import org.matsim.contrib.ev.EvModule; +import org.matsim.contrib.ev.discharging.AuxEnergyConsumption; +import org.matsim.contrib.ev.discharging.DriveEnergyConsumption; +import org.matsim.contrib.ev.discharging.LTHDriveEnergyConsumption; +import org.matsim.contrib.ev.fleet.ElectricVehicle; +import org.matsim.contrib.ev.infrastructure.LTHConsumptionModelReader; +import org.matsim.contrib.ev.routing.EvNetworkRoutingProvider; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.core.scenario.ScenarioUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +/** + * Runs a sample EV run using a vehicle consumption model designed at LTH in Lund which takes the speed and the slope of a link into account. + * Link slopes may be added using a double array on the network. + * The consumption maps are based on Domingues, Gabriel. / Modeling, Optimization and Analysis of Electromobility Systems. Lund : Department of Biomedical Engineering, Lund university, 2018. 169 p., PhD thesis + */ +public class RunEvExampleWithOwnConsumptionModel{ + static final String DEFAULT_CONFIG_FILE = "test/input/org/matsim/contrib/ev/example/RunEvExample/config.xml"; + private static final Logger log = LogManager.getLogger( RunEvExampleWithOwnConsumptionModel.class ); + + public static void main(String[] args) throws IOException { + if (args.length > 0) { + log.info("Starting simulation run with the following arguments:"); + log.info("args=" + Arrays.toString( args ) ); + } else { + File localConfigFile = new File(DEFAULT_CONFIG_FILE); + if (localConfigFile.exists()) { + log.info("Starting simulation run with the local example config file"); + args = new String[]{ DEFAULT_CONFIG_FILE }; + } else { + log.info("Starting simulation run with the example config file from GitHub repository"); + args = new String[]{"https://raw.githubusercontent.com/matsim-org/matsim/master/contribs/ev/" + + DEFAULT_CONFIG_FILE }; + } + } + new RunEvExampleWithOwnConsumptionModel().run(args ); + } + + public void run( String[] args ) { + Config config = ConfigUtils.loadConfig(args, new EvConfigGroup()); + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + + // === + + Scenario scenario = ScenarioUtils.loadScenario(config); + + // === + + Controler controler = new Controler(scenario); + { + DriveEnergyConsumption.Factory driveEnergyConsumptionFactory = new DriveEnergyConsumption.Factory(){ + @Override public DriveEnergyConsumption create( ElectricVehicle electricVehicle ){ + DriveEnergyConsumption.Factory factory = new LTHConsumptionModelReader().readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) ); + DriveEnergyConsumption delegate = factory.create( electricVehicle ); + + DriveEnergyConsumption consumption = new DriveEnergyConsumption(){ + @Override public double calcEnergyConsumption( Link link, double travelTime, double linkEnterTime ){ + + // discharge because the link must be driven: + double delta = delegate.calcEnergyConsumption( link, travelTime, linkEnterTime ); + + double desiredSocAtEndOfLink = (double) electricVehicle.getVehicleSpecification().getMatsimVehicle().getAttributes().getAttribute( "whatever" ); + + return electricVehicle.getBattery().getSoc() - desiredSocAtEndOfLink; + // * above will often be negative; this is the purpose: discharging is negative i.e. we are + // charging on the link. ((This is why I am in general against hiding the sign in the method + // name. kai)) + + // * above is in SOC space, needs to be translated into kWh space + + // * need to make sure that the above charging is physically possible + + // * need to make sure that we are not discharging beyond what is needed to drive the link + + } + }; + return consumption; + } + }; + + controler.addOverridingModule( new EvModule() ); + controler.addOverridingModule( new AbstractModule(){ + @Override + public void install(){ + bind( DriveEnergyConsumption.Factory.class ).toInstance( driveEnergyConsumptionFactory ); + bind( AuxEnergyConsumption.Factory.class ).toInstance( + electricVehicle -> ( beginTime, duration, linkId ) -> 0 ); //a dummy factory, as aux consumption is part of the drive consumption in the model + + addRoutingModuleBinding( TransportMode.car ).toProvider( new EvNetworkRoutingProvider( TransportMode.car ) ); + // a router that inserts charging activities when the battery is run empty. there may be some other way to insert + // charging activities, based on the situation. kai, dec'22 + } + } ); + } + + + controler.run(); + } +} diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java similarity index 94% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java index b3be0ab8a02..a9629018dfc 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java @@ -23,11 +23,11 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; -public class BatteryImpl implements Battery { +final class BatteryDefaultImpl implements Battery { private final double capacity; private double charge; - public BatteryImpl(double capacity, double charge) { + BatteryDefaultImpl( double capacity, double charge ) { this.capacity = capacity; this.charge = charge; } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java deleted file mode 100644 index 2f1475f964e..00000000000 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2022 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.contrib.ev.fleet; - -import static org.matsim.contrib.ev.fleet.ElectricVehicleSpecificationImpl.INITIAL_SOC; - -import org.matsim.vehicles.MatsimVehicleReader; -import org.matsim.vehicles.MatsimVehicleWriter; -import org.matsim.vehicles.VehicleUtils; - -/** - * @author Michal Maciejewski (michalm) - */ -public class ConvertInitialChargeToInitialSoc { - private static final String INITIAL_ENERGY_kWh = "initialEnergyInKWh"; - - public static void run(String file) { - var vehicles = VehicleUtils.createVehiclesContainer(); - var reader = new MatsimVehicleReader(vehicles); - reader.readFile(file); - - for (var v : vehicles.getVehicles().values()) { - double battery_kWh = VehicleUtils.getEnergyCapacity(v.getType().getEngineInformation()); - double initial_kWh = (double)v.getAttributes().getAttribute(INITIAL_ENERGY_kWh); - double initial_soc = initial_kWh / battery_kWh; - v.getAttributes().removeAttribute(INITIAL_ENERGY_kWh); - v.getAttributes().putAttribute(INITIAL_SOC, initial_soc); - } - - var writer = new MatsimVehicleWriter(vehicles); - writer.writeFile(file); - } -} diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java index fc6493ae3b8..179a6ec9116 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java @@ -37,7 +37,7 @@ /** * @author Michal Maciejewski (michalm) */ -public class ElectricFleetModule extends AbstractModule { +public final class ElectricFleetModule extends AbstractModule { @Inject private EvConfigGroup evCfg; @@ -46,9 +46,9 @@ public void install() { bind(ElectricFleetSpecification.class).toProvider(new Provider<>() { @Inject private Vehicles vehicles; @Override public ElectricFleetSpecification get() { - ElectricFleetSpecification fleetSpecification = new ElectricFleetSpecificationImpl(); - ElectricVehicleSpecificationImpl.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification, - vehicles.getVehicles().values()); + ElectricFleetSpecification fleetSpecification = new ElectricFleetSpecificationDefaultImpl(); + ElectricFleetUtils.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification, + vehicles.getVehicles().values() ); return fleetSpecification; } }).asEagerSingleton(); @@ -64,8 +64,8 @@ protected void configureQSim() { @Override public ElectricFleet get() { - return ElectricFleets.createDefaultFleet(fleetSpecification, driveConsumptionFactory, auxConsumptionFactory, - chargingPowerFactory); + return ElectricFleetUtils.createDefaultFleet(fleetSpecification, driveConsumptionFactory, auxConsumptionFactory, + chargingPowerFactory ); } }).asEagerSingleton(); @@ -77,7 +77,7 @@ public ElectricFleet get() { for (var oldSpec : electricFleetSpecification.getVehicleSpecifications().values()) { var matsimVehicle = oldSpec.getMatsimVehicle(); double socAtEndOfCurrentIteration = electricFleet.getElectricVehicles().get(oldSpec.getId()).getBattery().getSoc(); - ElectricVehicleSpecifications.setInitialSoc(matsimVehicle, socAtEndOfCurrentIteration); + ElectricFleetUtils.setInitialSoc(matsimVehicle, socAtEndOfCurrentIteration ); } } }); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java similarity index 96% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java index 14a70682741..b24583feb13 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java @@ -30,7 +30,7 @@ /** * @author Michal Maciejewski (michalm) */ -public final class ElectricFleetSpecificationImpl implements ElectricFleetSpecification { +final class ElectricFleetSpecificationDefaultImpl implements ElectricFleetSpecification { private final Map, ElectricVehicleSpecification> specifications = new LinkedHashMap<>(); @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java new file mode 100644 index 00000000000..0e92b52759c --- /dev/null +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java @@ -0,0 +1,90 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2022 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.contrib.ev.fleet; + +import java.util.Collection; +import java.util.Objects; + +import com.google.common.collect.ImmutableMap; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.ev.charging.ChargingPower; +import org.matsim.contrib.ev.discharging.AuxEnergyConsumption; +import org.matsim.contrib.ev.discharging.DriveEnergyConsumption; +import org.matsim.vehicles.*; + +public final class ElectricFleetUtils { + public static final String EV_ENGINE_HBEFA_TECHNOLOGY = "electricity"; + public static final String INITIAL_SOC = "initialSoc";// in [0, 1] + public static final String CHARGER_TYPES = "chargerTypes"; + private static final String INITIAL_ENERGY_kWh = "initialEnergyInKWh"; + private ElectricFleetUtils(){} // do not instantiate + public static void setInitialSoc(Vehicle vehicle, double initialSoc) { + vehicle.getAttributes().putAttribute( INITIAL_SOC, initialSoc ); + } + + public static void setChargerTypes(EngineInformation engineInformation, Collection chargerTypes) { + engineInformation.getAttributes().putAttribute( CHARGER_TYPES, chargerTypes ); + } + public static void run(String file) { + var vehicles = VehicleUtils.createVehiclesContainer(); + var reader = new MatsimVehicleReader(vehicles); + reader.readFile(file); + + for (var v : vehicles.getVehicles().values()) { + double battery_kWh = VehicleUtils.getEnergyCapacity(v.getType().getEngineInformation()); + double initial_kWh = (double)v.getAttributes().getAttribute(INITIAL_ENERGY_kWh); + double initial_soc = initial_kWh / battery_kWh; + v.getAttributes().removeAttribute(INITIAL_ENERGY_kWh); + v.getAttributes().putAttribute(INITIAL_SOC, initial_soc); + } + + var writer = new MatsimVehicleWriter(vehicles); + writer.writeFile(file); + } + public static ElectricVehicle create( ElectricVehicleSpecification vehicleSpecification, + DriveEnergyConsumption.Factory driveFactory, AuxEnergyConsumption.Factory auxFactory, + ChargingPower.Factory chargingFactory ) { + ElectricVehicleDefaultImpl ev = new ElectricVehicleDefaultImpl(vehicleSpecification); + ev.driveEnergyConsumption = Objects.requireNonNull(driveFactory.create(ev ) ); + ev.auxEnergyConsumption = Objects.requireNonNull(auxFactory.create(ev)); + ev.chargingPower = Objects.requireNonNull(chargingFactory.create(ev)); + return ev; + } + public static void createAndAddVehicleSpecificationsFromMatsimVehicles(ElectricFleetSpecification fleetSpecification, Collection vehicles) { + vehicles.stream() + .filter(vehicle -> EV_ENGINE_HBEFA_TECHNOLOGY.equals(VehicleUtils.getHbefaTechnology(vehicle.getType().getEngineInformation()))) + .map( ElectricVehicleSpecificationDefaultImpl::new ) + .forEach(fleetSpecification::addVehicleSpecification); + } + public static ElectricVehicleSpecification createElectricVehicleSpecificationDefaultImpl( Vehicle matsimVehicle ){ + return new ElectricVehicleSpecificationDefaultImpl( matsimVehicle ); + } + public static ElectricFleet createDefaultFleet(ElectricFleetSpecification fleetSpecification, + DriveEnergyConsumption.Factory driveConsumptionFactory, AuxEnergyConsumption.Factory auxConsumptionFactory, + ChargingPower.Factory chargingFactory) { + ImmutableMap, ElectricVehicle> vehicles = fleetSpecification.getVehicleSpecifications() + .values() + .stream() + .map(s -> create(s, driveConsumptionFactory, auxConsumptionFactory, chargingFactory )) + .collect(ImmutableMap.toImmutableMap(ElectricVehicle::getId, v -> v)); + return () -> vehicles; + } +} diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java deleted file mode 100644 index fbe29db0ab3..00000000000 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2019 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.contrib.ev.fleet; - -import org.matsim.api.core.v01.Id; -import org.matsim.contrib.ev.charging.ChargingPower; -import org.matsim.contrib.ev.discharging.AuxEnergyConsumption; -import org.matsim.contrib.ev.discharging.DriveEnergyConsumption; -import org.matsim.vehicles.Vehicle; - -import com.google.common.collect.ImmutableMap; - -public class ElectricFleets { - public static ElectricFleet createDefaultFleet(ElectricFleetSpecification fleetSpecification, - DriveEnergyConsumption.Factory driveConsumptionFactory, AuxEnergyConsumption.Factory auxConsumptionFactory, - ChargingPower.Factory chargingFactory) { - ImmutableMap, ElectricVehicle> vehicles = fleetSpecification.getVehicleSpecifications() - .values() - .stream() - .map(s -> ElectricVehicleImpl.create(s, driveConsumptionFactory, auxConsumptionFactory, - chargingFactory)) - .collect(ImmutableMap.toImmutableMap(ElectricVehicle::getId, v -> v)); - return () -> vehicles; - } -} diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java similarity index 74% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java index 91125b6500d..c4da3c65565 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java @@ -20,8 +20,6 @@ package org.matsim.contrib.ev.fleet; -import java.util.Objects; - import org.matsim.api.core.v01.Id; import org.matsim.contrib.ev.charging.ChargingPower; import org.matsim.contrib.ev.discharging.AuxEnergyConsumption; @@ -31,27 +29,18 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -public class ElectricVehicleImpl implements ElectricVehicle { - public static ElectricVehicle create(ElectricVehicleSpecification vehicleSpecification, - DriveEnergyConsumption.Factory driveFactory, AuxEnergyConsumption.Factory auxFactory, - ChargingPower.Factory chargingFactory) { - ElectricVehicleImpl ev = new ElectricVehicleImpl(vehicleSpecification); - ev.driveEnergyConsumption = Objects.requireNonNull(driveFactory.create(ev)); - ev.auxEnergyConsumption = Objects.requireNonNull(auxFactory.create(ev)); - ev.chargingPower = Objects.requireNonNull(chargingFactory.create(ev)); - return ev; - } +final class ElectricVehicleDefaultImpl implements ElectricVehicle { private final ElectricVehicleSpecification vehicleSpecification; private final Battery battery; - private DriveEnergyConsumption driveEnergyConsumption; - private AuxEnergyConsumption auxEnergyConsumption; - private ChargingPower chargingPower; + DriveEnergyConsumption driveEnergyConsumption; + AuxEnergyConsumption auxEnergyConsumption; + ChargingPower chargingPower; - private ElectricVehicleImpl(ElectricVehicleSpecification vehicleSpecification) { + ElectricVehicleDefaultImpl( ElectricVehicleSpecification vehicleSpecification ) { this.vehicleSpecification = vehicleSpecification; - battery = new BatteryImpl(vehicleSpecification.getBatteryCapacity(), vehicleSpecification.getInitialCharge()); + battery = new BatteryDefaultImpl(vehicleSpecification.getBatteryCapacity(), vehicleSpecification.getInitialCharge()); } @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java similarity index 73% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java index 70d4c100f77..ef18ae6cce6 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java @@ -33,23 +33,11 @@ /** * @author Michal Maciejewski (michalm) */ -public class ElectricVehicleSpecificationImpl implements ElectricVehicleSpecification { - public static final String EV_ENGINE_HBEFA_TECHNOLOGY = "electricity"; - - public static final String INITIAL_SOC = "initialSoc";// in [0, 1] - public static final String CHARGER_TYPES = "chargerTypes"; - - public static void createAndAddVehicleSpecificationsFromMatsimVehicles(ElectricFleetSpecification fleetSpecification, - Collection vehicles) { - vehicles.stream() - .filter(vehicle -> EV_ENGINE_HBEFA_TECHNOLOGY.equals(VehicleUtils.getHbefaTechnology(vehicle.getType().getEngineInformation()))) - .map(ElectricVehicleSpecificationImpl::new) - .forEach(fleetSpecification::addVehicleSpecification); - } +final class ElectricVehicleSpecificationDefaultImpl implements ElectricVehicleSpecification { private final Vehicle matsimVehicle; - public ElectricVehicleSpecificationImpl(Vehicle matsimVehicle) { + ElectricVehicleSpecificationDefaultImpl( Vehicle matsimVehicle ) { this.matsimVehicle = matsimVehicle; //provided per vehicle type (in engine info) Preconditions.checkArgument(getInitialSoc() >= 0 && getInitialSoc() <= 1, "Invalid initialCharge or batteryCapacity of vehicle: %s", getId()); @@ -68,12 +56,12 @@ public Vehicle getMatsimVehicle() { @Override public ImmutableList getChargerTypes() { var engineInfo = matsimVehicle.getType().getEngineInformation(); - return ImmutableList.copyOf((Collection)engineInfo.getAttributes().getAttribute(CHARGER_TYPES)); + return ImmutableList.copyOf((Collection)engineInfo.getAttributes().getAttribute( ElectricFleetUtils.CHARGER_TYPES ) ); } @Override public double getInitialSoc() { - return (double)matsimVehicle.getAttributes().getAttribute(INITIAL_SOC); + return (double)matsimVehicle.getAttributes().getAttribute( ElectricFleetUtils.INITIAL_SOC ); } @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java deleted file mode 100644 index 225d5be689d..00000000000 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) 2022 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.contrib.ev.fleet; - -import java.util.Collection; - -import org.matsim.vehicles.EngineInformation; -import org.matsim.vehicles.Vehicle; - -public class ElectricVehicleSpecifications { - public static void setInitialSoc(Vehicle vehicle, double initialSoc) { - vehicle.getAttributes().putAttribute(ElectricVehicleSpecificationImpl.INITIAL_SOC, initialSoc); - } - - public static void setChargerTypes(EngineInformation engineInformation, Collection chargerTypes) { - engineInformation.getAttributes().putAttribute(ElectricVehicleSpecificationImpl.CHARGER_TYPES, chargerTypes); - } -} diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java similarity index 95% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java index a37cd181c9e..d2efb68578d 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java @@ -29,13 +29,13 @@ import com.google.common.base.Preconditions; -public class ChargerImpl implements Charger { +class ChargerDefaultImpl implements Charger { private final ChargerSpecification specification; private final Link link; private final ChargingLogic logic; - public ChargerImpl(ChargerSpecification specification, Link link, ChargingLogic logic) { + ChargerDefaultImpl( ChargerSpecification specification, Link link, ChargingLogic logic ) { Preconditions.checkArgument(link.getId().equals(specification.getLinkId()), "link.id != specification.linkId"); this.specification = specification; this.link = link; diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java index 27f21fe2fff..9864622b4cb 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java @@ -28,7 +28,7 @@ import org.matsim.core.utils.io.MatsimXmlParser; import org.xml.sax.Attributes; -public class ChargerReader extends MatsimXmlParser { +public final class ChargerReader extends MatsimXmlParser { private final static String CHARGER = "charger"; private final ChargingInfrastructureSpecification chargingInfrastructure; diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java index bb03bc9f063..8955b266984 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java @@ -29,7 +29,7 @@ import org.matsim.core.utils.collections.Tuple; import org.matsim.core.utils.io.MatsimXmlWriter; -public class ChargerWriter extends MatsimXmlWriter { +public final class ChargerWriter extends MatsimXmlWriter { private final Stream chargerSpecifications; public ChargerWriter(Stream chargerSpecifications) { diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java index ea2e2526afb..f44bee53f11 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java @@ -36,7 +36,7 @@ /** * @author Michal Maciejewski (michalm) */ -public class ChargingInfrastructureModule extends AbstractModule { +public final class ChargingInfrastructureModule extends AbstractModule { public static final String CHARGERS = "chargers"; private final Key networkKey; @@ -56,7 +56,7 @@ public void install() { bind(Network.class).annotatedWith(Names.named(CHARGERS)).to(networkKey).asEagerSingleton(); bind(ChargingInfrastructureSpecification.class).toProvider(() -> { - ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationImpl(); + ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationDefaultImpl(); new ChargerReader(chargingInfrastructureSpecification).parse( ConfigGroup.getInputFileURL(getConfig().getContext(), evCfg.chargersFile)); return chargingInfrastructureSpecification; @@ -76,8 +76,8 @@ protected void configureQSim() { @Override public ChargingInfrastructure get() { - return ChargingInfrastructures.createChargingInfrastructure(chargingInfrastructureSpecification, - network.getLinks()::get, chargingLogicFactory); + return ChargingInfrastructureUtils.createChargingInfrastructure(chargingInfrastructureSpecification, + network.getLinks()::get, chargingLogicFactory ); } }).asEagerSingleton(); } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java similarity index 95% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java index ceeba42372f..48a27563616 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java @@ -28,7 +28,7 @@ /** * @author Michal Maciejewski (michalm) */ -public class ChargingInfrastructureSpecificationImpl implements ChargingInfrastructureSpecification { +final class ChargingInfrastructureSpecificationDefaultImpl implements ChargingInfrastructureSpecification { private final SpecificationContainer container = new SpecificationContainer<>(); @Override diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java similarity index 86% rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java index b86a140fcbb..1f10fab5e15 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java @@ -37,8 +37,14 @@ /** * @author Michal Maciejewski (michalm) */ -public class ChargingInfrastructures { - static final Logger log = LogManager.getLogger(ChargingInfrastructures.class); +public class ChargingInfrastructureUtils{ + static final Logger log = LogManager.getLogger( ChargingInfrastructureUtils.class ); + + private ChargingInfrastructureUtils(){} // do not instantiate + + public static ChargingInfrastructureSpecification createChargingInfrastructureSpecification() { + return new ChargingInfrastructureSpecificationDefaultImpl(); + } public static ChargingInfrastructure createChargingInfrastructure( ChargingInfrastructureSpecification infrastructureSpecification, Function, Link> linkProvider, @@ -46,7 +52,7 @@ public static ChargingInfrastructure createChargingInfrastructure( var chargers = infrastructureSpecification.getChargerSpecifications() .values() .stream() - .map(s -> new ChargerImpl(s, linkProvider.apply(s.getLinkId()), chargingLogicFactory.create(s))) + .map(s -> new ChargerDefaultImpl(s, linkProvider.apply(s.getLinkId() ), chargingLogicFactory.create(s )) ) .collect(ImmutableMap.toImmutableMap(Charger::getId, c -> (Charger)c)); return () -> chargers; } @@ -72,7 +78,7 @@ public static ChargingInfrastructure createModalNetworkChargers(ChargingInfrastr var reachableLinks = network.getLinks(); var filteredChargers = infrastructure.getChargers().values().stream().map(c -> { var link = reachableLinks.get(c.getLink().getId()); - return link == null ? null : new ChargerImpl(c.getSpecification(), link, c.getLogic()); + return link == null ? null : new ChargerDefaultImpl(c.getSpecification(), link, c.getLogic()); }).filter(Objects::nonNull).collect(ImmutableMap.toImmutableMap(Charger::getId, c -> (Charger)c)); int chargerCount = infrastructure.getChargers().size(); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java index aa08f5d6b85..a3d7192b793 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java @@ -40,7 +40,7 @@ public class ImmutableChargerSpecification implements ChargerSpecification { private final double plugPower; private final int plugCount; - private ImmutableChargerSpecification(Builder builder) { + private ImmutableChargerSpecification( ChargerSpecificationBuilder builder ) { id = Objects.requireNonNull(builder.id); linkId = Objects.requireNonNull(builder.linkId); chargerType = Objects.requireNonNull(builder.chargerType); @@ -51,12 +51,12 @@ private ImmutableChargerSpecification(Builder builder) { Preconditions.checkArgument(plugCount >= 0, "Negative plugCount of charger: %s", id); } - public static Builder newBuilder() { - return new Builder(); + public static ChargerSpecificationBuilder newBuilder() { + return new ChargerSpecificationBuilder(); } - public static Builder newBuilder(ChargerSpecification copy) { - Builder builder = new Builder(); + public static ChargerSpecificationBuilder newBuilder( ChargerSpecification copy ) { + ChargerSpecificationBuilder builder = new ChargerSpecificationBuilder(); builder.id = copy.getId(); builder.linkId = copy.getLinkId(); builder.chargerType = copy.getChargerType(); @@ -101,37 +101,37 @@ public String toString() { .toString(); } - public static final class Builder { + public static final class ChargerSpecificationBuilder{ private Id id; private Id linkId; private String chargerType; private Double plugPower; private Integer plugCount; - private Builder() { + private ChargerSpecificationBuilder() { } - public Builder id(Id val) { + public ChargerSpecificationBuilder id( Id val ) { id = val; return this; } - public Builder linkId(Id val) { + public ChargerSpecificationBuilder linkId( Id val ) { linkId = val; return this; } - public Builder chargerType(String val) { + public ChargerSpecificationBuilder chargerType( String val ) { chargerType = val; return this; } - public Builder plugPower(double val) { + public ChargerSpecificationBuilder plugPower( double val ) { plugPower = val; return this; } - public Builder plugCount(int val) { + public ChargerSpecificationBuilder plugCount( int val ) { plugCount = val; return this; } diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java index 5cb4e90d129..0b8e732e85a 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java @@ -28,6 +28,7 @@ import java.util.List; import org.matsim.api.core.v01.Id; +import org.matsim.contrib.ev.discharging.DriveEnergyConsumption; import org.matsim.contrib.ev.discharging.LTHDriveEnergyConsumption; import org.matsim.core.utils.io.tabularFileParser.TabularFileHandler; import org.matsim.core.utils.io.tabularFileParser.TabularFileParser; @@ -43,10 +44,10 @@ */ public class LTHConsumptionModelReader { - public LTHConsumptionModelReader(Id vehicleTypeId) { + public LTHConsumptionModelReader() { } - public LTHDriveEnergyConsumption.Factory readURL(URL fileUrl) { + public DriveEnergyConsumption.Factory readURL( URL fileUrl ) { List speeds = new ArrayList<>(); List slopes = new ArrayList<>(); TabularFileParserConfig tabularFileParserConfig = new TabularFileParserConfig(); diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java index b8acc39a3f7..1ae999170d8 100644 --- a/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java +++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java @@ -17,8 +17,6 @@ * * * *********************************************************************** */ -package org.matsim.contrib.ev; - /** * All values used in this package use SI base and derived units. In particular: *